In my Activity some external thing (service) need to be destroyed in onDestroy(). But I do not want this when configuration change happens (e.g. keyboard flips out) because it will be restored right away.
So the question is: how to distinguish whether onDestroy() is caused by say Back-key press or part of config change process?
after @CommonsWare's answer it would be pretty simple) something like:
@Override
onDestroy() {
if (mIsChangeConfig == true) {
mIsChangeConfig = false:
} else {
stopService();
}
}
@Override
onRetainNonConfigurationInstance() {
mIsChangeConfig = true;
}
In Android 3.x (API Level 11), you can call isChangingConfigurations() to see if the activity is being destroyed due to a configuration change.
Prior to that, override onRetainNonConfigurationInstance() and set a boolean data member (e.g., isChangingConfigurations) to true, and check that data member in onDestroy().
This may do the trick for you (from How to distinguish between orientation change and leaving application android):
Use the Activity's isFinishing() method.
Sample code:
@Override
protected void onDestroy() {
super.onDestroy();
if (isFinishing()) {
// Do stuff
} else {
// It's an orientation change.
}
}
I have a workaround for the cases when something X has to be done on onStop(), but you don't want it to be done if there is a configuration change (and obviously you don't have isChangingConfigurations() available).
The technique consists on doing this X action on an AsyncTask and delayed. You call the AsyncTask in onStop()/onPause() and in onRetainCustomNonConfigurationInstance() you cancel the task. This way, if the user presses the home key, for example, the X code will be executed on background . However, if there is a screen rotation, the X code will not be executed because the task will be cancelled before it's executed (that's the meaning of the delay).
I'm using it for example to solve problems with wakelocks: releasing them on onPause() but not if the user changes the screen orientation.
Here is my code:
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);
}
}
Hope it helps!
来源:https://stackoverflow.com/questions/6716893/how-to-distinguish-whether-ondestroy-is-called-as-part-of-configuration-change