Fragment 源码浅析——Fragment(三)

一、 与 Fragment 相关的类

我们平时使用fragment的时候都是通过创建事务,来操作fragment,

    getSupportFragmentManager()  //获取到FragmentManager,它的实现类是FragmentManagerImpl
        .beginTransaction()    //获取到FragmentTransaction,它的实现类是BackStackRecord 
        .add(R.id.container, new MyFragment()) //调用FragmentTransaction的函数
        .commit();  //调用FragmentTransaction的函数

先来一张图,看一下各类直接的关系,下面会简要说明各类的用途

在这里插入图片描述

FragmentController

FragmentController 是一个中间对象,它的所有函数,都会去调用mHostFragmentHostCallback)对应的函数去执行

Activity 通过FragmentActivityFragmentActivity 通过 FragmentController 类管理 Fragment。

FragmentActivity 中有一个FragmentController的实例变量 ,在声明的时候进行初始化。所以当 Activity 被实例化的时候,FragmentController 就被实例化了。

下面是FragmentActivity 中的代码片段:

    final FragmentController mFragments = FragmentController.createController(new HostCallbacks());
    public FragmentManager getSupportFragmentManager() {
        return mFragments.getSupportFragmentManager();
    }
    public void dispatchCreate() {
        mHost.mFragmentManager.dispatchCreate();
    }

FragmentHostCallback 、HostCallback

FragmentController有一个类型为 FragmentHostCallback的变量mHost

FragmentHostCallback有一个类型为 FragmentManagerImpl 的变量mFragmentManager

FragmentController中的函数,其实都是调用mHost.mFragmentManager 的函数去执行

// Fragment 可以寄生在任何对象上,让 fragment 寄存在自己身上需要实现 FragmentHostCallback 类,实现里面的一些方法 。 
public abstract class FragmentHostCallback<E> extends FragmentContainer{

    final FragmentManagerImpl mFragmentManager = new FragmentManagerImpl();
    FragmentManagerImpl getFragmentManagerImpl() {
        return mFragmentManager;
    }
}

FragmentHostCallback 是一个抽象类,它的实现类是HostCallback

class HostCallbacks extends FragmentHostCallback<FragmentActivity> 

FragmentManager、FragmentManagerImpl

FragmentController中的函数,其实都是调用mHost.mFragmentManager 的函数去执行。这里的mHost 类型是FragmentHostCallbackmFragmentManager的类型是FragmentManager

commit() 调用后,具体的操作,fragment的生命周期操作、增加、显示、删除等等操作,都是由FragmentManagerImpl中来具体实现

FragmentTransaction、BackStackRecord

通过FragmentManager 的beginTransaction()函数获取FragmentTransaction

BackStackRecord继承自FragmentTransaction,它们是负责处理事务的,BackStackRecord 类实现了操作Fragment的所有事物,add,replace,remove,hide,show,等操作,最终都是有该类去具体执行

二、Activit 与 FragmentManager 建立关系

在这里插入图片描述

对不同的activity,FragmentActivityActivity ,他们和FragmentManager 建立关系的时机是不同的,现在用的比较多的是FragmentActivity,因为现在activity自动继承自AppCompatActivity,AppCompatActivity继承自FragmentActivity

下面先以Activity 来分析,再去看FragmentActivity的流程就很清晰了。

继承不同的Activity获取FragmentManager的方式不同,在Activity 中使用getFragmentManager(),在FragmentActivity中使用getSupportFragmentManager()。详情

创建Activity 的代码是在 ActivityThread 中的 performLaunchActivity()

  private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
               ...省略代码...
                activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
              ...省略代码...
                activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.referrer, r.voiceInteractor, window, r.configCallback);
               ...省略代码...

}

下面来到Activity.java的代码中看一下attach函数


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


    final void attach(Context context, ActivityThread aThread,
            Instrumentation instr, IBinder token, int ident,
            Application application, Intent intent, ActivityInfo info,
            CharSequence title, Activity parent, String id,
            NonConfigurationInstances lastNonConfigurationInstances,
            Configuration config, String referrer, IVoiceInteractor voiceInteractor,
            Window window, ActivityConfigCallback activityConfigCallback) {

        ...省略代码...
        
        mFragments.attachHost(null /*parent*/);
        
       ...省略代码...
    }

调用了FragmentController 的attachHost函数
而在FragmentActivity中调用FragmentController 的attachHost函数,是在onCreate()函数中

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        mFragments.attachHost(null /*parent*/);
                ...省略代码...
}

下面看一下FragmentController.java 中的attachHost函数

    public void attachHost(Fragment parent) {
        mHost.mFragmentManager.attachController(
                mHost, mHost /*container*/, parent);
    }

这里变量mHostFragmentHostCallback 类型

调用FragmentManagerattachController()

// 第一个参数是宿主;
// 第二参数是容器,FragmentHostCallback 继承于 FragmentContainer 也代表容器;
// 第三个参数是父类 Fragment
public void attachController(FragmentHostCallback host,
            FragmentContainer container, Fragment parent) {
        // 宿主只能有一个
        if (mHost != null) throw new IllegalStateException("Already attached");
        mHost = host;
        mContainer = container;
        mParent = parent;
}

这个方法最终将宿主对象和控制器中的 FragmentManager 关联,内部就是进行赋值。
为什么里面传的是 null?注释写了 parent。应该是传入的父类 fragment,而由 Activity 创建的 fragment 没有父类,所以是 null。

三、事务操作

    getSupportFragmentManager()  //获取到FragmentManager,它的实现类是FragmentManagerImpl
        .beginTransaction()    //获取到FragmentTransaction,它的实现类是BackStackRecord 
        .add(R.id.container, new MyFragment()) //调用FragmentTransaction的函数
        .commit();  //调用FragmentTransaction的函数


在Activity中调用getSupportFragmentManager(),会通过mHost (类型FragmentController)获取FragmentManager

    public FragmentManager getSupportFragmentManager() {
        return mHost.getFragmentManagerImpl();
    }

现在来看 beginTransaction()

// FragmentManagerImpl 
public FragmentTransaction beginTransaction() {
    return new BackStackRecord(this);
}

// BackStackState
final class BackStackRecord extends FragmentTransaction implements
        FragmentManager.BackStackEntry, FragmentManagerImpl.OpGenerator {
    static final String TAG = FragmentManagerImpl.TAG;
    static final boolean SUPPORTS_TRANSITIONS = Build.VERSION.SDK_INT >= 21;

    final FragmentManagerImpl mManager;
    
    // 表示一系列操作
    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 class Op {
        // 执行的操作(添加/删除。。。)
        int cmd;
        Fragment fragment;
        
        // 进栈动画
        int enterAnim;
        int exitAnim;
        
        // 出栈动画
        int popEnterAnim;
        int popExitAnim;

        Op() {
        }
        
        Op(int cmd, Fragment fragment) {
            this.cmd = cmd;
            this.fragment = fragment;
        }
    }
    
    // ...
}

BackStackRecord 继承 FragmentTransation 抽象类,同时实现 BackStackEntry 和 OpGenerator 接口。我们在程序里要进行 add,remove,replace 等等操作时,用的是 FragmentTransation 类型,其实这个实例是 BackStackRecord 对象。

BackStackRecord 是用于保存用户一次提交的操作行为,一次提交可以有多个操作,是一组 add、replace、remove 变化的集合。每一次的变化,即是一次操作,用 Op 类来表示。在 BackStackRecord 里保存了一个双向链表 (mHead, mTail),用于保存一组操作。Op 类中的 cmd 表示操作类型(如 add,replace,remove 等等)。最终通过 commit() 方法提交一些列操作。

BackStackRecord

BackStackRecord 实现了操作 fragment 的所有事务,每个方法内部 最终都是由 addOp()实现的。


    @Override
    public FragmentTransaction add(Fragment fragment, String tag) {
        doAddOp(0, fragment, tag, OP_ADD);
        return this;
    }

    @Override
    public FragmentTransaction add(int containerViewId, Fragment fragment) {
        doAddOp(containerViewId, fragment, null, OP_ADD);
        return this;
    }

    @Override
    public FragmentTransaction add(int containerViewId, Fragment fragment, String tag) {
        doAddOp(containerViewId, fragment, tag, OP_ADD);
        return this;
    }

    public FragmentTransaction replace(int containerViewId, Fragment fragment, String tag) {
        if (containerViewId == 0) {
            throw new IllegalArgumentException("Must use non-zero containerViewId");
        }

        doAddOp(containerViewId, fragment, tag, OP_REPLACE);
        return this;
    }
    
    @Override
    public FragmentTransaction remove(Fragment fragment) {
        addOp(new Op(OP_REMOVE, fragment));

        return this;
    }

    @Override
    public FragmentTransaction hide(Fragment fragment) {
        addOp(new Op(OP_HIDE, fragment));

        return this;
    }

    @Override
    public FragmentTransaction show(Fragment fragment) {
        addOp(new Op(OP_SHOW, fragment));

        return this;
    }

    @Override
    public FragmentTransaction detach(Fragment fragment) {
        addOp(new Op(OP_DETACH, fragment));

        return this;
    }

    @Override
    public FragmentTransaction attach(Fragment fragment) {
        addOp(new Op(OP_ATTACH, fragment));

        return this;
    }

 private void doAddOp(int containerViewId, Fragment fragment, String tag, int opcmd) {
 
    // ...
    // 将 manager 赋值给 fragment
    fragment.mFragmentManager = mManager;
    
    // 设置 containerViewId
    if (containerViewId != 0) {
      fragment.mContainerId = fragment.mFragmentId = containerViewId;
    }
    // ...
    // 将这个事务对象加到 ArrayList 中
    addOp(new Op(opcmd, fragment));
  }
    void addOp(Op op) {
        mOps.add(op);
        op.enterAnim = mEnterAnim;
        op.exitAnim = mExitAnim;
        op.popEnterAnim = mPopEnterAnim;
        op.popExitAnim = mPopExitAnim;
    }

add、replace、remove 只是把这些操作,收集起来,真正的执行是在commit()

提交事务

常用的提交事务, 一种是将所有事物放入事务队列,轮询执行。另一种是立刻执行,从方法命名也可以看出来。看看它们内部是如何提交的。而立刻提交是不允许加入回退栈的。

    @Override
    public int commit() {
        return commitInternal(false);
    }

    int commitInternal(boolean allowStateLoss) {
     
        mCommitted = true;
        
        // 判断是否加入回退栈
        if (mAddToBackStack) {
            mIndex = mManager.allocBackStackIndex(this);
        } else {
            mIndex = -1;
        }
        // 将事务添加到轮询队列等待执行
        mManager.enqueueAction(this, allowStateLoss);
        return mIndex;
    }
    
     public void enqueueAction(OpGenerator action, boolean allowStateLoss) {
        // 检查状态
        if (!allowStateLoss) {
            checkStateLoss();
        }
        synchronized (this) {
            if (mDestroyed || mHost == null) {
                throw new IllegalStateException("Activity has been destroyed");
            }
            if (mPendingActions == null) {
                mPendingActions = new ArrayList<>();
            }
            
            mPendingActions.add(action);
            scheduleCommit();
        }
    }
    
    // 将事务交通过 handler post 执行
      private void scheduleCommit() {
        synchronized (this) {
            boolean postponeReady =
                    mPostponedTransactions != null && !mPostponedTransactions.isEmpty();
            boolean pendingReady = mPendingActions != null && mPendingActions.size() == 1;
            if (postponeReady || pendingReady) {
                mHost.getHandler().removeCallbacks(mExecCommit);
                mHost.getHandler().post(mExecCommit);
            }
        }
    }
    
// mExecCommit 这个 Runnable 做的事:
public boolean execPendingActions() {
    ensureExecReady(true);

    boolean didSomething = false;
    while (generateOpsForPendingActions(mTmpRecords, mTmpIsPop)) {
        mExecutingActions = true;
            try {
                // 优化执行我们的实务操作,具体的执行就在这个方法里
                optimizeAndExecuteOps(mTmpRecords, mTmpIsPop);
            } finally {
                cleanupExec();
            }
            didSomething = true;
        }

        doPendingDeferredStart();

        return didSomething;
    }

    
    // 这里进行了优化和执行事务的操作,执行事务是由 executeOpsTogether 完成
    private void optimizeAndExecuteOps(ArrayList<BackStackRecord> records,
            ArrayList<Boolean> isRecordPop) {
       // ... 
        

        final int numRecords = records.size();
        int startIndex = 0;
        // 遍历所有的事务
        for (int recordNum = 0; recordNum < numRecords; recordNum++) {
            // 标记优化
            final boolean canOptimize = records.get(recordNum).mAllowOptimization;
            if (!canOptimize) {
                // ..
                if (startIndex != recordNum) {
                    executeOpsTogether(records, isRecordPop, startIndex, recordNum);
                }
                
                executeOpsTogether(records, isRecordPop, recordNum, optimizeEnd);
                // ...
            }
        }
        if (startIndex != numRecords) {
            executeOpsTogether(records, isRecordPop, startIndex, numRecords);
        }
    }

    
    // 这里发现执行事务由 executeOps 方法来执行的
   private void executeOpsTogether(ArrayList<BackStackRecord> records,
            ArrayList<Boolean> isRecordPop, int startIndex, int endIndex) {
        final boolean allowOptimization = records.get(startIndex).mAllowOptimization;
        // ... 
       

       // ...
        executeOps(records, isRecordPop, startIndex, endIndex);

        // ...

        if (postponeIndex != startIndex && allowOptimization) {
            // need to run something now
            FragmentTransition.startTransitions(this, records, isRecordPop, startIndex,
                    postponeIndex, true);
            moveToState(mCurState, true);
        }

        // ..
        if (addToBackStack) {
            reportBackStackChanged();
        }
    }
    
 
    // 最终判断执行 executeOps 还是 executePopOps
   private static void executeOps(ArrayList<BackStackRecord> records,
            ArrayList<Boolean> isRecordPop, int startIndex, int endIndex) {
        for (int i = startIndex; i < endIndex; i++) {
            final BackStackRecord record = records.get(i);
            final boolean isPop = isRecordPop.get(i);
            if (isPop) {
                record.bumpBackStackNesting(-1);
                // Only execute the add operations at the end of
                // all transactions.
                boolean moveToState = i == (endIndex - 1);
                record.executePopOps(moveToState);
            } else {
                record.bumpBackStackNesting(1);
                record.executeOps();
            }
        }
    }

下面这个函数的具体操作,是通过fragmentManager 来执行的

void executeOps() {
        final int numOps = mOps.size();
        for (int opNum = 0; opNum < numOps; opNum++) {
            final Op op = mOps.get(opNum);
            final Fragment f = op.fragment;
            if (f != null) {
                f.setNextTransition(mTransition, mTransitionStyle);
            }
            switch (op.cmd) {
                case OP_ADD:
                    f.setNextAnim(op.enterAnim);
                    mManager.addFragment(f, false);
                    break;
                case OP_REMOVE:
                    f.setNextAnim(op.exitAnim);
                    mManager.removeFragment(f);
                    break;
                case OP_HIDE:
                    f.setNextAnim(op.exitAnim);
                    mManager.hideFragment(f);
                    break;
                // ...
                
            }
        }
        // ...
    }

最后调用 movetToState()

     public void addFragment(Fragment fragment, boolean moveToStateNow) {
            if (mAdded == null) {
                mAdded = new ArrayList<Fragment>();
            }
            makeActive(fragment);
            if (!fragment.mDetached) {
                // ...
                mAdded.add(fragment);
                fragment.mAdded = true;
                fragment.mRemoving = false;
                if (fragment.mView == null) {
                    fragment.mHiddenChanged = false;
                }
                if (fragment.mHasMenu && fragment.mMenuVisible) {
                    mNeedMenuInvalidate = true;
                }
                if (moveToStateNow) {
                    moveToState(fragment);
                }
            }
        }
    void moveToState(Fragment f) {
        moveToState(f, mCurState, 0, 0, false);
    }

这一段的代码特别长,根据状态调用对应的生命周期, 在添加的时候把 View 添加进父布局。通过 View.GONE/VISIBLE 显示隐藏 Fragment。

    void moveToState(Fragment f, int newState, int transit, int transitionStyle,
            boolean keepActive) {
    if (f.mState <= newState) {
            // ...
            switch (f.mState) {
                case Fragment.INITIALIZING:
                    // OnFragmentPreAttached
                    dispatchOnFragmentPreAttached(f, mHost.getContext(), false);
                    // 调用 fragment 的 onAttach
                    f.onAttach(mHost.getContext());
                    
                    // 回调宿主的 onAttachFragment
                    mHost.onAttachFragment(f);
                    
                    dispatchOnFragmentAttached(f,     mHost.getContext(), false);
                    // 执行 fragment 的 onCreate
                    f.performCreate(f.mSavedFragmentState);

                    dispatchOnFragmentCreated(f, f.mSavedFragmentState, false);

                // ...
                case Fragment.CREATED:
                    f.mContainer = container;
                    // fragmenr 执行 onCreateView 创建 View
                    f.mView = f.performCreateView(f.getLayoutInflater(
                                    f.mSavedFragmentState), container, f.mSavedFragmentState);
                                    
                    if (container != null) {
                        // 加入父布局
                        container.addView(f.mView);
                    }
                    // 设置 View 的 GONE VISIBLE 来控制 hide,show
                    if (f.mHidden) {
                        f.mView.setVisibility(View.GONE);
                    }
                    
                    // onViewCreated
                    f.onViewCreated(f.mView, f.mSavedFragmentState);
                    
                    // 回调
                    dispatchOnFragmentViewCreated(f, f.mView, f.mSavedFragmentState,false);
                       
                    // onActivityCreated   
                    f.performActivityCreated(f.mSavedFragmentState);

                // ...
                case Fragment.ACTIVITY_CREATED:
                //...
                case Fragment.STOPPED:
                // ..
                    // onStart
                    f.performStart();

                    dispatchOnFragmentStarted(f, false);

                case Fragment.STARTED:
                    // ...
                    // onResume
                    f.performResume();
                    dispatchOnFragmentResumed(f, false);

            }
        } else if (f.mState > newState) {
            switch (f.mState) {
                case Fragment.RESUMED:
                    // onPause
                    f.performPause();
                    dispatchOnFragmentPaused(f, false);

                // ..
                case Fragment.STARTED:
                    // onStop
                    f.performStop();
                    dispatchOnFragmentStopped(f, false);
                // ...
                case Fragment.STOPPED:
                    f.performReallyStop();
                    // ...    
                case Fragment.ACTIVITY_CREATED:
                    // ..
                    // onDestroyView
                    f.performDestroyView();
                    dispatchOnFragmentViewDestroyed(f, false);

                case Fragment.CREATED:
                    // onDestory
                    f.performDestroy();
                    // onDetach
                    f.performDetach();


                // ...
            }
        }
    }

到此,Fragment的大概流程就分析完了,建议大家打开代码,跟着代码,去看文章会更有感觉


参考:
https://juejin.im/post/5a30f2f3f265da4320033d2d

©️2020 CSDN 皮肤主题: 撸撸猫 设计师: 设计师小姐姐 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值