У меня есть Android IntentService, который подключается к веб-службе для загрузки некоторых заданий в формате json. Затем они разбираются и помещаются в базу данных SQLite3.Сбой при вызове Looper.quit()
Следующий код (с добавленными чувствительными битами) работал на эмуляторе, но никогда не работал на самом устройстве.
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");
}
}
Он жаловался на публикацию в Dead Thread. После некоторого чтения вокруг, я добавил Looper держать IntentService вокруг, пока данные не были загружены и обработаны, как таковой:
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)
,
Если я удаляю вызовы quit(), то нет сбоя, но, очевидно, служба не останавливается и не освобождает ресурсы, пока приложение не завершит работу.
Что я делаю неправильно?
Спасибо, у меня есть еще один звонок в WebService, которую я называю либо из пользовательского интерфейса или как часть описанного выше процесса. Каков наилучший способ приблизиться к этому? не следует ли повторно использовать код и написать его двумя способами? –
Если вы загружаете и не заботитесь о ответе, проще всего использовать «IntentService». Если вы загружаете материал или хотите получить ответ, вы должны изучить 'ASyncTaskLoader' – JoeyJubb