如何区分 onDestroy() 是否作为配置更改序列的一部分被调用?

发布于 2024-11-24 02:32:45 字数 420 浏览 2 评论 0原文

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

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

在 @CommonsWare 的回答之后,这将非常简单),例如:

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

@Override 
onRetainNonConfigurationInstance() { 
  mIsChangeConfig = true; 
}

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; 
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

甜点 2024-12-01 02:32:45

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

在此之前,重写onRetainNonConfigurationInstance()并将布尔数据成员(例如isChangingConfigurations)设置为true,并检查中的该数据成员代码>onDestroy()

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().

祁梦 2024-12-01 02:32:45

这可能对你有用(来自如何区分在方向改变和离开应用程序 android 之间):

使用 Activity 的 isFinishing() 方法。

示例代码:

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

  if (isFinishing()) {
    // Do stuff
  } else { 
    // It's an orientation change.
  }
}

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.
  }
}
呆萌少年 2024-12-01 02:32:45

对于必须在 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);
    }
}

希望有帮助!

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!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文