作为一名 Android 开发者,大家绝对都接触过 Fragment 开发,而且绝大多数人例如我一直都很难记住下图 Fragment 复杂的生命周期,更别说要将其与 Activity 的生命周期关联起来。
死背是无法解决问题的,若我们能从源码的角度对 Fragment 的启动过程进行分析,就能达到事半功倍的效果。那么我们选择上图中的第一部分入手吧。
下面我将会分析 Fragment 这一部分的启动过程,剩下部分的逻辑没有多大差异,所用的 Android SDK 版本为 23。
一般情况下我们 MainActivity 需要显示一个 ContentFragment,代码可以这么写。
//MainActivity
public class MainActivity extends Activity{
ContentFragment mContentFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContentFragment = ContentFragment.newInstance(null);
getFragmentManager()
.beginTransaction()
.replace(R.id.container,mContentFragment)
.commit();
}
}
同时为了方便起见,我大概介绍下我们即将遇到的几个类。第一次看的时候可能印象不深,但没关系,后面还会反复提起。
上面 UML 类图并不是完整的,但已经足够了。
- ActivityThread : 大名鼎鼎的 Android 入口类,我们的分析也将会从它开始
- Instrumentation : ActivityThread 的得力助手,帮助 ActivityThread 触发 Activity 的生命周期
- MainActivity : 就是上文提到例子中的 MainActivity 类,继承自 Activity
- HostCallbacks : Activity 的内部类,继承自 FragmentHostCallback
- FragmentHostCallback : 持有 Handler、FragmentManagerImpl 等等对象的引用,别的对象可以通过持有它的引用间接控制 FragmentManagerImpl 等等对象
- FragmentController : Activity 通过控制它间接向 FragmentManagerImpl 发出命令
- FragmentManagerImpl : 顾名思义,它继承自 FragmentManager,用来对 Fragment 进行管理,在 FragmentHostCallback 中被初始化
- BackStackRecord : 继承自 FragmentTransation 并实现了 Runnable,每次调用 FragmentManager 对象的
beginTransaction()
方法都会产生一个 BackStackRecord 对象,可以将其理解为对 Fragment 的一系列操作(即事务)- Op : 每次对 Fragment 的操作都会产生一个 Op 对象,其表示双向链表的一个结点
哈哈,没印象无所谓...
那从哪里开始呢,我们注意到 Activity 类中有个 FragmentController 实例,那它是怎么初始化的?我们直接在 Activity 中搜索 FragmentController 关键字,即可找到如下代码:
//Activity
final FragmentController mFragments = FragmentController.createController(new HostCallbacks());
原来在声明成员变量的同时初始化的呀,那也就是说在 Activity 被实例化时该成员变量也会被初始化,那么 Activity 又是在哪里被实例化的呢?作为一位看过 Activity 启动过程源码解析的男人,一下子就能想到 ActivityThread 的 performLaunchActivity
方法(当然,没看过 Activity 启动过程源码的朋友也没事,这篇文章分析的流程比那个简单多了,而且我们这里并不关注 Activity 的启动过程,看了这个或许对看那个有一定帮助),那我们去 ActivityThread 类的 performLaunchActivity
方法找下吧
//ActivityThread
Activity activity = null;
try {
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
/*这个方法最终会通过反射调用 Activity 的无参构造方法*/
//...
} catch (Exception e) {
//...
}
//上面代码省略了一些非本次该关注的逻辑,下同
我们从 Activity 的实例化这里开始讲起吧
上文说到,Activity 会在 ActivityThread 的方法 performLaunchActivity
中通过反射实例化,相当于调用了它的无参构造方法,接着会触发 Activity 的成员变量 mFragments 的初始化,即
//Activity
final FragmentController mFragments = FragmentController.createController(new HostCallbacks());
直接实例化了一个 HostCallbacks 对象并将其作为参数传入 FragmentController 类的 createController
静态方法中。
好的,我们先看看 HostCallbacks 初始化做了啥。
//HostCallbacks(因为 HostCallbacks 是 Activity 的内部类,所以是在 Activity.java 文件里)
public HostCallbacks() {
super(Activity.this );
}
嗯,因为 HostCallbacks 是 Activity 的内部类,所以直接用 Activity.this
作为参数调用它父类的构造方法,通过上文我们知道它的父类是 FragmentHostCallback
//FragmentHostCallback
FragmentHostCallback(Activity activity) {
this(activity, activity /*context*/, activity.mHandler, 0 /*windowAnimations*/);
}
FragmentHostCallback(Activity activity, Context context, Handler handler,
int windowAnimations) {
mActivity = activity;
mContext = context;
mHandler = handler;
mWindowAnimations = windowAnimations;
}
我们可以了解到它最终调用了 FragmentHostCallback 四个参数的重载构造方法,并会将 Activity 、Handler 等等对象保存到它的成员变量中。上文说到 FragmentManagerImpl 会在 FragmentHostCallback 中被初始化,看来它不是在构造方法中被初始化,那我们到成员变量的声明处看看吧。
//FragmentHostCallback
final FragmentManagerImpl mFragmentManager = new FragmentManagerImpl();
又是在声明的同时初始化。FragmentManagerImpl 继承自抽象类 FragmentManager,FragmentManagerImpl 采用的是默认的构造方法,所以这部分的分析就到此为止了。对了,FragmentManagerImpl 和 FragmentManager 两个类都是在 FragmentManager.java
文件中的,而且不是内外部类关系,FragmentManagerImpl 类的声明如下
//FragmentManager
final class FragmentManagerImpl extends FragmentManager implements LayoutInflater.Factory2{
//...
}
作用域是包级的,包名是 android.app
。
上一节后我们已经有了一个 HostCallback 对象,并将其作为参数传给 FragmentController 的 createController
静态方法,我们现在进去看看吧。
//FragmentController
public static final FragmentController createController(FragmentHostCallback> callbacks) {
return new FragmentController(callbacks);
}
private FragmentController(FragmentHostCallback> callbacks) {
mHost = callbacks;
}
原来 FragmentController 隐藏了自己的构造方法,createController
就如同工厂方法,最后令 FragmentController 对象持有了 HostCallbacks 对象的引用。这样 FragmentController 就能通过 HostCallbacks 对象的引用来间接调用 FragmentManagerImpl 了啦,因为你看上面 FragmentHostCallback 类中 mFragmentManager 的声明也是默认包级的。
在 Activity 实例化的过程中,初始化了它的成员变量 FragmentController,FragmentController 持有了 HostCallbacks 对象的引用,HostCallbacks 是 Activity 的内部类,HostCallbacks 用 Activity 对象作为参数调用自己父类 FragmentHostCallback 的构造方法,接着 FragmentHostCallback 会持有了 Activity、Handler 等等对象的引用,并在声明 mFragmentManager 成员变量的同时实例化 FragmentManagerImpl 对象。
在 ActivityThread 类的 performLounchActivity
方法里 Activity 被实例化后不久会被调用重量级的 attach
方法,我们试试到这方法下看看是否有我们需要的信息。
//Activity
mFragments.attachHost(null /*parent*/);
我们知道 mFragments 就是 FragmentController 对象的引用,看来这里确实有些初始化操作,那为什么是传入 null 呢?我们看下方法吧。
//FragmentManagerImpl
public void attachHost(Fragment parent) {
mHost.mFragmentManager.attachController(
mHost, mHost /*container*/, parent);
}
因为 Fragment 下也能有自己的子 Fragment,而现在我们的 Fragment 是在 Activity 下的,所以这里当然就直接传入 null 啦。我们再注意到本方法调用了 mHost 的 mFragmentManager 成员变量的 attachController
方法,我们只需关心方法的第一个参数。
//FragmentManagerImpl
public void attachController(FragmentHostCallback> host, FragmentContainer container,
Fragment parent) {
if (mHost != null) throw new IllegalStateException("Already attached");
mHost = host;
mContainer = container;
mParent = parent;
}
嗯,现在 FragmentManagerImpl 对象也持有了 HostCallbacks 对象的引用。
这一部分我们关注的仅仅是 FragmentManagerImpl 对象持有了 HostCallbacks 对象的引用。
我们知道 Fragment 的生命周期与 Acitivty 的有对应关系,那么我们也就可以猜到 Activity 的生命周期方法被触发时,Activity 会同时触发 Fragment 对应的生命周期方法,而且是通过自己持有的 FragmentController 对象来触发的,我们来看看是不是这样子吧。Activity 生命周期第一个被调用的方法是 onCreate
方法,它是在哪里被触发的呢?现在就是 ActivityThread 的得力助手 Instrumentation 出场的时候了!
还是在 ActivityThread 的 performLounchActivity
方法中,我们发现如下代码
//ActivityThread
mInstrumentation.callActivityOnCreate(activity, r.state);
跳去 Instrumentation 类看看
//Instrumentation
public void callActivityOnCreate(Activity activity, Bundle icicle) {
//...
activity.performCreate(icicle);
//...
}
调用了 performCreate
方法,注意这里的 activity 的运行时类型是 MainActivity,因为我们的 MainActivity 继承了 Activity,但 performCreate
方法是 final 的,MainActivity 无法重写,所以调用了其父类 Activity 的 performCreate
方法,我们去看下
//Activity
final void performCreate(Bundle icicle) {
onCreate(icicle);
//...
performCreateCommon();
}
先调用 onCreate
方法再调用 performCreateCommon
方法,同时我们注意到 onCreate
方法最先被调用而 performCreateCommon
最后被调用,两个方法都会分别触发 Fragment 的生命周期方法,这样安排是有目的的。下面我们分别分析。
PS : 下面是一连串的调用,先休息下,揉揉眼睛,喝喝水吧。
因为 MainActivity 重写了 Activity 的 onCreate
方法,我们先再看下我们重写的 onCreate
方法。
//MainActivity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContentFragment = ContentFragment.newInstance(null);
getFragmentManager()
.beginTransaction()
.replace(R.id.container,mContentFragment)
.commit();
}
这个方法做了挺多操作的,我们还是一个一个来哈。
首先调用了父类 Activity 的 onCreate
方法,我们去看看做了啥。
//Activity
@MainThread
@CallSuper
protected void onCreate(@Nullable Bundle savedInstanceState) {
//...
mFragments.dispatchCreate();
//...
}
Activity 好懒哟,又让人家 FragmentController 干活,可怜的 FragmentController
//FragmentController
public void dispatchCreate() {
mHost.mFragmentManager.dispatchCreate();
}
FragmentController 深得 Activity 精髓,把活推给了 FragmentManagerImpl,原来 FragmentManagerImpl 才是苦力。
//FragmentManagerImpl
public void dispatchCreate() {
//...
moveToState(Fragment.CREATED, false);
}
void moveToState(int newState, boolean always) {
moveToState(newState, 0, 0, always);
}
void moveToState(int newState, int transit, int transitStyle, boolean always) {
if (mHost == null && newState != Fragment.INITIALIZING) {
throw new IllegalStateException("No activity");
}
if (!always && mCurState == newState) {
return;
}
mCurState = newState;
if (mActive != null) {
//...
}
}
上面有三个方法被顺序调用,到了最后一个 moveToState
方法时我们只需关注它的参数 newState = Fragment.CREATED、always = false,而默认情况下成员变量 mCurState = Fragment.INITIALIZING、mActive = null,所以该方法执行后只有一个值得我们关注的细节 mCurState = Fragment.CREATED 了
MainActivity 的父类的 onCreate
方法执行完后我们该关注 getFragmentManager
方法了,到 Activity 中看看这个方法吧。
//Activity
public FragmentManager getFragmentManager() {
return mFragments.getFragmentManager();
}
//FragmentController
public FragmentManager getFragmentManager() {
return mHost.getFragmentManagerImpl();
}
只是直接返回 HostCallbacks 对象持有的 FragmentManagerImpl 对象而已。
接下来就到了 FragmentManagerImpl 的 beginTransaction
方法了。
//FragmentManagerImpl
public FragmentTransaction beginTransaction() {
return new BackStackRecord(this);
}
如我们所知,BackStackRecord 对象代表一系列对 Fragment 的操作,即事务,这里调用了 BackStackRecord 的构造方法并将 FragmentManagerImpl 自己作为参数传入。咱去看看构造方法做了啥。
//BackStackRecord
public BackStackRecord(FragmentManagerImpl manager) {
mManager = manager;
}
这样 BackStackRecord 也持有了 FragmentManagerImpl 对象的引用。
然后调用 BackStackRecord 的 replace
方法,即
//BackStackRecord
public FragmentTransaction replace(int containerViewId, Fragment fragment) {
return replace(containerViewId, fragment, null);
}
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;
}
先调用 replace
两个参数的重载方法,在该方法里调用了 replace
三个参数的重载方法,同时参数 tag = null,在这个方法里首先判断传进的用来装载 Fragment 的容器的 ID 是否有效,接着调用 doAddOpp
方法,它第三个参数传入了的是 OP_REPLACE 常量。这里注意它最后返回了 this,也就是我们的链式调用的下一个方法还是 BackStackRecord 对象的,结合下面我们脑海就能很形象地产生 Op 双向链表的图像。
//BackStackRecord
private void doAddOp(int containerViewId, Fragment fragment, String tag, int opcmd) {
fragment.mFragmentManager = mManager;
if (tag != null) {
if (fragment.mTag != null && !tag.equals(fragment.mTag)) {
throw new IllegalStateException("Can't change tag of fragment "
+ fragment + ": was " + fragment.mTag
+ " now " + tag);
}
fragment.mTag = tag;
}
if (containerViewId != 0) {
if (fragment.mFragmentId != 0 && fragment.mFragmentId != containerViewId) {
throw new IllegalStateException("Can't change container ID of fragment "
+ fragment + ": was " + fragment.mFragmentId
+ " now " + containerViewId);
}
fragment.mContainerId = fragment.mFragmentId = containerViewId;
}
Op op = new Op();
op.cmd = opcmd;
op.fragment = fragment;
addOp(op);
}
在本方法首先让参数 fragment 持有 FragmentManagerImpl 的引用,接着就是判断参数 tag 和 containerViewId 是否有效并赋值给 fragment 的成员变量。最后 Op 对象终于出场了(此处应有掌声)。实例化了一个 OP 对象后改变了它成员变量 cmd 的值,这里是 OP_REPLACE,接着让 Op 也持有 Fragment 对象的引用,最后就是将 Op 对象作为参数调用 addOp
方法。
//BackStackRecord
void addOp(Op op) {
if (mHead == null) {
mHead = mTail = op;
} else {
op.prev = mTail;
mTail.next = op;
mTail = op;
}
op.enterAnim = mEnterAnim;
op.exitAnim = mExitAnim;
op.popEnterAnim = mPopEnterAnim;
op.popExitAnim = mPopExitAnim;
mNumOp++;
}
前面我们说过 Op 表示的是双向链表的一个结点,这里得到了证实。这个方法只是双向链表的创建及添加结点逻辑。
可以提交事务了,即调用了 BackStackRecord 对象的 commit
方法。
//BackStackRecord
public int commit() {
return commitInternal(false);
}
int commitInternal(boolean allowStateLoss) {
if (mCommitted) {
throw new IllegalStateException("commit already called");
}
//...
mCommitted = true;
if (mAddToBackStack) {
mIndex = mManager.allocBackStackIndex(this);
} else {
mIndex = -1;
}
mManager.enqueueAction(this, allowStateLoss);
return mIndex;
}
最终调用了 commitInternal
方法,首先通过 mCommitted 判断是否已经提交过,因为默认为 false,所以这里不会抛出错误,接着最重要的逻辑就是调用了 mManager.enqueueAction(this, allowStateLoss)
,mManager 就是FragmentManagerImpl 对象,方法 enqueueAction
的第一个参数是 Runnable 类,但这里的 this 不是 BackStackRecord 对象么?
//BackStackRecord
final class BackStackRecord extends FragmentTransaction implements
FragmentManager.BackStackEntry, Runnable{
//...
}
看到了吧,BackStackRecord 实现了 Runnable,看来会有大事发生...
//FragmentManagerImpl
public void enqueueAction(Runnable action, boolean allowStateLoss) {
//...
synchronized (this) {
if (mDestroyed || mHost == null) {
throw new IllegalStateException("Activity has been destroyed");
}
if (mPendingActions == null) {
mPendingActions = new ArrayList();
}
mPendingActions.add(action);
if (mPendingActions.size() == 1) {
mHost.getHandler().removeCallbacks(mExecCommit);
mHost.getHandler().post(mExecCommit);
}
}
}
这里将 Runnable 装入了 mPendingActions 中,因为此时 mPendingActions.size() == 1 为 true,所以最终会将 mExecCommit 成员变量压入 mHost 持有的来自 Activity 的 Handler 对象里。那么我们现在可以推断出 mExecCommit 也是 Runnable 类型,同时它会在主线程被调用。我们看看 mExecCommmit 是何方神圣。
//FragmentManagerImpl
Runnable mExecCommit = new Runnable() {
@Override
public void run() {
execPendingActions();
}
};
原来它的作用就是为了切换到主线程然后执行它外部类即 FragmentManagerImpl 的 execPendingActions
方法而已。现在我假设这个 Runnable 对象会被马上被调用,实际可能需要排队...好,到 execPendingAcions
方法了。
//FragmentManagerImpl
public boolean execPendingActions() {
//...
while (true) {
int numActions;
synchronized (this) {
if (mPendingActions == null || mPendingActions.size() == 0) {
break;
}
numActions = mPendingActions.size();
if (mTmpActions == null || mTmpActions.length < numActions) {
mTmpActions = new Runnable[numActions];
}
mPendingActions.toArray(mTmpActions);
mPendingActions.clear();
mHost.getHandler().removeCallbacks(mExecCommit);
}
//...
for (int i=0; inull;
}
//...
}
//...
}
本方法我们只需关注首先将 mPendingActions 里的 Runnable 对象转移到 mTmpActions 数组里,并依次调用 mTmpActions 数组保存的 Runnable 的 run
方法。我们知道这里指的就是 BackStackRecord 中的 run
方法。去看看吧
//BackStackRecord
public void run() {
//...
Op op = mHead;
while (op != null) {
switch (op.cmd) {
//...
case OP_REPLACE: {
Fragment f = op.fragment;
int containerId = f.mContainerId;
//...
if (f != null) {
f.mNextAnim = op.enterAnim;
mManager.addFragment(f, false);
}
}
break;
//...
}
op = op.next;
}
mManager.moveToState(mManager.mCurState, mTransition,mTransitionStyle, true);
//...
}
这个方法其实很长的,但我们还是只要关注我们当前需要关注的逻辑就行啦。可以看到其实就是从头遍历 Op 双向链表,并通过判断 Op 对象里的 cmd 成员变量的值进行不同操作而已(其实这就是命令模式,可以看我的另一篇介绍设计模式的文章),这里我们只关注 OP_REPLACE。首先取出 Op 中保存的 Fragment 对象作为参数调用 FragmentManagerImpl 对象的 addFragment
方法,最后又通过 FragmentManagerImpl 对象的 moveToState
方法改变状态,还是一步一步来。
PS : 咳咳,下面我还有几句话要说。哈哈,我画了张思维导图,或许对照着看能更好地理解。
先看看 FragmentManagerImpl 的 addFragment
方法吧,注意这里第一个参数传入了 Fragment 对象,第二个参数传入 false。
//FragmentManagerImpl
public void addFragment(Fragment fragment, boolean moveToStateNow) {
if (mAdded == null) {
mAdded = new ArrayList();
}
//...
makeActive(fragment);
if (!fragment.mDetached) {
if (mAdded.contains(fragment)) {
throw new IllegalStateException("Fragment already added: " + fragment);
}
mAdded.add(fragment);
fragment.mAdded = true;
fragment.mRemoving = false;
//...
if (moveToStateNow) {
moveToState(fragment);
}
}
}
这里做了几件事:
makeActive
方法将 Fragment 对象添加进 mActive 列表中。然后到 FragmentManagerImpl 的 moveToState
方法了。我们只需关心它的第一个参数,即 mManager.mCurState,我们知道这里的 mCurState 此时已经被赋值成了 Fragment.CREATED。
//FragmentManagerImpl
void moveToState(int newState, int transit, int transitStyle, boolean always) {
//...
mCurState = newState;
if (mActive != null) {
//..
for (int i=0; iif (f != null) {
moveToState(f, newState, transit, transitStyle, false);
//...
}
}
//...
}
}
这里做了两件事
moveToState
方法。下面我们见识下这个方法吧(<- 大 BOSS)。方法很长,还是只关注我们需要那部分。//FragmentManagerImpl
void moveToState(Fragment f, int newState, int transit, int transitionStyle,
boolean keepActive) {
//...
if (f.mState < newState) {
//...
switch (f.mState) {
case Fragment.INITIALIZING:
//...
f.mHost = mHost;
f.mParentFragment = mParent;
f.mFragmentManager = mParent != null
? mParent.mChildFragmentManager : mHost.getFragmentManagerImpl();
f.mCalled = false;
f.onAttach(mHost.getContext());
//...
if (f.mParentFragment == null) {
mHost.onAttachFragment(f);
}
if (!f.mRetaining) {
f.performCreate(f.mSavedFragmentState);
}
f.mRetaining = false;
if (f.mFromLayout) {
//...
}
//...
}
f.mState = newState;
}
首先注意这里 f.mState = Fragment.INITIALIZING(默认)、newState = Fragment.CREATED、mParent = null、f.mRetaining = false(默认)、f.mFromLayout = false(默认)。那么这里干了几件事。
onAttach
!!onAttachFragment
,进去看看 //HostCallback
@Override
public void onAttachFragment(Fragment fragment) {
Activity.this.onAttachFragment(fragment);
}
也就说 Activity 可以通过这个方法知道被依附的 Fragment 的实例。performCreate
方法 //Fragment
void performCreate(Bundle savedInstanceState) {
//...
onCreate(savedInstanceState);
//...
}
这里终于调用了 Fragment 的生命周期 onCreate
方法!!在 Activity 的 performCreate
方法中调用了 onCreate
方法后,做了如上操作。主要做了两件最关注的事:
onAttach
、onCreate
并将 Fragment 的状态即 mState 改为了 Fragment.CREATED。那么就到了 Activity 的 performCreate
方法中最后调用的 performCreateCommon
方法了。
//Activity
final void performCreateCommon() {
//...
mFragments.dispatchActivityCreated();
//...
}
和上面一样,相同的逻辑,那么我们可以猜到下面其实也大同小异,那就全盘托出吧。
//ActivityController
public void dispatchActivityCreated() {
mHost.mFragmentManager.dispatchActivityCreated();
/*一样,调用了 FragmentManagerImpl 的 dispatchActivityCreated 方法*/
}
//FragmentManagerImpl
public void dispatchActivityCreated() {
//...
moveToState(Fragment.ACTIVITY_CREATED, false);
/*现在传入的状态常量是 Fragment.ACTIVITY_CREATED*/
}
//FragmentManagerImpl
void moveToState(int newState, boolean always) {
moveToState(newState, 0, 0, always);
}
//FragmentManagerImpl
void moveToState(int newState, int transit, int transitStyle, boolean always) {
//...
/*mCurState 这里又被改成了 Fragment.ACTIVITY_CREATED*/
mCurState = newState;
if (mActive != null) {
//...
for (int i=0; i/*一样,遍历 mActive,调用 moveToState,分别将 Fragment 作为参数传入 */
Fragment f = mActive.get(i);
if (f != null) {
moveToState(f, newState, transit, transitStyle, false);
//...
}
}
//...
}
}
//FragmentManagerImpl
//方法很长,不怕,我们在代码外分析
void moveToState(Fragment f, int newState, int transit, int transitionStyle,
boolean keepActive) {
//...
if (f.mState < newState) {
//...
switch (f.mState) {
//...
case Fragment.CREATED:
if (newState > Fragment.CREATED) {
//...
if (!f.mFromLayout) {
ViewGroup container = null;
if (f.mContainerId != 0) {
container = (ViewGroup)mContainer.onFindViewById(f.mContainerId);
if (container == null && !f.mRestored) {
//...
}
}
f.mContainer = container;
f.mView = f.performCreateView(f.getLayoutInflater(
f.mSavedFragmentState), container, f.mSavedFragmentState);
if (f.mView != null) {
//...
if (container != null) {
Animator anim = loadAnimator(f, transit, true,
transitionStyle);
if (anim != null) {
anim.setTarget(f.mView);
setHWLayerAnimListenerIfAlpha(f.mView, anim);
anim.start();
}
container.addView(f.mView);
}
//...
f.onViewCreated(f.mView, f.mSavedFragmentState);
}
}
f.performActivityCreated(f.mSavedFragmentState);
//...
}
//...
}
}
f.mState = newState;
}
嗯,和我们猜的一样,最后还是调用了这个 moveToState
方法,因为现在我们的参数 newState = Fragment.ACTIVITY_CREATED、f.newState = Fragment.CREATED、f.mFromLayout = false(默认),那从代码一步一步来看这里做了几件事。
f.performCreateView
获取到 View 并赋给 f.mView,那么 performCreateView
又是何方神圣? //Fragment
View performCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//...
return onCreateView(inflater, container, savedInstanceState);
}
哈哈,调用了我们 Fragment 的生命周期方法 onCreateView
方法!!f.performActivityCreated
//Fragment
void performActivityCreated(Bundle savedInstanceState) {
//...
onActivityCreated(savedInstanceState);
//...
}
onActivityCreated
终于出现啦,就这样,我们需要分析的生命周期方法都出来啦。通过 Activity 的 performCreateCommon
方法后,做了这么两件事:
onCreateView
被调用后将返回的 View 添加到指定容器中,随后就是另一个生命周期方法 onActivityCreated
方法,最后一样还会将 f.mState 改成最新的状态即 Fragment.ACTIVITY_CREATED。InStrumentation 对象通过 callActivityOnCreate
方法触发了 Activity 的 performCreate
后,Activity 也负责任地分别触发了 Fragment 的生命周期方法 onAttach
、onCreate
、onCreateView
、onActivityCreated
。经过了上面的分析,现在看这张图是不是不会觉得难记了?
其它生命周期方法逻辑没多大区别,每当 Activity 的生命周期方法被触发后它也会触发依附在它身上的 Fragment 的生命周期方法,感兴趣的朋友可以亲自去看看源码。
为了方便理解,我画了张思维导图,图片在此(超级大...)。