Prevent Activity Stack from being Restored?

后端 未结 5 571
有刺的猬
有刺的猬 2020-12-02 20:48

When an application\'s process is killed, its activity stack is saved. Then when the application is restarted, all my activities resume and run into null pointers. Rather th

5条回答
  •  南笙
    南笙 (楼主)
    2020-12-02 21:10

    The solution above of relying on process death to reset a static variable works, but is a code smell due to it's reliance on static state. Here's a solution that has very similar properties, but doesn't rely on a static variable being reset after process death. Instead, it relies on the fact that after a process death any retained fragments will have their instance variables set back to default.

    /**
     * This retained fragment functions as a detector for when the activity is restoring it's state
     * after a process death.
     *
     * 

    The callback onRestoreInstanceState cannot be used here, since that callback is also invoked * during regular activity recreation due to configuration changes, and there's no way to tell * whether the state is being restored from a configuration change or from recreation after process * death. * *

    This retained fragment can be used to disambiguate these two scenarios. When the fragment is * created, it's {@code wasProcessKilled} flag is set to {@code false}, which will be retained * across activity restarts from configuration changes. However, on process rebirth, the retained * fragment will still be retained, but the value of {@code wasProcessKilled} will be set back to * its default value of {@code true}. */ public class ProcessDeathDetectorFragment extends Fragment { public static final String TAG = "ProcessDeathDetectorFragmentTag"; public static ProcessDeathDetectorFragment create() { ProcessDeathDetectorFragment frag = new ProcessDeathDetectorFragment(); frag.wasProcessKilled = false; frag.setRetainInstance(true); return frag; } private boolean wasProcessKilled = true; public boolean wasProcessKilled() { return wasProcessKilled; } @VisibleForTesting public void clear() { wasProcessKilled = true; } } private void closeActivityIfRestoredAfterProcessDeath(Bundle bundle) { FragmentManager fragmentManager = getSupportFragmentManager(); ProcessDeathDetectorFragment retainedFragment = (ProcessDeathDetectorFragment) fragmentManager.findFragmentByTag(ProcessDeathDetectorFragment.TAG); if (bundle != null && retainedFragment != null && retainedFragment.wasProcessKilled()) { // If the bundle is non-null, then this is a restore flow. // If we are in a restore flow AND the retained fragment's wasProcessKilled flag is set back // to its default value of true, then we are restoring // from process death, otherwise the flag would have the value of false that was set when it // was created for the first time. finish(); return; } if (retainedFragment == null) { fragmentManager .beginTransaction() .add(ProcessDeathDetectorFragment.create(), ProcessDeathDetectorFragment.TAG) .commit(); } } @Override protected void onCreate(Bundle bundle) { super.onCreate(bundle); closeActivityIfRestoredAfterProcessDeath(bundle); ... }

提交回复
热议问题