В настоящее время я разрабатываю приложение для Android. Одним из требований является обширный журнал о том, как приложение используется. В частности, должно появиться сообщение о том, когда пользователь закрывает приложение. Это ведение журнала состоит из взаимодействия с сервером. Что касается этого конкретного требования я наткнулся на:Служба Android выполняет AsyncTask после закрытия приложения
Detect Application Exit(1) и Detect application Exit (2)
Оба вопроса имеют общепринятый ответ, опираясь на Service#onTaskRemoved(Intent)
.
В моем случае, однако, это решение, похоже, не работает, то есть AsyncTask
s, которые запускаются в этом методе, являются только иногда выполнен. В частности, onPreExecute
исполняется всегда, но doInBackground
нет. Я тестировал это на Nexus 5 с установленным Android 6 (Marshmallow).
public class SomeService extends Service {
@Override
public IBinder onBind(Intent aIntent) {
return null;
}
@Override
public void onTaskRemoved(Intent aRootIntent) {
new DoSomethingTask().executeOnExecutor(Asyntask.THREAD_POOL_EXECUTOR);
}
private static final class DoSomethingTask extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
Log.e(DoSomethingTask.class.getName(), "This is executed always");
}
@Override
protected Void doInBackground(Void... aParams) {
Log.e(DoSomethingTask.class.getName(), "This appears to be executed only sometimes... ");
// here an actual call to a Rest API should be made to inform the server that the user has closed the application.
}
@Override
protected void onCancelled(Void result) {
super.onCancelled(result);
Log.e(DoSomethingTask.class.getName(), "Never invoked");
}
@Override
protected void onCancelled() {
super.onCancelled();
Log.e(DoSomethingTask.class.getName(), "Never invoked");
}
}
}
Вот краткий обзор всего, что я попытался в дополнение к указанной выше примере кода:
- Я пробовал различные варианты
onStartCommand
(START_STICKY, START_NOT_STICKY и т.д.) не увенчались успехом. - Я также попытался перезапустить службу в методе
onTaskRemoved
, а затем выполнил командуAsyncTask
в onStartCommand. - Запуск
IntentService
в методеonTaskRemoved
(который запускаетAsyncTask
в своем методеonHandleIntent
) не решает проблему ни. - с использованием
BroadcastReceiver
в сочетании с местной широковещательной рассылкой (LocalBroadcastManager#sendBroadcast
) также не работает (я дважды проверил, что широковещательный приемник фактически зарегистрирован в качестве приемника для отправленной передачи).
EDIT:
Я также принял взглянуть на обратных вызовах в Application
классе: - onTerminate
: этот метод вызывается только в эмулируемой среде и, следовательно, бесполезно - onTrimMemory(int)
: этот метод может используется для обнаружения, когда приложение переходит в фоновый режим, но не имеет отдельного случая, когда приложение выходит.
Я мог бы хранить стек действий (который будет обновлен в Activity#onPause()
и т. Д.). Но это требует довольно много работы в каждом Activity
вместо вышеописанного подхода Service
, который включает только помехи в одном месте.
Возможно, вы сможете это сделать, расширив класс Application и переопределив onTerminate() onDestroy() onLowMemory() и все такое. – napkinsterror
Я тоже пробовал это, но я забыл упомянуть об этом в сообщении. Я сделал это сейчас внизу, см. Раздел ** Редактировать **. –