AndroidX Fragment探究-状态保存和恢复

本文深入探讨了AndroidX Fragment中的状态保存和恢复机制。从源码角度解析FragmentActivity如何在onSaveInstanceState中通知Fragment保存状态,以及在onCreate中如何恢复状态。Fragment的onSaveInstanceState回调用于保存自定义数据,而视图状态则通过saveHierarchyState方法保存。在Fragment的生命周期中,通过mSavedFragmentState恢复数据和视图。同时,文章还介绍了commit与commitAllowingStateLoss的区别,强调不允许在onSaveInstanceState后添加Fragment事务以防止状态丢失。
摘要由CSDN通过智能技术生成

概述

我们知道Activity提供了onSaveInstanceStateonRestoreInstanceState回调方法用于状态保存和恢复,同样FragmentActivity和Fragment也支持状态保存和恢复,FragmentActivity会在适当的时机,通过FragmentManagerImpl通知Fragment进行保存操作,接下来从源码中跟踪这个通知过程。

源码探究

文中源码基于’androidx.fragment:fragment:1.1.0’

状态保存

FragmentActivity重写了onSaveInstanceState方法:
[FragmentActivity.java]

protected void onSaveInstanceState(@NonNull Bundle outState) {
   
    super.onSaveInstanceState(outState);
    // ···
    // 调用FragmentController的saveAllState方法获取Parcelable
    Parcelable p = mFragments.saveAllState();
    if (p != null) {
   
        // 将Parcelable保存进outState,FRAGMENTS_TAG值为"android:support:fragments"
        outState.putParcelable(FRAGMENTS_TAG, p);
    }
    // ···
}

outState中以FRAGMENTS_TAG为key存储数据。

FragmentController的saveAllState方法中又调用FragmentManagerImpl的saveAllState方法:
[FragmentManagerImpl.java]

Parcelable saveAllState() {
   
    // Make sure all pending operations have now been executed to get
    // our state update-to-date.
    forcePostponedTransactions();
    endAnimatingAwayFragments();
    execPendingActions();

    // 标记状态保存为true
    mStateSaved = true;

    if (mActive.isEmpty()) {
   
        return null;
    }

    // First collect all active fragments.
    int size = mActive.size();
    ArrayList<FragmentState> active = new ArrayList<>(size);
    boolean haveFragments = false;
    for (Fragment f : mActive.values()) {
   
        if (f != null) {
   
            if (f.mFragmentManager != this) {
   
                throwException(new IllegalStateException(
                        "Failure saving state: active " + f
                                + " was removed from the FragmentManager"));
            }

            haveFragments = true;

            // 创建FragmentState用于保存Fragment中的成员变量值
            FragmentState fs = new FragmentState(f);
            active.add(fs);

            // fs.mSavedFragmentState此时默认为空
            if (f.mState > Fragment.INITIALIZING && fs.mSavedFragmentState == null) {
   
                // 派发通知fragment进行数据保存
                fs.mSavedFragmentState = saveFragmentBasicState(f);

                // 若有setTargetFragment,则进行TargetFragment相关数据保存
                if (f.mTargetWho != null) {
   
                    Fragment target = mActive.get(f.mTargetWho);
                    if (target == null) {
   
                        throwException(new IllegalStateException(
                                "Failure saving state: " + f
                                        + " has target not in fragment manager: "
                                        + f.mTargetWho));
                    }
                    if (fs.mSavedFragmentState == null) {
   
                        fs.mSavedFragmentState = new Bundle();
                    }
                    putFragment(fs.mSavedFragmentState,
                            FragmentManagerImpl.TARGET_STATE_TAG, target);
                    if (f.mTargetRequestCode != 0) {
   
                        fs.mSavedFragmentState.putInt(
                                FragmentManagerImpl.TARGET_REQUEST_CODE_STATE_TAG,
                                f.mTargetRequestCode);
                    }
                }

            } else {
   
                fs.mSavedFragmentState = f.mSavedFragmentState;
            }

            if (DEBUG) Log.v(TAG, "Saved state of " + f + ": "
                    + fs.mSavedFragmentState);
        }
    }

    if (!haveFragments) {
   
        if (DEBUG) Log.v(TAG, "saveAllState: no fragments!");
        return null;
    }

    ArrayList<String> added = null;
    BackStackState[] backStack = null;

    // Build list of currently added fragments.
    // 保存mAdded集合中的Fragment唯一ID
    size = mAdded.size();
    if (size > 0) {
   
        added = new ArrayList<>(size);
        for (Fragment f : mAdded) {
   
            // f.mWho为Fragment实例化时生成的唯一UUID
            added.add(f.mWho);
            if (f.mFragmentManager != this) {
   
                throwException(new IllegalStateException(
                        "Failure saving state: active " + f
                                + " was removed from the FragmentManager"));
            }
            if (DEBUG) {
   
                Log.v(TAG, "saveAllState: adding fragment (" + f.mWho
                        + "): " + f);
            }
        }
    }

    // Now save back stack.
    // 若有addToBackStack,则进行回退栈相关数据保存
    if (mBackStack != null) {
   
        size = mBackStack.size();
        if (size > 0) {
   
            backStack = new BackStackState[size];
            
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值