Как определить, вызывается ли onDestroy () как часть последовательности изменения конфигурации? - PullRequest
18 голосов
/ 16 июля 2011

В моей Деятельности некоторая внешняя вещь (услуга) должна быть уничтожена в onDestroy ().Но я не хочу, чтобы это происходило, когда происходит изменение конфигурации (например, вылетает клавиатура), потому что оно будет восстановлено сразу.

Итак, вопрос в том, как определить, вызвана ли onDestroy (), скажем, нажатием клавиши Backили часть процесса изменения конфигурации?

после ответа @ CommonsWare это будет довольно просто) что-то вроде:

@Override 
onDestroy() { 
  if (mIsChangeConfig == true) { 
    mIsChangeConfig = false: 
  } else { 
    stopService(); 
  } 
} 

@Override 
onRetainNonConfigurationInstance() { 
  mIsChangeConfig = true; 
}

Ответы [ 3 ]

24 голосов
/ 16 июля 2011

В Android 3.x (уровень API 11) вы можете позвонить isChangingConfigurations(), чтобы узнать, уничтожается ли действие из-за изменения конфигурации.

Перед этим переопределите onRetainNonConfigurationInstance() и установителогический элемент данных (например, isChangingConfigurations) до true и проверьте этот элемент данных в onDestroy().

6 голосов
/ 27 марта 2014

Это может помочь вам (из Как отличить изменение ориентации от выхода из приложения android ):

Использовать метод Activity isFinishing ().

Пример кода:

@Override
protected void onDestroy() {
  super.onDestroy();

  if (isFinishing()) {
    // Do stuff
  } else { 
    // It's an orientation change.
  }
}
0 голосов
/ 11 апреля 2013

У меня есть обходной путь для случаев, когда что-то X должно быть сделано в onStop (), но вы не хотите, чтобы это делалось, если есть изменение конфигурации (и, очевидно, у вас нет доступной isChangingConfigurations ()).

Техника состоит в выполнении этого действия X для AsyncTask и с задержкой.Вы вызываете AsyncTask в onStop () / onPause () и в onRetainCustomNonConfigurationInstance () отменяете задачу.Таким образом, если пользователь нажимает домашнюю клавишу, например, X-код будет выполняться в фоновом режиме.Однако при повороте экрана код X не будет выполнен, поскольку задание будет отменено до выполнения (в этом смысл задержки).

Я использую его, например, для решения проблемс помощью wakelocks: освобождение их при onPause (), но только если пользователь меняет ориентацию экрана.

Вот мой код:

private class ReleaseWakeLockDelayedTask extends AsyncTask<WakeLock, Integer, Integer>{

    @Override
    protected Integer doInBackground(WakeLock... params) {

        try {
            // Delay so that onRetainCustomNonConfigurationInstance is in
            //  time of cancelling the task
            Thread.sleep(5000);  
        } catch (InterruptedException e) {}

        if(isCancelled()) return null;
        releaseWakeLock(params[0]); // own method that calls the actual release
        return null;
    }
}


@Override
public Object onRetainCustomNonConfigurationInstance() {
    ...
    if(mReleaseWakeLockTask != null && mReleaseWakeLockTask .getStatus() != AsyncTask.Status.FINISHED){
        mReleaseWakeLockTask.cancel(true));
    }
    ...
}

@Override
protected void onPause() {
    // create and call the task
    boolean wRun;

    if(mReleaseWakeLockTask != null){
        if(mReleaseWakeLockTask .getStatus() != AsyncTask.Status.FINISHED) wRun= false;
        else wRun= true;
    }else wRun = true;

    if(wRun){
        mReleaseWakeLockTask = new mReleaseWakeLockTask ();
        mReleaseWakeLockTask .execute(wakeLock);
    }
}

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

...