19

在我的活动中,需要在 onDestroy() 中销毁一些外部事物(服务)。但是当配置更改发生(例如键盘翻转)时,我不希望这样做,因为它将立即恢复。

所以问题是:如何区分 onDestroy() 是由说返回键按下还是配置更改过程的一部分引起的?

在@CommonsWare 的回答之后,这将非常简单)类似于:

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

@Override 
onRetainNonConfigurationInstance() { 
  mIsChangeConfig = true; 
}
4

3 回答 3

24

在 Android 3.x(API 级别 11)中,您可以调用isChangingConfigurations()以查看 Activity 是否由于配置更改而被销毁。

在此之前,覆盖onRetainNonConfigurationInstance()并将布尔数据成员(例如isChangingConfigurations)设置为true,并在 中检查该数据成员onDestroy()

于 2011-07-16T12:04:17.600 回答
6

这可能会为您解决问题(来自如何区分方向更改和离开应用程序 android):

使用 Activity 的 isFinishing() 方法。

示例代码:

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

  if (isFinishing()) {
    // Do stuff
  } else { 
    // It's an orientation change.
  }
}
于 2014-03-27T16:16:01.723 回答
0

对于必须在 onStop() 上完成某项 X 的情况,我有一个解决方法,但如果有配置更改(显然你没有可用的 isChangingConfigurations()),你不希望它完成。

该技术包括在 AsyncTask 上执行此 X 操作并延迟。您在 onStop()/onPause() 中调用 AsyncTask 并在 onRetainCustomNonConfigurationInstance() 中取消该任务。这样,例如,如果用户按下 home 键,X 代码将在后台执行。但是,如果有屏幕旋转,X代码不会被执行,因为任务在执行之前会被取消(这就是延迟的意思)。

例如,我使用它来解决唤醒锁问题:在 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);
    }
}

希望能帮助到你!

于 2013-04-11T00:58:29.593 回答