How to distinguish whether onDestroy() is called as part of configuration change sequence?

前端 未结 3 1970
天命终不由人
天命终不由人 2021-02-01 20:34

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 w

相关标签:
3条回答
  • 2021-02-01 20:46

    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!

    0 讨论(0)
  • 2021-02-01 20:54

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

    0 讨论(0)
  • 2021-02-01 21:08

    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.
      }
    }
    
    0 讨论(0)
提交回复
热议问题