Приложение Android не называет "onDestroy()" когда убито (ICS)
Я разрабатываю приложение для Android, использующее bluetooth-связь (используя протранзитный протокол), и мне нужно уловить момент, когда приложение будет убито.
Я хотел использовать метод onDestroy(), но он не вызывается каждый раз, когда приложение убито.
Я заметил, что он вызывается, когда я нажимаю кнопку "Назад", и только иногда, когда я убиваю приложение из диспетчера задач.
Вопрос: как я могу уловить момент до того, как приложение будет убито?
Вот код, который я пытался использовать:
@Override
public void onDestroy() {
sendMessage(msg);
Log.d("SampleApp", "destroy");
super.onDestroy();
}
@Override
public void finish(){
sendMessage(msg);
Log.d("SampleApp", "finish");
super.finish();
}
К сожалению, finish() никогда не вызывается, а onDestroy не вызывается каждый раз, когда я закрываю приложение из диспетчера задач.
Как я могу справиться с этим?
Ответы
Ответ 1
Как указано в документации здесь, нет никакой гарантии, что onDestroy() когда-либо будет вызван. Вместо этого используйте onPause(), чтобы делать то, что вы хотите делать, когда приложение перемещается в фоновом режиме, и оставляйте только этот код в onDestroy(), который вы хотите запустить, когда ваше приложение убито.
EDIT:
Из ваших комментариев кажется, что вы хотите запускать некоторый код, когда ваше приложение переходит в фоновый режим, но не в том случае, если оно зашло в фоновый режим, потому что вы запустили намерение. AFAIK, в Android нет метода, который обрабатывает это по умолчанию, но вы можете использовать что-то вроде этого:
Имеет логическое значение:
boolean usedIntent = false;
Теперь перед использованием намерения установите для boolean значение true. Теперь в вашем onPause() переместите код для случая намерения в блок if, подобный этому:
if(usedIntent)
{
//Your code
}
Наконец, в вашем onResume() снова установите значение boolean в false, чтобы оно могло обрабатывать ваше приложение, перемещаемое в фоновое изображение с помощью немыслителя.
Ответ 2
Ваше приложение не получит никаких дополнительных обратных вызовов, если процесс, который он завершил с помощью внешних средств (т.е. убил по соображениям памяти или пользовательской силе, остановил приложение). Вам нужно будет выполнить обратные вызовы, которые вы получили, когда приложение зашло в фоновое окно для очистки вашего приложения.
finish()
вызывается системой только тогда, когда пользователь нажимает кнопку BACK из вашей активности, хотя она часто вызывается непосредственно приложениями для выхода из Activity и возврата к предыдущей. Это не технически обратный вызов жизненного цикла.
onDestroy()
только вызывается в Activity в результате вызова finish()
, поэтому в основном только тогда, когда пользователь нажимает кнопку BACK. Когда пользователь нажимает кнопку "HOME", активность переднего плана проходит только через onPause()
и onStop()
.
Это означает, что Android не дает много отзывов для Activity, чтобы дифференцировать пользователя, идущего домой, или переход на другую активность (из вашего приложения или любого другого); сама деятельность сама по себе не знает, что она больше не находится на переднем плане. Приложение для Android - это более свободная коллекция мероприятий, чем плотная интегрированная уникальная концепция (например, вы можете использовать ее на других платформах), поэтому нет реальных системных обратных вызовов, чтобы знать, когда ваше приложение в целом был перенесен или перемещен назад.
В конечном счете, я настоятельно призываю вас пересмотреть свою архитектуру приложений, если она опирается на знание того, является ли ANY Activity в вашем приложении на переднем плане, но в зависимости от ваших потребностей могут быть другие способы, более дружественные к структуре для выполнения это. Один из вариантов - реализовать привязанный Service
внутри вашего приложения, к которому привязывается каждый Activity
, пока он активен (т.е. Между onStart()
и onStop()
). Это дает вам возможность использовать тот факт, что связанный Service
работает только до тех пор, пока клиенты привязаны к нему, поэтому вы можете отслеживать методы onCreate()
и onDestroy()
службы. > знать, когда текущая задача переднего плана не является частью вашего приложения.
Вы также можете найти эту статью, написанную Dianne Hackborn, для интересного освещения в деталях архитектуры Android и того, как Google считает, что это должно быть б.
Ответ 3
Я просто решил проблему подобного типа.
Вот что вы можете сделать, если его просто остановить службу, когда приложение убито путем прокрутки из списка последних приложений.
Внутри файла манифеста сохраните флаг stopWithTask
как true
для службы. Как:
<service
android:name="com.myapp.MyService"
android:stopWithTask="true" />
Но, как вы говорите, вы хотите отменить регистрацию слушателей и прекратить уведомление и т.д., я бы предложил такой подход:
-
Внутри файла манифеста сохраните флаг stopWithTask
как false
для службы. Как:
<service
android:name="com.myapp.MyService"
android:stopWithTask="false" />
-
Теперь в вашей службе MyService
переопределите метод onTaskRemoved
. (Это будет запущено, только если для параметра stopWithTask
установлено значение false
).
public void onTaskRemoved(Intent rootIntent) {
//unregister listeners
//do any other cleanup if required
//stop service
stopSelf();
}
Обратитесь к моему вопросу для получения более подробной информации, в которой содержится и другая часть кода.
- Начать услугу, как показано ниже.
startService (новый Intent (это, MyService.class));
Надеюсь, что это поможет.