前言
随着谷歌那边Jetpack单activity应用的流行,fragment以后用的概率会越来越高,对fragment有个完整的认识愈发重要。在我的个人印象中,对fragment的认识也是有点模糊,趁着周末有时间,直接瞅了瞅相关源码,顺手也记录一下。
整体介绍
Fragment如果看过相关源码的话可以简单的认为:Fragment就是一个具有生命周期的View.一个FragmentTransaction的完成就意味了一个ContainerView中移除添加view或者设置f.mView Visiblity的动作。当然口说无凭,我们直接fucking the source code.
源码流程介绍
我们先上一段比较简单常见的代码段:
supportFragmentManager.beginTransaction()
.replace(R.id.container, Fragment())
.commit();
beginTransaction()返回了一个FragmentTransaction的子类对象BackStackRecord:
//FragmentManagerImpl.java
public FragmentTransaction beginTransaction() {
return new BackStackRecord(this);
}
紧接着我们看replace方法
//FragmentTransaction.java
//保存所有的options(操作)
ArrayList<Op> mOps = new ArrayList<>();
@NonNull
public FragmentTransaction replace(@IdRes int containerViewId, @NonNull Fragment fragment,
@Nullable String tag) {
if (containerViewId == 0) {
throw new IllegalArgumentException("Must use non-zero containerViewId");
}
//添加一个Op 其opcmd 的类型为OP_REPLACE 后面会根据OP_REPLACE来做对应的操作
doAddOp(containerViewId, fragment, tag, OP_REPLACE);
return this;
}
public void doAddOp(int containerViewId, Fragment fragment, @Nullable String tag, int opcmd) {
...
//设置fragment的tag
fragment.mTag = tag;
...
//设置fragment的mContainerId
fragment.mContainerId = fragment.mFragmentId = containerViewId;
//将新的Op对象放到list中
addOp(new Op(opcmd, fragment));
}
void addOp(Op op) {
mOps.add(op);
...
}
看完上面两个方法介绍,感觉前两个方法没做啥东西。。实际上replace方法只是为commit方法准备一些操作数据,commit才是真正的执行,commit方法执行流程比较复杂,我们忽略中间方法,简要描述一下执行流程:通过调用commit()方法,然后中间通过handler post了一个runnable,这个runnable里面的方法具体就是处理了Op对象和Fragment,层层调用最终调到了moveToState方法中:
void moveToState(Fragment f, int newState, int transit, int transitionStyle,
boolean keepActive) {
if (f.mState <= newState) {
switch (f.mState) {
...
case Fragment.INITIALIZING:
...
// fall through 注意源码这一块并没有break 会继续往下执行
case Fragment.CREATED:
...
// fall through
case Fragment.ACTIVITY_CREATED:
...
case Fragment.STARTED:
}
}
看moveToState 里面的switch分支,我们可以知道这个应该和fragment的生命周期有关系,并且有点核心哦。那么接下来我们介绍其中两个case中的源码:
//FragmentManagerImpl.java
case Fragment.INITIALIZING:
// 源码日志:执行完这个case 我就要到fragment的created状态了
if (DEBUG) Log.v(TAG, "moveto CREATED: " + f);
...
//通知监听fragment生命周期的listener我即将要attach了
dispatchOnFragmentPreAttached(f, mHost.getContext(), false);
//执行fragment的preformAttach方法,并回调了fragment的attach方法
f.performAttach();
//通知监听fragment生命周期的listener我已经attached了
dispatchOnFragmentAttached(f, mHost.getContext(), false);
//r如果fragment还没创建 则performCreate 和attach类似
if (!f.mIsCreated) {
dispatchOnFragmentPreCreated(f, f.mSavedFragmentState, false);
//回调fragment的onCreate生命周期
f.performCreate(f.mSavedFragmentState);
dispatchOnFragmentCreated(f, f.mSavedFragmentState, false);
} else {
f.restoreChildFragmentState(f.mSavedFragmentState);
f.mState = Fragment.CREATED;
}
// fall through
然后我们挑其中fragment.preformCreate()源码瞅瞅:
//fragment.java
void performCreate(Bundle savedInstanceState) {
...
//state状态更改为created
mState = CREATED;
mCalled = false;
...
//回调onCreate方法
onCreate(savedInstanceState);
//isCreated为true
mIsCreated = true;
//通知lifeCycle onCreateEvent
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
}
具体上面代码就不总结了,注释还是比较清晰的。接下来我们看看另外一个case的源码:
case Fragment.CREATED:
...
if (DEBUG) Log.v(TAG, "moveto ACTIVITY_CREATED: " + f);
if (!f.mFromLayout) {
ViewGroup container = null;
if (f.mContainerId != 0) {
//找到view 具体实现在activity中 就是一个findViewById
container = (ViewGroup) mContainer.onFindViewById(f.mContainerId);
}
//给mContainer赋值
f.mContainer = container;
//回调onCreateView
f.performCreateView(f.performGetLayoutInflater(
f.mSavedFragmentState), container, f.mSavedFragmentState);
if (f.mView != null) {
f.mInnerView = f.mView;
f.mView.setSaveFromParentEnabled(false);
if (container != null) {
//将我们重写的onCreateView返回的值 添加到container中
container.addView(f.mView);
}
//回调onViewCreated
f.onViewCreated(f.mView, f.mSavedFragmentState);
...
}
}
//回调onActivityCreated
f.performActivityCreated(f.mSavedFragmentState);
dispatchOnFragmentActivityCreated(f, f.mSavedFragmentState, false);
...
// fall through
终于我们在这个case里看到了我们熟悉的view 和我们经常重写的onCreateView 和onViewCreated。。。 太难了。。。 到这基本上fragment算是和container绑定起来了。后续的比如onStart onResume等生命周期基本类似 大家自己挖掘一下就好了。。。