Lors de la validation d'un Fragment arbitraire avec FragmentTransaction, il existe des cas où FragmentTransaction # commitAllowingStateLoss est utilisé pour éviter IllegalStateException, mais je vais expliquer brièvement ce qui se passe lorsque commitAllowingStateLoss est utilisé.
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.
Le point est "Ceci est dangereux car la validation peut être perdue si l'activité doit être restaurée ultérieurement à partir de son état", traduit littéralement par l'enseignant google "Ceci est validé lorsque l'activité doit être restaurée de l'état plus tard" C'est dangereux car il peut être perdu. " Je ne comprends pas. .. ..
java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
Si vous ne commitAllowingStateLoss, vous ne pouvez pas commettre après onSaveInstanceState avec IllegalStateException! Mettez-vous en colère. Jetons un coup d'œil à la source de Activity # onSaveInstanceState pour comprendre le javadoc plus tôt.
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 ();
et ʻoutState.putParcelable (FRAGMENTS_TAG, p);
Il semble que l'objet Fragment soit complètement enregistré avec `.
Où le fragment enregistré est-il restauré? ..
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;
}
Dans onCreate, récupérez le Fragment enregistré avec Parcelable p = savedInstanceState.getParcelable (FRAGMENTS_TAG);
et restaurez-le avec mFragments.restoreAllState (p, mLastNonConfigurationInstances! = Null? MLastNonConfigurationInstances.fragments: null);
.
Il semble que le point est l'implémentation qui enregistre complètement le fragment avec onSaveInstanceState et restaure le fragment complètement enregistré avec onCreate.
La signification de «commit est perdu lorsque l'activité doit être restaurée à partir de l'état» dans commitAllowingStateLoss est que même si vous validez Fragment dans le but que vous avez vu dans commitAllowingStateLoss après onSaveInstanceState, le fragment a déjà été enregistré dans onSaveInstanceState. , Les modifications entre onSaveInstanceState et commitAllowingStateLoss ne sont pas conservées. Je comprends que cela signifie que l'état ne peut pas être rétabli lorsque l'activité est régénérée.
Après tout, vous ne devriez utiliser commitAllowingStateLoss que lorsque vous n'avez pas besoin de maintenir l'état.
Quand j'ai rencontré commitAllowingStateLoss pour la première fois, je me demandais ce qui serait perdu et j'ai créé une PG pour vérifier l'opération, et j'ai résolu moi-même que je perdais, mais cette fois, le code était perdu. Reste incapable d'expliquer exactement ce qui est perdu. .. Je suis désolé. .. ..
Recommended Posts