首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >调用Looper.quit()时崩溃

调用Looper.quit()时崩溃
EN

Stack Overflow用户
提问于 2015-11-11 13:44:29
回答 1查看 144关注 0票数 1

我有一个Android IntentService,它连接到一个web服务,以json格式下载一些作业。然后将这些数据解析并放入SQLite3 DB中。

下面的代码(添加了敏感位)在模拟器上工作,但从未在实际设备上工作。

代码语言:javascript
复制
public class FetchJobsService extends IntentService {
    private final static String LOG_TAG = "FetchJobsService";

    public FetchJobsService() {
        super("FetchJobsService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        Log.i(LOG_TAG, "Fetch Jobs Service Started");

        AsyncHttpClient client = new AsyncHttpClient();

        Map<String, Object> params = new HashMap<String, Object>();
        // Add params to send in the request!
        JSONObject jsonData = new JSONObject(params);

        RequestParams requestParams = new RequestParams();
        requestParams.put(Constants.DATA, jsonData.toString());


        client.post(Constants.FETCH_JOBS, requestParams,
            new AsyncHttpResponseHandler() {
                @Override
                public void onSuccess(int i, Header[] headers, byte[] bytes) {
                    try {
                        JSONObject returnObj = new JSONObject(new String(bytes));
                        Log.i(LOG_TAG, "Success! Jobs downloaded");
                        JSONObject dataObj = returnObj.getJSONObject(Constants.DATA);
                        JSONArray jobs = dataObj.getJSONArray(Constants.JOBS);
                        // Do something with the data downloaded!
                    } catch (JSONException e) {
                        Log.e(LOG_TAG, "Failure! Jobs not successfully downloaded", e);
                    } 
                }

                @Override
                public void onFailure(int statusCode, Header[] headers, byte[] bytes,
                                      Throwable throwable) {
                    Log.i(LOG_TAG, "Failure! Status Code: " + statusCode);
                }
            }
        );

        Log.i(LOG_TAG, "Fetch Jobs Service Finished");
    }
}

它抱怨发帖给一个死线程。在阅读了一段时间之后,我添加了一个Looper,以便在下载和解析数据之前保持IntentService,如下所示:

代码语言:javascript
复制
public class FetchJobsService extends IntentService {
    private final static String LOG_TAG = "FetchJobsService";

    public FetchJobsService() {
        super("FetchJobsService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        Log.i(LOG_TAG, "Fetch Jobs Service Started");

        if (Looper.myLooper() == null) {
            Looper.prepare();
        }

        AsyncHttpClient client = new AsyncHttpClient();

        Map<String, Object> params = new HashMap<String, Object>();
        // Add params to send in the request!
        JSONObject jsonData = new JSONObject(params);

        RequestParams requestParams = new RequestParams();
        requestParams.put(Constants.DATA, jsonData.toString());


        client.post(Constants.FETCH_JOBS, requestParams,
            new AsyncHttpResponseHandler() {
                @Override
                public void onSuccess(int i, Header[] headers, byte[] bytes) {
                    try {
                        JSONObject returnObj = new JSONObject(new String(bytes));
                        Log.i(LOG_TAG, "Success! Jobs downloaded");
                        JSONObject dataObj = returnObj.getJSONObject(Constants.DATA);
                        JSONArray jobs = dataObj.getJSONArray(Constants.JOBS);
                        // Do something with the data downloaded!
                    } catch (JSONException e) {
                        Log.e(LOG_TAG, "Failure! Jobs not successfully downloaded", e);
                    } finally {
                        if (Looper.myLooper() != null) {
                            Looper.myLooper().quit();
                        }
                    }
                }

                @Override
                public void onFailure(int statusCode, Header[] headers, byte[] bytes,
                                      Throwable throwable) {
                    Log.i(LOG_TAG, "Failure! Status Code: " + statusCode);
                    if (Looper.myLooper() != null) {
                        Looper.myLooper().quit();
                    }
                }
            }
        );


        Looper.loop();
        Log.i(LOG_TAG, "Fetch Jobs Service Finished");
    }
}

现在已经成功下载了这些作业,但是对quit()quitSafely()的调用会导致Fatal signal 11 (SIGSEGV) at 0x0000000c (code=1)崩溃。

如果我删除了对but ()的调用,那么就不会出现崩溃,但是很明显,在应用程序退出之前,服务不会停止并释放资源。

我做错了什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-11-11 14:07:40

IntentService是用来处理自己的生命周期的。您只需重写onHandleIntent回调并执行所需操作--一旦此方法退出,IntentService将关闭自身。

IntentService已经在单独的线程中运行,所以异步地发出请求是没有意义的。您应该在onHandleIntent回调中同步执行网络调用。在这篇文章中有一些例子。

你可以尝试一些这样的方法:

代码语言:javascript
复制
HttpEntity requestEntity = new UrlEncodedFormEntity(params);

//set up post request
final HttpPost post = new HttpPost(url);
post.addHeader(requestEntity.getContentType());
post.setEntity(requestEntity);

//get http client
DefaultHttpClient mHttpClient = new DefaultHttpClient();
final HttpParams httpParams = mHttpClient.getParams();
HttpConnectionParams.setConnectionTimeout(httpParams, TIMEOUT);
HttpConnectionParams.setSoTimeout(httpParams, TIMEOUT);
ConnManagerParams.setTimeout(httpParams, TIMEOUT);

// get response -- this line will block until it is complete -- which is completely fine in an IntentService!
HttpResponse response = getHttpClient().execute(post);

int statusCode = response.getStatusLine().getStatusCode();
String responseEntity = EntityUtils.toString(response.getEntity());

if (statusCode != HttpStatus.SC_OK) {
    // something bad happened, request failed!
} else{
    // response was good, and "responseEntity" can be used for whatever you need
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33651871

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档