我们先套用安卓官网给的一张Activity对应Fragment的生命周期图:
上面的图说明了Fragment跟Activity之间的关系。这张图的前提条件是什么呢?在什么情况下成立呢?对于我们新手来说,需要说明一下这个问题。
1、 Fragment的启动(Activity 在Paused之前状态)
我们可以分两种情况来说明:
第一种:在Activity的启动过程中,我们在activity的生命周期中添加了的Fragment会随着上图走,并且会追赶上Activity的生命周期,假如我们在Activity的onStart方法中添加了Fragment,那么我们的Fragment会自动调用onStart之前的生命周期方法。
第二种:在Activity启动完成以后其实还是跟上面的理解一样,我们当前Activity
执行过onResume方法了,所以我们在使用Fragment的时候,fragment会自动的点用onPause之前的生命周期的方法。
2、Fragment的销毁 (Activity 的Paused之后的状态)
销毁还的分两种情况:
第一种:Activity自己销毁的过程中所有的Fragment会跟随Activity调用,我做了一个有趣的实验。在Activity执行onPause()方法时我加入了这么一段代码
@Override
protected void onPause() {
super.onPause();
getSupportFragmentManager().beginTransaction().addToBackStack(null).replace(R.id.container_id, new FragmentLifecycle2()).commit();
}
你们猜效果会怎样?当我按下锁屏键的时候,Activity会执行onResume,onStop方法
06-25 14:47:40.631 30961-30961/com.lj.test I/com.lj.test.FragmentLifecycle2: onAttach
onCreate
06-25 14:47:40.632 30961-30961/com.lj.test I/com.lj.test.FragmentLifecycle: onStop
06-25 14:47:40.633 30961-30961/com.lj.test I/com.lj.test.FragmentLifecycle: onDestroyView
06-25 14:47:40.636 30961-30961/com.lj.test I/com.lj.test.FragmentLifecycle2: onCreateView
06-25 14:47:40.659 30961-30961/com.lj.test I/com.lj.test.FragmentLifecycle2: onViewCreated
onActivityCreated
onStart
06-25 14:47:40.664 30961-30961/com.lj.test I/com.lj.test.FragmentLifecycle: onSaveInstanceState
06-25 14:47:40.665 30961-30961/com.lj.test I/com.lj.test.FragmentLifecycle2: onSaveInstanceState
06-25 14:47:40.677 30961-30961/com.lj.test I/com.lj.test.FragmentLifecycle2: onStop
通过上面的log我们知道了,新启动的FragmentLifecycle2先会自动调用OnResume之前的生命周期方法跟Actvity同步,然后当Activity调用onStop的时候,FragmentLifecycle2也会跟随Actiivity调用onStop方法。
我们如果在Activity的onStop和之后的生命周期方法中调用上面的代码会crash。
小结:
通过上面的实验和研究我们发现,处于显示中的fragment的生命周期是紧紧追随它的宿主Activity的。
上面讨论的都是在讨论当Fragment处于栈顶时的生命周期变化,下面我们要讨论的是,当我们替换Fragment时此时Activity的生命周期为发生变化的情况下的Fragment的生命周期如何呢?
我们还是分情况研究:
情况一:当我们使用replace替换之前处于显示中的fragment时,被替换的fragment和新的fragment又是如何的呢?
答:
我们还是需要分两种情况:一种是加入回退栈的情况,一种是不加入。
加入回退栈的情况下的研究:
操作一:我们先显示FragmentLifecycle,然后将其替换为FragmentLifecycle2后打印出来的log
06-25 15:11:33.889 32527-32527/com.lj.test I/com.lj.test.FragmentLifecycle2: onAttach
onCreate
06-25 15:11:33.890 32527-32527/com.lj.test I/com.lj.test.FragmentLifecycle: onPause
06-25 15:11:33.891 32527-32527/com.lj.test I/com.lj.test.FragmentLifecycle: onStop
06-25 15:11:33.892 32527-32527/com.lj.test I/com.lj.test.FragmentLifecycle: onDestroyView
06-25 15:11:33.893 32527-32527/com.lj.test I/com.lj.test.FragmentLifecycle2: onCreateView
06-25 15:11:33.913 32527-32527/com.lj.test I/com.lj.test.FragmentLifecycle2: onViewCreated
06-25 15:11:33.914 32527-32527/com.lj.test I/com.lj.test.FragmentLifecycle2: onActivityCreated
onStart
onResume
先执行FragmentLifecycle2中的onAttach、onCreate,
然后执行FragmentLifecycle的onPause、onStop、onDestroyView,
紧接着执行FragmentLifecycle2中的onCreateView、onViewCreated、onActivityCreated、onStart、onResume
通过上面的生命周期的观察很明显是:先创建FragmentLifecycle2->销毁FragmentLifecycle中的视图->创建FragmentLifecycle2视图并添加到Acitivity的View视图树中。
小结:大家有没有发现一个问题,FragmentLifecycle并没有调用onDestory和OnDetach方法,其实因为FragmentLifecycle已经被加入回退栈中了,所以没有被完全销毁,只是销毁了视图,但是整个Fragment还在。
操作二:当我按下返回键会出现什么现象呢?
06-25 15:36:08.551 32527-32527/com.lj.test I/com.lj.test.FragmentLifecycle2: onPause
06-25 15:36:08.552 32527-32527/com.lj.test I/com.lj.test.FragmentLifecycle2: onStop
onDestroyView
06-25 15:36:08.553 32527-32527/com.lj.test I/com.lj.test.FragmentLifecycle2: onDestroy
onDetach
06-25 15:36:08.554 32527-32527/com.lj.test I/com.lj.test.FragmentLifecycle: onCreateView
06-25 15:36:08.571 32527-32527/com.lj.test I/com.lj.test.FragmentLifecycle: onViewCreated
onActivityCreated
onStart
onResume
先执行FragmentLifecycle2的:
onPause、onStop、onDestroyView、onDestroy、 onDetach
再执行FragmentLifecycle 的:
onCreateView、onViewCreated、onActivityCreated、onStart、onResume
通过上面的生命周期的观察:先是完成将FragmentLifecycle2的onPause之后的所有生周期走完意味着它的死亡->重新创建FragmentLifecycle的视图并追平Actvity当前的生命状态。
总结:当我们按下返回键的时候是将正在显示的FragmentLifecycle2直接完全死亡,紧接着我们会加载回退栈中的栈顶的Fragment,你们有没有发现FragmentLifecycle并没有走onAttach和onCreate方法,以为我们将FragmentLifecycle中后,并没有使其死亡,生命周期只是走到了onDestroyView销毁了视图,后面的onDestory和OnDetach方法并没有执行,着也对应了我们上面的实验结果
操作二:当我继续按返回键还会发生什么呢?
06-25 15:49:10.106 32527-32527/com.lj.test I/com.lj.test.FragmentLifecycle: onPause
06-25 15:49:10.245 32527-32527/com.lj.test I/com.lj.test.FragmentLifecycle: onStop
06-25 15:49:10.248 32527-32527/com.lj.test I/com.lj.test.FragmentLifecycle: onDestroyView
06-25 15:49:10.250 32527-32527/com.lj.test I/com.lj.test.FragmentLifecycle: onDestroy
onDetach
FragmentLifecycle 走完了自己的生命周期,即死亡了。
我们能得出什么结论呢?
总结:整个过程是这样的,当我们替换正在显示的FragmentLifecycle并把它加入回退栈时,它只是销毁了视图,当按下返回键时系统就会从回退栈中取出栈顶元素,并且重新创建视图并同步到actvity当前的状态中,当我再次按下返回键时,我们的FragmentLifecycle由于没有加入到回退栈中,所以会直接走向死亡。同时此时的回退栈中没有fragment了,所以就会推出actvity了
上面的研究时加入到回退栈的研究,那么我们不加入回退栈会是怎样呢?
其实我们通过上面的研究也差不多能知道了,就是别替换的fragment会直接死亡。我们通过打印log进行一下证实吧。
操作一:当我在fragment替换操作时把.addToBackStack(null)代码去掉后,当我用FragmentLifecycle2替换FragmentLifecycle时,log如下:
06-25 15:59:37.731 2007-2007/com.lj.test I/com.lj.test.FragmentLifecycle2: onAttach
onCreate
06-25 15:59:37.733 2007-2007/com.lj.test I/com.lj.test.FragmentLifecycle: onPause
06-25 15:59:37.734 2007-2007/com.lj.test I/com.lj.test.FragmentLifecycle: onStop
06-25 15:59:37.736 2007-2007/com.lj.test I/com.lj.test.FragmentLifecycle: onDestroyView
06-25 15:59:37.738 2007-2007/com.lj.test I/com.lj.test.FragmentLifecycle: onDestroy
onDetach
06-25 15:59:37.738 2007-2007/com.lj.test I/com.lj.test.FragmentLifecycle2: onCreateView
06-25 15:59:37.777 2007-2007/com.lj.test I/com.lj.test.FragmentLifecycle2: onViewCreated
onActivityCreated
06-25 15:59:37.778 2007-2007/com.lj.test I/com.lj.test.FragmentLifecycle2: onStart
06-25 15:59:37.780 2007-2007/com.lj.test I/com.lj.test.FragmentLifecycle2: onResume
通过查看log我发现跟上面实验结果不同的地方是:FragmentLifecycle调用了onDestroy
onDetach
这也就是说FragmentLifecycle直接就死亡了
操作二:我们按返回键
06-25 16:05:38.989 2007-2007/com.lj.test I/com.lj.test.FragmentLifecycle2: onPause
06-25 16:05:39.139 2007-2007/com.lj.test I/com.lj.test.FragmentLifecycle2: onStop
onDestroyView
06-25 16:05:39.140 2007-2007/com.lj.test I/com.lj.test.FragmentLifecycle2: onDestroy
onDetach
这次调用了FragmentLifecycle2的剩于生命周期,同时activiy直接退出了。
Fragment的生命周期我们又通过做实验的方式详细的分析了一下,希望对大家有所帮助,同时错误的地方还望大家指正。