问题
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;
}
回答1:
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()
.
回答2:
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.
}
}
回答3:
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