Can not perform this action after onSaveInstanceState

Keywords: Android Java SDK Google

protected void onSaveInstanceState (Bundle outState)

Activities can be invoked before they can be kill ed, saving the state of each instance so that they can be restored in onCreate(Bundle) or onRestore Instance State (Bundle) methods (outState is passed to both methods).

For example, when A starts B and A is invisible, A will execute this method to save the current information and then kill A to recover resources. When B returns to A, A will recover information through onCreate(Bundle) or onRestore Instance State (Bundle).

This method has no direct relationship with onPause() and onStop().

Assuming that A is a normal Activeness, B is a transparent A ctivity.

  1. A starts B, B returns A, B's onPause(), onStop() calls, but onSaveInstanceState() is not called, because B's instance will not be restored.
  2. A starts B. If A is not killed by the system, onPause() of A is called, but onSaveInstanceState() is not called because the interface of A is not recycled.

After android P(28), this method will be executed after onStop(), but before P, it will be executed before onStop(), not before or after onPause().

activity may be kill ed by the system, including but not limited to:

(1) In the foreground, A calls kill A when the system wants kill A because of the problem of recycling resources at a certain time.
(2) From A to desktop;
(3) Lock screen from A;
(4) When the horizontal and vertical screen of A is switched;
(5) A starts B, B is in the foreground, A calls this method when A is not visible;
(6) A starts B, B is in the foreground, A is still visible, at some point the system because of the problem of resource recovery kill B, B will call this method.

In summary, before stop is executed, the system determines whether it needs to go back to the interface (users do not need to manually exit kill, the system needs to recycle resource kill), and if necessary, the onSaveInstanceState() method is executed.

bug(sdk 23):

java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
    at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager:1884)
    at android.support.v4.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager:783)
    at android.support.v4.app.FragmentActivity.onBackPressed(FragmentActivity:178)

The reason for this problem is that instanceState was saved while pressing the return key, but not restore. Sup. onBackPressed () judges the state of save.

Solution:

// Questionable Writing
@Override
public void onBackPressed() {
    super.onBackPressed();
    ......
}

// Reform 1
// Remove super
@Override
public void onBackPressed() {
    ......
}

// Reform 2
// Add onStateNotSaved before super to set saved status to false
@Override
public void onBackPressed() {
    onStateNotSaved();
    super.onBackPressed();
    ......
}

// Reform 3
// Modify the onSaveInstanceState method to set the saved state to false
@Override
protected void onSaveInstanceState(Bundle outState){
    super.onSaveInstanceState(outState);
    onStateNotSaved();
}

bug(sdk 23):

java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
    at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1884)
    at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1902)
    at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:650)
    at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:609)

The reason for this problem is that at commit, instance state was saved, but not restore. The state of save is judged in commit().

Solution:
Ibid., add onStateNotSaved() to the method calling commit.

Posted by rolwong on Tue, 11 Dec 2018 23:03:05 -0800