Как обрабатывать код, когда приложение убит, проводя в Android?

Если мое приложение работает, и я нажимаю кнопку "Домой", приложение переходит в фоновый режим. Теперь, если долго нажимать кнопку "Домой" и убить приложение, удалив его из списка последних приложений, ни одно из событий, подобных onPause(), onStop() или же onDestroy() скорее вызывается, процесс завершается. Так что, если я хочу, чтобы мои службы останавливались, убивали уведомления и отменяли регистрацию слушателей, как я могу это сделать? Я прочитал довольно много статей и блогов, но не получил никакой полезной информации, и я не нашел никакой документации об этом. Любая помощь будет оценена. Заранее спасибо.

6 ответов

Решение

Я только что решил похожую проблему.

Вот что вы можете сделать, если просто остановите службу, когда приложение убито, проведя пальцем из списка Недавние приложения.

Внутри вашего файла манифеста сохраняйте флаг stopWithTask как true для обслуживания. Подобно:

<service
    android:name="com.myapp.MyService"
    android:stopWithTask="true" />

Но поскольку вы говорите, что хотите отменить регистрацию слушателей и прекратить уведомления и т.д., я бы предложил этот подход:

  1. Внутри вашего файла манифеста сохраняйте флаг stopWithTask как false для обслуживания. Подобно:

    <service
        android:name="com.myapp.MyService"
        android:stopWithTask="false" />
    
  2. Теперь в вашем MyService сервис, метод переопределения onTaskRemoved, (Это будет уволено, только если stopWithTask установлен в false).

    public void onTaskRemoved(Intent rootIntent) {
    
        //unregister listeners
        //do any other cleanup if required
    
        //stop service
        stopSelf();  
    }
    

Обратитесь к моему вопросу для получения более подробной информации, которая также содержит другую часть кода.

Надеюсь это поможет.

Нашел один способ сделать это

сделать один сервис, как это

public class OnClearFromRecentService extends Service {

@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Log.d("ClearFromRecentService", "Service Started");
    return START_NOT_STICKY;
}

@Override
public void onDestroy() {
    super.onDestroy();
    Log.d("ClearFromRecentService", "Service Destroyed");
}

@Override
public void onTaskRemoved(Intent rootIntent) {
    Log.e("ClearFromRecentService", "END");
    //Code here
    stopSelf();
}

}

2) зарегистрировать этот сервис в manifest.xml

<service android:name="com.example.OnClearFromRecentService" android:stopWithTask="false" />

3) Затем запустите эту услугу на вашей всплывающей активности

startService(new Intent(getBaseContext(), OnClearFromRecentService.class));

А теперь всякий раз, когда вы очистите свое приложение от недавнего Android, тогда этот метод onTaskRemoved() будет выполняться.

Я решил похожую проблему. Если вы хотите, чтобы после смахивания с недавней задачи и при следующем запуске она работала должным образом, выполните следующие шаги: -

1) Сохранить идентификатор процесса в общих настройках:

SharedPreferencesUtils.getInstance().putInt(SharedPreferencesUtils.APP_PROCESS_ID, android.os.Process.myPid());

2) Когда приложение запускается из панели запуска после очистки от недавней задачи, выполните:

int previousProcessID = mSharedPreferencesUtils.getInt(SharedPreferencesUtils.APP_PROCESS_ID);

int currentProcessID = android.os.Process.myPid();

if ((previousProcessID == currentProcessID)) {
    // This ensures application not killed yet either by clearing recent or anyway
} else {
    // This ensures application killed either by clearing recent or by anyother means
}

Когда вы нажимаете домой - onPause а также onStop вашей деятельности называется, так что в настоящее время вы должны сделать все сбережения и очистки, потому что платформа Android больше не гарантирует, что onDestroy или любой другой метод жизненного цикла будет вызван, так что процесс может быть завершен без какого-либо уведомления.

Как упомянул Боб Крам в своем ответе, ответом является метод onCleared() модели View. Работает в обоих случаях:

  1. Когда пользователь удаляет приложение, проводя его из фона.
  2. Когда пользователь очищает все приложения с помощью кнопки очистки списка.

OnTaskRemoved() службы будет работать, когда пользователь проведет пальцем по приложению из фона, но не будет работать, когда приложения будут очищены с помощью кнопки kill all.

Но метод onCleared() viewModel работает в обоих случаях. Вы можете использовать if, чтобы остановить любой текущий процесс или очистить любую задачу на удаленном сервере.

 override fun onCleared() {
        super.onCleared()
        Log.d(TAG , "App Killed")
    }

ViewModel.onCleared() может быть полезен, если целью является высвобождение некоторого ресурса (возможно, системы, работающей где-то еще в сети), когда пользователь выполняет неожиданный выход, проводя пальцем по экрану, а не нажимая кнопку "стоп" или кнопку. [Так я изначально пришел к этому вопросу].

Приложение не получает уведомления, и Activity.onDestroy() вызывается для изменений конфигурации, таких как изменение ориентации, поэтому ответа нет. Но ViewModel.onCleared вызывается, когда приложение удаляется (а также когда пользователь отказывается от активности). Если ресурс, который вы хотите использовать, связан с более чем одним действием в стеке, вы можете добавить счетчики ссылок или какой-либо другой механизм, чтобы решить, следует ли ViewModel.onClear освободить ресурс.

Это еще одна из многих веских причин использовать ViewModel.

- Боб

Я действительно не знаю, почему вышеуказанные подходы не работают в моем случае, даже если я установил android:stopWithTask="false" который onTaskRemoved() не звонил.

Другой хороший подход - использовать AndroidViewModel. Это работает даже в случае, когда пользователь выходит из приложения, нажав кнопку возврата.

Просто связаны ViewModel класс к вашему MainActivity тогда сделай свою задачу onCleared() Перезвоните.

Пример:

public class MainViewModel extends AndroidViewModel {
    public MainViewModel(@NonNull Application application) {
        super(application);
    }

    @Override
    protected void onCleared() {
        // Do your task here
        Log.e("MainViewModel", "OnCleared mainViewModel");
        super.onCleared();
    }
}

затем привяжите его к своей MainActivity:

MainViewModel viewModel = new ViewModelProvider(this).get(MainViewModel.class);

~ Вуаля!

Вы не можете справиться со смахиванием, потому что система просто удаляет ваш процесс из памяти, не вызывая обратного вызова.

Я проверил, что перед тем, как пользователь вызывает экран "Недавние приложения", всегда вызывается onPause(). Поэтому вам нужно сохранить все данные в методе onPause без проверки isFinishing().

Чтобы проверить кнопку возврата, используйте метод onBackPressed.

Вы должны сохранить свои данные, когда на onPause() называется. Посмотрите на эту диаграмму жизненного цикла: Android Developer

Вы можете видеть, что приложение может быть убито после onPause() или же onStop(),

Обработайте ваши данные там и восстановите их в onRestart() \ onCreate(),

удачи!

Это работало для меня на Android 6,7,8,9.

Сделайте один сервис как это:

 public class OnClearFromRecentService extends Service {

 @Override public IBinder onBind(Intent intent) {
     return null; }

 @Override public int onStartCommand(Intent intent, int flags, int
 startId) {
     Log.d("ClearFromRecentService", "Service Started");
     return START_NOT_STICKY; }

 @Override public void onDestroy() {
     super.onDestroy();
     Log.d("ClearFromRecentService", "Service Destroyed"); }

 @Override public void onTaskRemoved(Intent rootIntent) {
     Log.e("ClearFromRecentService", "END");
     //Code here
     stopSelf(); } }

2) Зарегистрируйте эту услугу в manifest.xml:

<service android:name="com.example.OnClearFromRecentService"
 android:stopWithTask="false" />

3) Затем запустите этот сервис на вашей всплывающей активности

 startService(new Intent(getBaseContext(),
 OnClearFromRecentService.class));
Другие вопросы по тегам