Wenn Sie ein beliebiges Fragment mit FragmentTransaction festschreiben, gibt es Fälle, in denen FragmentTransaction # commitAllowingStateLoss verwendet wird, um IllegalStateException zu vermeiden. Ich werde jedoch kurz erläutern, was passiert, wenn commitAllowingStateLoss verwendet wird.
commitAllowingStateLoss javadoc https://developer.android.com/reference/android/app/FragmentTransaction.html#commitAllowingStateLoss()
Like commit() but allows the commit to be executed after an activity's state is saved. This is dangerous because the commit can be lost if the activity needs to later be restored from its state, so this should only be used for cases where it is okay for the UI state to change unexpectedly on the user.
Der Punkt ist der Teil "Dies ist gefährlich, da das Commit verloren gehen kann, wenn die Aktivität später aus ihrem Status wiederhergestellt werden muss", wörtlich übersetzt von Google Teacher. "Dies wird festgeschrieben, wenn die Aktivität später aus dem Status wiederhergestellt werden muss." Es ist gefährlich, weil es verloren gehen kann. " Ich verstehe nicht. .. ..
java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
Wenn SieAllowingStateLoss nicht festlegen, können Sie nach onSaveInstanceState keine Festschreibung mit IllegalStateException vornehmen! Wütend werden. Werfen wir einen Blick auf die Quelle der Aktivität # onSaveInstanceState, um das Javadoc früher zu verstehen.
Activity.java
protected void onSaveInstanceState(Bundle outState) {
outState.putBundle(WINDOW_HIERARCHY_TAG, mWindow.saveHierarchyState());
outState.putInt(LAST_AUTOFILL_ID, mLastAutofillId);
Parcelable p = mFragments.saveAllState();
if (p != null) {
outState.putParcelable(FRAGMENTS_TAG, p);
}
if (mAutoFillResetNeeded) {
outState.putBoolean(AUTOFILL_RESET_NEEDED, true);
getAutofillManager().onSaveInstanceState(outState);
}
getApplication().dispatchActivitySaveInstanceState(this, outState);
}
Parcelable p = mFragments.saveAllState ();
und outState.putParcelable (FRAGMENTS_TAG, p); Es scheint, dass das Fragment-Objekt vollständig mit
gespeichert ist.
Wo wird das gespeicherte Fragment wiederhergestellt? ..
MainActivity.java
protected void onCreate(@Nullable Bundle savedInstanceState) {
if (DEBUG_LIFECYCLE) Slog.v(TAG, "onCreate " + this + ": " + savedInstanceState);
if (getApplicationInfo().targetSdkVersion > O && mActivityInfo.isFixedOrientation()) {
final TypedArray ta = obtainStyledAttributes(com.android.internal.R.styleable.Window);
final boolean isTranslucentOrFloating = ActivityInfo.isTranslucentOrFloating(ta);
ta.recycle();
if (isTranslucentOrFloating) {
throw new IllegalStateException(
"Only fullscreen opaque activities can request orientation");
}
}
if (mLastNonConfigurationInstances != null) {
mFragments.restoreLoaderNonConfig(mLastNonConfigurationInstances.loaders);
}
if (mActivityInfo.parentActivityName != null) {
if (mActionBar == null) {
mEnableDefaultActionBarUp = true;
} else {
mActionBar.setDefaultDisplayHomeAsUpEnabled(true);
}
}
if (savedInstanceState != null) {
mAutoFillResetNeeded = savedInstanceState.getBoolean(AUTOFILL_RESET_NEEDED, false);
mLastAutofillId = savedInstanceState.getInt(LAST_AUTOFILL_ID,
View.LAST_APP_AUTOFILL_ID);
if (mAutoFillResetNeeded) {
getAutofillManager().onCreate(savedInstanceState);
}
Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
mFragments.restoreAllState(p, mLastNonConfigurationInstances != null
? mLastNonConfigurationInstances.fragments : null);
}
mFragments.dispatchCreate();
getApplication().dispatchActivityCreated(this, savedInstanceState);
if (mVoiceInteractor != null) {
mVoiceInteractor.attachActivity(this);
}
mCalled = true;
}
In onCreate wird das Fragment mit Parcelable p = savedInstanceState.getParcelable (FRAGMENTS_TAG);
gespeichert und mit mFragments.restoreAllState (p, mLastNonConfigurationInstances! = Null? MmlastNonConfigurationInstances.fragments: null);
wiederhergestellt.
Es scheint, dass der Punkt die Implementierung ist, die das Fragment vollständig mit onSaveInstanceState speichert und das mit onCreate vollständig gespeicherte Fragment wiederherstellt.
Die Bedeutung von "Festschreiben geht verloren, wenn Aktivität aus dem Status wiederhergestellt werden muss" in commitAllowingStateLoss ist, dass Fragment bereits in onSaveInstanceState gespeichert wurde, selbst wenn Sie Fragment für den Zweck festschreiben, den Sie in commitAllowingStateLoss nach onSaveInstanceState gesehen haben. , Änderungen zwischen onSaveInstanceState und commitAllowingStateLoss werden nicht beibehalten. Ich verstehe, dass dies bedeutet, dass der Zustand nicht wiederhergestellt werden kann, wenn die Aktivität neu generiert wird.
Schließlich sollten Sie commitAllowingStateLoss nur verwenden, wenn Sie den Status nicht beibehalten müssen.
Als ich zum ersten Mal auf commitAllowingStateLoss stieß, fragte ich mich, was verloren gehen würde, und erstellte ein PG zum Überprüfen des Vorgangs. Ich stellte selbst fest, dass ich verlor, aber diesmal ging der Code verloren. Kann nicht genau erklären, was verloren geht. .. Es tut mir Leid. .. ..
Recommended Posts