创建一个Fragment的流程
//创建Fragment
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.sync_viewpager_container, new Sync_SubjectExerciseFragment(),"subject");
fragmentTransaction.commit();
首先第一步就是获取FragmentManager 对象
- AppCompatActivity 继承 FragmentActivity
- FragmentActivity 包含 FragmentController
- FragmentController 是一个代理
- FragmentHostCallback 被FragmentController持有,有一个FragmentManagerImpl,真正的进行fragment操作
- FragmentContainer view容器
FragmentTransaction
- Fragment操作的事务,每个FragmentTransaction对象,代表着系列Fragment操作的事务
- 操作Fragment的添加,删除,隐藏,显示时,都要使用FragmentTransaction
- FragmentTransaction其实是个抽象类,真正的实现类是BackStackRecord
BackStackRecord
- BackStackRecord实现了FragmentTransaction,每一个BackStackRecord对象,都代表了一次Fragment操作事务,
OP
-
op对象主要保存了FragmentTransaction操作事务中的单次操作,是相对于Fragment而言的,每个op对象,保存了add -> new Op
-
把Fragment和操作的命令 OP_ADD映射关系
-
最终添加到OP 列表中
-
addOp 包含了 Fragment动画
Commit(在BackStackRecord的方法)
- 在主线程中已不执行,其实也是Handler抛出任务,等待主线程调度执行,
- commit需要宿主activity保存状态之前调用,否则报错
- 这是因为如果activity出现异常需要恢复状态,在保存状态之后的commit将会丢失,这和调用的初衷不符,所以会报错。
commitAllowingStateLoss
- 也是异步执行的,但是他的不同之处在于,允许在activity保存状态之后调用,也就是说他遇到状态丢失不会报错
commitInternal (allowStateLoss)
- 是否加入回退栈
- 异步任务入队 mManager.enqueueAction(this,allowStateLoss)
enqueueAction
- mPendingActions.add(action) 讲commit处理操作放置到mPendingActions列表中(ArrayList)
- scheduleCommit 发送任务
scheduleCommit
- mHost.getHandler().post(mExecCommit);
- mHost 就是 FragmentActivity 的mHost 获取了主线程的handler对象,新建runnable对象,最终执行 execPendingActions()
execPendingActions
- 将mPendingActions列表的action拷贝到mTempActions数组里
- mTempRecords, 前者用来临时存储所有待执行的动作(mPendingActions)生成的BackStackRecord.
- mTmpIsPop用来存储BackStackRecord是否出栈
- removeRedundantOperationsAndExecute()这里是入口执行 BackStackRecord 真正的去执行Fragment 操作
commitNow 立即执行
- disallowAddToBackStack() 不允许添加到回退栈中
- mMananger.execSingleAction 立即执行
- removeRedundantOperationsAndExecute()这里是入口执行 BackStackRecord
commitNow 为什么不允许添加到回退栈?
- 因为以时间添加到回退栈
execPendingActions
真正的去执行Fragment 操作
- mAdded 代表存活的Fragment
- mTmpRecords 用于优化执行的临时变量
- mTmpIsPop 用于优化执行的临时变量 用来存储是否出栈
removeRedundantOperationsAndExecute()
- executeOpsTogether 这里将Ops过滤一遍
- expandReplaceOps 方法吧replace替换(目标fragment已经被add)成相应的remove和add操作
- executeOps () 真正处理的入口
- moveToState 最后一个事务时需要moveTostate为true
- record.executePopOps 对出栈事务的所有Op进行逆操作(执行出栈)
- record.executeOps 执行非出栈事务的所有Op操作(执行commit)
executeOps 很多对fragment的操作
比如addFragment 操作
- 是执行FragmentManager 的 addFragment
- makeActive 更新没Active列表
- 更新mAdded列表
- 更新当前fragment状态
- 最终调用moveToState
moveToState
-
类正向的切换顺序,INITIALZEING -> CREATE -> ACTIVITY_CREATE -> STARTED -> RESUME 值变得越来愈大。代表着fragment从初始化到可见交互的状态
-
类是反向的切换顺序,与之相反,值越来越小,代表着fragment从可见可交互到与activity分离的状态
Fragment
fragment = View + 固有属性 + state
- view就是添加到界面中的视图,
- 固有属性就是attr,指的是fragment的一些固有属性,不会随着fragment的生命周期发生变化
- state,就是fragment当前的状态,fragment在生命周期变迁中会发生改变的状态,其实就是说白了,fragment就是一个拥有生命周期的自定义View
fragment状态并不等同于他的生命周期
状态
值 | 状态 | 意义 | 入口方法 |
---|---|---|---|
0 | INITIALIZING | fragment尚未初始化或者已经被销毁 | dispatchDestroy |
1 | CREATE | Fragement已经被创建 | dispatchDestroyView |
2 | ACTIVITY_CREATE | fragment所在activity已经创建成功 | dispatchActivityCreate |
3 | STARTED | fragment已经可见,但是还不可以接受点击事件 | dispatchPause |
4 | RESUME | fragment已经被创建,但是尚未不可见 | dispatchResume |
Fragment 如何 添加到 Activity的?
fragment 和 activity 的生命对应的关系
moveToState (CREATE)
- Activity#onCreate -> Fragment#onAttch -> Fragment#onCreate -> Fragment#onCreateView -> Fragment#onViewCreate -> Fragment#onActivityCreate
moveToState (ACTIVITY_CREATE)
- Activity#onStart
moveToState (STARTED) - Fragment#onCreateView -> Fragment#onViewCreate -> Fragment#onActivityCreate -> Activity#onResume
moveToState (RESUME)
- Fragment#onStart -> Fragment#onResume -> Fragment 可见可交互
moveToState (STARTED) - Fragment#onPause -> Activity#onPause -> Fragment#onStop-> Activity#onStop
moveToState (CREATE)
- Fragment#onDestroyView -> Fragment#onDestroy
moveToState (INIT)
- Fragment#onDetach -> Activity#onDestroy
allocBackStackIndex() 用于给加入到返回栈的BackStackRecord分配下标
- mBackStackIndices(ArrayList) 记录 BackStackRecord
- mAvalBackStackIndices (SparseList) 记录 mBackStackIndices 下标index(已经被回收BackStackRecord),下次mBackStackIndices存储时,直接复用
类图 -> 类的组合
时序图-> 类的交互