Fragment原理分析

1,993 阅读7分钟

基于AndroidX源码分析

Activity与Fragment 之间的关系

  • Fragment是Activity界面的一部分,Fragment是依附于Activity之上的;
  • Activity是Fragment的基础,Fragment是Activity的延续和发展
  • 一个Activity可以有多个Fragment,一个Fragment也可以被多个Activity重复使用;
  • 一个Fragment除了Activity处于onResume状态下,他可以自己灵活的控制自己的生命周期,其他状态下,其生命周期都是由Activity所决定的;
  • Fragment的出现增强了UI界面布局的灵活性,可以实现动态的改变UI布局;

Fragment生命周期

Activity fragment_lifecycle

这是一张google官方提供的一张Fragment生命周期的图片,Fragment的生命周期又依赖与Activity

我们通过上面图开始进入我们的源码的分析

一、FragmentController 创建

FragmentActivity中有个变量mFragments,在一开始就初始化完成

final FragmentController mFragments = FragmentController.createController(new HostCallbacks());

整个类图结构图如上所示,里面的细节会在后续流程会讲到。

二、生命周期分发

我们Fragment的生命周期会跟随Activity的生命周期进行变化,所以我们看几个生命周期的调用。

protected void onCreate(@Nullable Bundle savedInstanceState) {
  	//调用attach
    mFragments.attachHost(null /*parent*/);

    if (savedInstanceState != null) {
        //... 数据保存相关
    }
		
  	//...
    super.onCreate(savedInstanceState);
  	//分发create
    mFragments.dispatchCreate();
}

protected void onPostResume() {
    super.onPostResume();
  	//分发Resume,会在onResume之前执行
    mFragments.dispatchResume();
}

protected void onPause() {
    super.onPause();
    mResumed = false;
  	//分发Pause
    mFragments.dispatchPause();
}

上面的代码可以看到随着Activity生命周期的变化会调用FragmentManagerImpl.dispatchXXX()通知。跟踪代码我们会发现FragmentManagerImpl.dispatchXXX()最终都会调用FragmentManagerImpl.dispatchStateChange(int nextState)

Fragment状态

Fragment有多个状态值来标示当前自己生命周期所处的状态

static final int INITIALIZING = 0;     // Not yet created.
static final int CREATED = 1;          // Created.
static final int ACTIVITY_CREATED = 2; // Fully created, not started.
static final int STARTED = 3;          // Created and started, not resumed.
static final int RESUMED = 4;          // Created started and resumed.
//Fragment 默认的状态是 INITIALIZING,也是代表当前的生命周期状态
int mState = INITIALIZING;

FragmentManagerImpl.dispatchStateChange

//nextState 顾名思义,就是想要Fragment进入的下一个状态
private void dispatchStateChange(int nextState) {
    try {
      	//这个标志位是为了防止
        mExecutingActions = true;
      	//1.变化到下一个状态
        moveToState(nextState, false);
    } finally {
        mExecutingActions = false;
    }
  	//执行未执行的操作事务管理会讲到
    execPendingActions();
}

三、生命周期变化 moveToState

第1步

void moveToState(int newState, boolean always) {
    if (mHost == null && newState != Fragment.INITIALIZING) {
        throw new IllegalStateException("No activity");
    }
		//如果状态相同,返回
    if (!always && newState == mCurState) {
        return;
    }
		
    mCurState = newState;

    // Must add them in the proper order. mActive fragments may be out of order
    final int numAdded = mAdded.size();
    for (int i = 0; i < numAdded; i++) {
        Fragment f = mAdded.get(i);
      	//【1-1】所有的Fragment都会调用这个方法,但不会真的更新状态看【2-1】
        moveFragmentToExpectedState(f);
    }

    // Now iterate through all active fragments. These will include those that are removed
    // and detached.
  	//一些特殊的情况,比如被回收了 remove 和 detached 不会再mAdded列表里面
    for (Fragment f : mActive.values()) {
        if (f != null && (f.mRemoving || f.mDetached) && !f.mIsNewlyAdded) {
          	//【1-2】被回收的再执行生命周期变化
            moveFragmentToExpectedState(f);
        }
    }
		//比如有些Fragment 需要等到其他Fragment执行完毕之后在执行自己的生命周期变化,比如说用户不可见的,需要让用户可见的先执行生命周期,再轮到自己。这也是google优化的思路,那么什么时候延迟 todo
  	//【1-3】开始执行延迟的Fragment 生命周期变化【3-1】
    startPendingDeferredFragments();
		//。。。
}

【1-3】 startPendingDeferredFragments => performPendingDeferredStart

public void performPendingDeferredStart(Fragment f) {
    if (f.mDeferStart) {
        if (mExecutingActions) {
            mHavePendingDeferredStart = true;
            return;
        }
      	//把延迟加载标记清空
        f.mDeferStart = false;
      	//接着走后面的生命周期 到第三步
        moveToState(f, mCurState, 0, 0, false);
    }
}

第2步

void moveFragmentToExpectedState(Fragment f) {
    if (f == null) {
        return;
    }
  	//【2-1】.mActive存在key 才能继续执行
    if (!mActive.containsKey(f.mWho)) {
        return;
    }
    int nextState = mCurState;
    if (f.mRemoving) {
      	//如果被移出 控制他的生命周期nextState不能超过预期
        if (f.isInBackStack()) {
            nextState = Math.min(nextState, Fragment.CREATED);
        } else {
            nextState = Math.min(nextState, Fragment.INITIALIZING);
        }
    }
  	//【2-2】进入真正的状态
    moveToState(f, nextState, f.getNextTransition(), f.getNextTransitionStyle(), false);
		//...
}

第3步

void moveToState(Fragment f, int newState, int transit, int transitionStyle,
                 boolean keepActive) {
 		//未添加或detached了先走oncreate
    if ((!f.mAdded || f.mDetached) && newState > Fragment.CREATED) {
        newState = Fragment.CREATED;
    }
  	//在此控制newState 如果被移出 控制他的生命周期nextState不能超过预期
    if (f.mRemoving && newState > f.mState) {
        if (f.mState == Fragment.INITIALIZING && f.isInBackStack()) {
            // Allow the fragment to be created so that it can be saved later.
            newState = Fragment.CREATED;
        } else {
            // While removing a fragment, we can't change it to a higher state.
            newState = f.mState;
        }
    }
  	//延迟加载则将newState 直接赋值为 Fragment.ACTIVITY_CREATED , 他将不会执行 CREATED 和 INITIALIZING,而直接跳过本次的生命周期
    if (f.mDeferStart && f.mState < Fragment.STARTED && newState > Fragment.ACTIVITY_CREATED) {
        newState = Fragment.ACTIVITY_CREATED;
    }
  	//控制Fragment 最大生命周期执行到哪一步,在ViewPager2 用的比较多
    if (f.mMaxState == Lifecycle.State.CREATED) {
        newState = Math.min(newState, Fragment.CREATED);
    } else {
        newState = Math.min(newState, f.mMaxState.ordinal());
    }
    if (f.mState <= newState) {
				//...
      	//switch 当前状态
        switch (f.mState) {
            case Fragment.INITIALIZING:
                if (newState > Fragment.INITIALIZING) {//执行这里面说明要走到CREATE生命周期状态
                    if (f.mSavedFragmentState != null) {
                        //...状态恢复
                      	//【3-1】如果Fragment用户不可见不让他走到START,等所有执行完再走【1-3】
                        if (!f.mUserVisibleHint) {
                            f.mDeferStart = true;
                            if (newState > Fragment.ACTIVITY_CREATED) {
                                newState = Fragment.ACTIVITY_CREATED;
                            }
                        }
                    }

                    f.mHost = mHost;
                    f.mParentFragment = mParent;
                    f.mFragmentManager = mParent != null
                            ? mParent.mChildFragmentManager : mHost.mFragmentManager;

                    //优先执行Childfragment依赖的ParentFragment
                    if (f.mTarget != null) {
                        if (f.mTarget.mState < Fragment.CREATED) {
                            moveToState(f.mTarget, Fragment.CREATED, 0, 0, true);
                        }
                        f.mTargetWho = f.mTarget.mWho;
                        f.mTarget = null;
                    }
                    if (f.mTargetWho != null) {
                        Fragment target = mActive.get(f.mTargetWho);
                        if (target.mState < Fragment.CREATED) {
                            moveToState(target, Fragment.CREATED, 0, 0, true);
                        }
                    }
										
                  	//生命周期的回调和分发
                    dispatchOnFragmentPreAttached(f, mHost.getContext(), false);
                  	//fragment attach
                    f.performAttach();
                    if (f.mParentFragment == null) {
                        mHost.onAttachFragment(f);
                    } else {
                        f.mParentFragment.onAttachFragment(f);
                    }
                    dispatchOnFragmentAttached(f, mHost.getContext(), false);
										//f.mState 标记为 CREATED
                    if (!f.mIsCreated) {
                        dispatchOnFragmentPreCreated(f, f.mSavedFragmentState, false);
                        f.performCreate(f.mSavedFragmentState);
                        dispatchOnFragmentCreated(f, f.mSavedFragmentState, false);
                    } else {
                        f.restoreChildFragmentState(f.mSavedFragmentState);
                        f.mState = Fragment.CREATED;
                    }
                }
            case Fragment.CREATED:
                if (newState > Fragment.INITIALIZING) {
                  	//创建FragmentView
                    ensureInflatedFragmentView(f);
                }

                if (newState > Fragment.CREATED) {//执行这里面说明要走到ACTIVITY_CREATE生命周期状态
                    if (!f.mFromLayout) {
                       //...把Fragment的 View 添加到 Activity View容器
                    }
										//f.mState 标记为 ACTIVITY_CREATED
                    f.performActivityCreated(f.mSavedFragmentState);
                    dispatchOnFragmentActivityCreated(f, f.mSavedFragmentState, false);
                    if (f.mView != null) {
                        f.restoreViewState(f.mSavedFragmentState);
                    }
                    f.mSavedFragmentState = null;
                }
            case Fragment.ACTIVITY_CREATED:
                if (newState > Fragment.ACTIVITY_CREATED) {//执行这里面说明要走到START生命周期状态
                    f.performStart();
                    dispatchOnFragmentStarted(f, false);
                }
            case Fragment.STARTED:
                if (newState > Fragment.STARTED) {//执行这里面说明要走到RESUME生命周期状态
                  	//执行Fragment Resume
                    f.performResume();
                  	//分发生命周期监听的回调
                    dispatchOnFragmentResumed(f, false);
                    f.mSavedFragmentState = null;
                    f.mSavedViewState = null;
                }
        }
    } else if (f.mState > newState) {
        // 省略反向从 RESUME =》 INITIALIZING 大家可以自己分析,比正向的简单
    }
		//设置fragment 当前state
    if (f.mState != newState) {
        f.mState = newState;
    }
}

事务管理

将一个Fragment添加到Activity布局有两种方式。

  • 通过fragment标签加入(静态加入)
  • 通过代码动态的加入(动态加入)

而这里要讲的就是第二种方式。

事务的action

static final int OP_NULL = 0;
static final int OP_ADD = 1;
static final int OP_REPLACE = 2;
static final int OP_REMOVE = 3;
static final int OP_HIDE = 4;
static final int OP_SHOW = 5;
static final int OP_DETACH = 6;
static final int OP_ATTACH = 7;
static final int OP_SET_PRIMARY_NAV = 8;
static final int OP_UNSET_PRIMARY_NAV = 9;
static final int OP_SET_MAX_LIFECYCLE = 10;

事务添加的流程

事务四种Commit的区别

www.cnblogs.com/mengdd/p/58…

在 Fragment 之间传递数据

为了重复使用 Fragment 界面组件,您应将每个组件构建为一个完全独立的模块化组件,定义它自己的布局和行为。定义这些可重用的 Fragment 后,您可以将它们与 Activity 相关联,并将其与应用逻辑相关联以实现整个复合界面。

在AndroidX Fragment版本是 1.3.0-alpha04开始,每个 FragmentManager 都会实现 FragmentResultOwner。我们实现Fragment之间的通信。

我们可以看到 上面通信条件必须是在同一个Activity下面,如果跨越Acitivty的话那就是生命周期大于Acitivity 全局的观察着设计模式了,有RxJava, EventBus、LiveDataBus 这些比较成熟的线程间的通信开源组件了。

状态保存和恢复

状态保存

当Activity在后台被回收或者App的进程处于Sleep状态等特殊情况时候会调用ActivityThread.callActivityOnSaveInstanceState => Instrumentation.callActivityOnSaveInstanceState => Activity.performSaveInstanceState => Activity.onSaveInstanceState => FragmentActivity.onSaveInstanceState 来保存数据

FragmentActivity.onSaveInstanceState

protected void onSaveInstanceState(@NonNull Bundle outState) {
    super.onSaveInstanceState(outState);
  	//将Fragment的状态变更为CREATE
    markFragmentsCreated();
    mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
  	//1.封装所有fragment需要保存的状态数据
    Parcelable p = mFragments.saveAllState();
    if (p != null) {
      	//2.把数据保存到bundle中
        outState.putParcelable(FRAGMENTS_TAG, p);
    }
    if (mPendingFragmentActivityResults.size() > 0) {
        outState.putInt(NEXT_CANDIDATE_REQUEST_INDEX_TAG, mNextCandidateRequestIndex);

        int[] requestCodes = new int[mPendingFragmentActivityResults.size()];
        String[] fragmentWhos = new String[mPendingFragmentActivityResults.size()];
        for (int i = 0; i < mPendingFragmentActivityResults.size(); i++) {
            requestCodes[i] = mPendingFragmentActivityResults.keyAt(i);
            fragmentWhos[i] = mPendingFragmentActivityResults.valueAt(i);
        }
        outState.putIntArray(ALLOCATED_REQUEST_INDICIES_TAG, requestCodes);
        outState.putStringArray(REQUEST_FRAGMENT_WHO_TAG, fragmentWhos);
    }
}

第一步方法执行之后mFragments.saveAllState => FragmentController.saveAllState => FragmentManagerImpl.saveAllState

最总进入FragmentManagerImpl.saveAllState

FragmentManagerImpl.saveAllState

Parcelable saveAllState() {
  	//确保所有等待操作的都已处理完,再进入保存数据
    forcePostponedTransactions();
    endAnimatingAwayFragments();
    execPendingActions();
  
		//1.标志位置为true,在mStateSaved == true 的时候commit会抛出异常
    mStateSaved = true;

  	//fragment 为空,也就是没有Fragment 添加到 FragmentManager
    if (mActive.isEmpty()) {
        return null;
    }

    // First collect all active fragments.
    int size = mActive.size();
    ArrayList<FragmentState> active = new ArrayList<>(size);
    boolean haveFragments = false;
  	//遍历所有活跃的fragment
    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;
						//2.用于保存fragment的成员变量,并添加到 active,用于数据恢复
            FragmentState fs = new FragmentState(f);
            active.add(fs);

            if (f.mState > Fragment.INITIALIZING && fs.mSavedFragmentState == null) {
              	//保存基本状态
                fs.mSavedFragmentState = saveFragmentBasicState(f);
								
                if (f.mTargetWho != null) {
                    Fragment target = mActive.get(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 (!haveFragments) {
        return null;
    }

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

    // Build list of currently added fragments.
    size = mAdded.size();
    if (size > 0) {
      	//遍历所有添加到FragmentManager的Fragment
        added = new ArrayList<>(size);
        for (Fragment f : mAdded) {
          	//f.mWho fragment 唯一标识
            added.add(f.mWho);
        }
    }

  	//保存回退栈
    // Now save back stack.
    if (mBackStack != null) {
        size = mBackStack.size();
        if (size > 0) {
            backStack = new BackStackState[size];
            for (int i = 0; i < size; i++) {
                backStack[i] = new BackStackState(mBackStack.get(i));
            }
        }
    }

  	//3。保存FragmentManagerImpl的整体信息
    FragmentManagerState fms = new FragmentManagerState();
    fms.mActive = active;
    fms.mAdded = added;
    fms.mBackStack = backStack;
    if (mPrimaryNav != null) {
        fms.mPrimaryNavActiveWho = mPrimaryNav.mWho;
    }
    fms.mNextFragmentIndex = mNextFragmentIndex;
    return fms;
}

通过上面几个步骤最终将我们的数据保存到ActivityClienttRecord的成员变量 state

状态恢复

当Activity恢复的时候会创建一个新的Activity,并走一遍Activity的生命周期方法。

FragmentActivity.onCreate

  1. => FragmentController.restoreSaveState => FragmentManagerImpl.restoreSaveState 恢复数据
  2. => FragmentController.dispatchCreate => FragmentManagerImpl.dispatchCreate 重走Fragment的生命周期

FragmentManagerImpl.restoreSaveState

void restoreSaveState(Parcelable state) {
    // If there is no saved state at all, then there's nothing else to do
    if (state == null) return;
    FragmentManagerState fms = (FragmentManagerState)state;
    if (fms.mActive == null) return;

    // First re-attach any non-config instances we are retaining back
    // to their saved state, so we don't try to instantiate them again.
    for (Fragment f : mNonConfig.getRetainedFragments()) {
        FragmentState fs = null;
        for (FragmentState fragmentState : fms.mActive) {
            if (fragmentState.mWho.equals(f.mWho)) {
                fs = fragmentState;
                break;
            }
        }
        if (fs == null) {
            // We need to ensure that onDestroy and any other clean up is done
            // so move the Fragment up to CREATED, then mark it as being removed, then
            // destroy it.
            moveToState(f, Fragment.CREATED, 0, 0, false);
            f.mRemoving = true;
            moveToState(f, Fragment.INITIALIZING, 0, 0, false);
            continue;
        }
        fs.mInstance = f;
        f.mSavedViewState = null;
        f.mBackStackNesting = 0;
        f.mInLayout = false;
        f.mAdded = false;
        f.mTargetWho = f.mTarget != null ? f.mTarget.mWho : null;
        f.mTarget = null;
        if (fs.mSavedFragmentState != null) {
            fs.mSavedFragmentState.setClassLoader(mHost.getContext().getClassLoader());
            f.mSavedViewState = fs.mSavedFragmentState.getSparseParcelableArray(
                    FragmentManagerImpl.VIEW_STATE_TAG);
            f.mSavedFragmentState = fs.mSavedFragmentState;
        }
    }

  	//先清空活跃的Fragment
    mActive.clear();
  	//从缓存中取出FragmentState 恢复活跃的Fragment并添加到mActive中
    for (FragmentState fs : fms.mActive) {
        if (fs != null) {
            Fragment f = fs.instantiate(mHost.getContext().getClassLoader(),
                    getFragmentFactory());
            f.mFragmentManager = this;
            if (DEBUG) Log.v(TAG, "restoreSaveState: active (" + f.mWho + "): " + f);
            mActive.put(f.mWho, f);
            fs.mInstance = null;
        }
    }

    // Build the list of currently added fragments.
  	//同理恢复add的Fragment
    mAdded.clear();
    if (fms.mAdded != null) {
        for (String who : fms.mAdded) {
            Fragment f = mActive.get(who);
            if (f == null) {
                throwException(new IllegalStateException(
                        "No instantiated fragment for (" + who + ")"));
            }
            f.mAdded = true;
            if (mAdded.contains(f)) {
                throw new IllegalStateException("Already added " + f);
            }
            synchronized (mAdded) {
                mAdded.add(f);
            }
        }
    }

    // Build the back stack.
    if (fms.mBackStack != null) {
        mBackStack = new ArrayList<BackStackRecord>(fms.mBackStack.length);
        for (int i=0; i<fms.mBackStack.length; i++) {
            BackStackRecord bse = fms.mBackStack[i].instantiate(this);
            mBackStack.add(bse);
            if (bse.mIndex >= 0) {
                setBackStackIndex(bse.mIndex, bse);
            }
        }
    } else {
        mBackStack = null;
    }

    if (fms.mPrimaryNavActiveWho != null) {
        mPrimaryNav = mActive.get(fms.mPrimaryNavActiveWho);
        dispatchParentPrimaryNavigationFragmentChanged(mPrimaryNav);
    }
    this.mNextFragmentIndex = fms.mNextFragmentIndex;
}