[JAVA] Une brève explication de commitAllowingStateLoss

Aperçu

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é.

Détails

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.

Considérant la mise en œuvre de l'activité

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.

À la fin

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

Une brève explication de commitAllowingStateLoss
Une brève description des dépendances JAVA
Un bref résumé des conteneurs DI et DI
Créons une application TODO avec Java 1 Brève explication de MVC
Un bref résumé des options d'association Rails (clé_trangère, clé_principale)
Une explication approximative du fonctionnement des applications Web Java
Une brève explication d'un jeu de labyrinthe fait à Java pour les cousins du primaire
Une explication rapide des cinq types de statique Java
Créer un lot Liferay
Explication de Ruby on rails pour les débutants ③ ~ Création d'une base de données ~
Pensez à une stratégie de mise à jour Java
Une liste de rawValues pour UITextContentType.
Un mémorandum du problème FizzBuzz
Explique les objets Ruby Array
Histoire d'une certaine SE interne
Comprendre un peu la formule lambda