Как отличить, вызвана ли onDestroy() как часть последовательности изменения конфигурации?
В моей деятельности в onDestroy() необходимо уничтожить какую-то внешнюю вещь (услугу). Но я не хочу этого, когда происходит изменение конфигурации (например, переключение клавиатуры), потому что он будет восстановлен сразу.
Итак, вопрос заключается в следующем: как отличить, вызвано ли onDestroy() нажатием клавиши Back-key или частью процесса изменения конфигурации?
после @CommonsWare ответ будет довольно простым) что-то вроде:
@Override
onDestroy() {
if (mIsChangeConfig == true) {
mIsChangeConfig = false:
} else {
stopService();
}
}
@Override
onRetainNonConfigurationInstance() {
mIsChangeConfig = true;
}
Ответы
Ответ 1
В Android 3.x(уровень API 11) вы можете вызвать isChangingConfigurations()
, чтобы узнать, уничтожена ли активность из-за изменения конфигурации.
До этого переопределите onRetainNonConfigurationInstance()
и установите элемент данных boolean (например, isChangingConfigurations
) на true
и проверьте, что элемент данных находится в onDestroy()
.
Ответ 2
Это может сделать трюк для вас (от Как отличить изменение ориентации и оставить андроид приложения):
Используйте метод Activity isFinishing().
Пример кода:
@Override
protected void onDestroy() {
super.onDestroy();
if (isFinishing()) {
// Do stuff
} else {
// It an orientation change.
}
}
Ответ 3
У меня есть обходное решение для случаев, когда что-то 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);
}
}
Надеюсь, что это поможет!