再学一遍Activity和Fragment生命周期

虽说我们开发用过很多次Fragment和Activity但是我到现在对有些生命周期还是懵逼中,所以这篇博客的目的就是自己写一个测试项目测试下到底生命周期是如何发挥作用的呢?

首先我们看看Activity自己的生命周期

正常我们点击返回键的时候生命周期

2019-06-19 23:27:14.087 4388-4388/com.justtest I/liangchaojie: onCreate: 0
2019-06-19 23:27:14.090 4388-4388/com.justtest I/liangchaojie: onStart: 0
2019-06-19 23:27:14.090 4388-4388/com.justtest I/liangchaojie: onPostCreate: 0
2019-06-19 23:27:14.090 4388-4388/com.justtest I/liangchaojie: onResume: 0
2019-06-19 23:27:14.090 4388-4388/com.justtest I/liangchaojie: onPostResume: 0
2019-06-19 23:27:17.281 4388-4388/com.justtest I/liangchaojie: onPause: 0
2019-06-19 23:27:17.887 4388-4388/com.justtest I/liangchaojie: onStop: 0
2019-06-19 23:27:17.888 4388-4388/com.justtest I/liangchaojie: onDestroy: 0

点击Home键或者底部进程栈键的的时候

2019-06-19 23:29:11.475 4511-4511/com.justtest I/liangchaojie: onPause: 0
2019-06-19 23:29:11.489 4511-4511/com.justtest I/liangchaojie: onStop: 0
2019-06-19 23:29:11.489 4511-4511/com.justtest I/liangchaojie: haha onSaveInstanceState: 

切换横竖屏的时候

2019-06-19 23:31:06.684 4511-4511/com.justtest I/liangchaojie: onPause: 0
2019-06-19 23:31:06.694 4511-4511/com.justtest I/liangchaojie: onStop: 0
2019-06-19 23:31:06.694 4511-4511/com.justtest I/liangchaojie: haha onSaveInstanceState: 
2019-06-19 23:31:06.695 4511-4511/com.justtest I/liangchaojie: onDestroy: 0
2019-06-19 23:31:06.759 4511-4511/com.justtest I/liangchaojie: onCreate: 0
2019-06-19 23:31:06.763 4511-4511/com.justtest I/liangchaojie: onStart: 0
2019-06-19 23:31:06.764 4511-4511/com.justtest I/liangchaojie: haha onRestoreInstanceState: 
2019-06-19 23:31:06.764 4511-4511/com.justtest I/liangchaojie: onPostCreate: 0
2019-06-19 23:31:06.764 4511-4511/com.justtest I/liangchaojie: onResume: 0
2019-06-19 23:31:06.764 4511-4511/com.justtest I/liangchaojie: onPostResume: 0

当从该Activity跳转到下一个Activity但是没有finish当前页面的时候

2019-06-19 23:32:56.866 4765-4765/com.justtest I/liangchaojie: onCreate: 0
2019-06-19 23:32:56.878 4765-4765/com.justtest I/liangchaojie: onStart: 0
2019-06-19 23:32:56.879 4765-4765/com.justtest I/liangchaojie: onPostCreate: 0
2019-06-19 23:32:56.882 4765-4765/com.justtest I/liangchaojie: onResume: 0
2019-06-19 23:32:56.883 4765-4765/com.justtest I/liangchaojie: onPostResume: 0
2019-06-19 23:32:56.926 4765-4765/com.justtest I/liangchaojie: onPause: 0
2019-06-19 23:32:57.192 4765-4765/com.justtest I/liangchaojie: onStop: 0
2019-06-19 23:32:57.192 4765-4765/com.justtest I/liangchaojie: haha onSaveInstanceState: 

综上所述,onSaveInstanceState是在Activity可能被异常杀死的情况下调用的,如果有对Activity的保存可以在这里进行,当然如果是横竖屏切换是可以恢复的但是进程的杀死就只能存取sp里面然后再取出来了

接下来我们看看Fragment的生命周期

private void initView() {
        ParamFragment paramFragment = ParamFragment.newInstance(2);
        getSupportFragmentManager().beginTransaction().add(R.id.fragment, paramFragment).commit();
    }

1 正常启动

2019-05-25 20:10:30.954 13382-13382/? I/TAG: LCJ Activity onCreate: 
2019-05-25 20:10:30.960 13382-13382/? I/TAG: LCJ Fragment onAttach: 
2019-05-25 20:10:30.960 13382-13382/? I/TAG: LCJ Fragment onCreate: 
2019-05-25 20:10:30.962 13382-13382/? I/TAG: LCJ Fragment onCreateView: 
2019-05-25 20:10:30.969 13382-13382/? I/TAG: LCJ Fragment onViewCreated: 
2019-05-25 20:10:30.970 13382-13382/? I/TAG: LCJ Fragment onActivityCreated: 
2019-05-25 20:10:30.970 13382-13382/? I/TAG: LCJ Fragment onStart: 
2019-05-25 20:10:30.970 13382-13382/? I/TAG: LCJ Activity onStart: 
2019-05-25 20:10:30.972 13382-13382/? I/TAG: LCJ Activity onPostCreate: 
2019-05-25 20:10:30.980 13382-13382/? I/TAG: LCJ Activity onResume: 
2019-05-25 20:10:30.981 13382-13382/? I/TAG: LCJ Fragment onResume: 

这里需要注意的是:

1 Fragment onStart先于Activity onStart执行
2 Activity onPostCreate方法是在onStart方法之后,onResume方法之前执行
3 Activity onResume先于Fragment onResume执行

为什么会出现这样的结果呢?我的理解是这样,舞台就是一个Actiivty,Fragment是舞台上的一个节目道具,我们首先要把道具什么的摆好才可以拉开幕布展示给观众,所以要Fragment先onStart——准备好节目道具,再Activity onStart——拉开幕布让观众们看到,观众先盯住的是舞台——Activity onResume,聚精会神才是舞台上的一个节目道具——Fragment onResume

2 正常退出

(正常启动的日志在上面,这里就不贴上了)
2019-05-25 20:20:26.615 14135-14135/? I/TAG: LCJ Fragment onPause: 
2019-05-25 20:20:26.615 14135-14135/? I/TAG: LCJ Activity onPause: 
2019-05-25 20:20:27.132 14135-14135/? I/TAG: LCJ Fragment onStop: 
2019-05-25 20:20:27.133 14135-14135/? I/TAG: LCJ Activity onStop: 
2019-05-25 20:20:27.134 14135-14135/? I/TAG: LCJ Fragment onDestroyView: 
2019-05-25 20:20:27.138 14135-14135/? I/TAG: LCJ Fragment onDestroy: 
2019-05-25 20:20:27.138 14135-14135/? I/TAG: LCJ Fragment onDetach: 
2019-05-25 20:20:27.139 14135-14135/? I/TAG: LCJ Activity onDestroy: 

节目暂停了,舞台凝固了,节目结束,舞台拉上幕布,节目开始慌忙的把道具搬下去,把位置让出来
onDetach是最后的解绑,和宿主activity失去了关联就要被回收了

2 屏幕旋转导致的销毁和重建

(正常启动的日志在上面,这里就不贴上了)
2019-05-25 20:27:25.729 15437-15437/com.justtest I/TAG: LCJ Fragment onPause: 
2019-05-25 20:27:25.729 15437-15437/com.justtest I/TAG: LCJ Activity onPause: 
2019-05-25 20:27:25.736 15437-15437/com.justtest I/TAG: LCJ Fragment onStop: 
2019-05-25 20:27:25.736 15437-15437/com.justtest I/TAG: LCJ Activity onStop: 
2019-05-25 20:27:25.737 15437-15437/com.justtest I/TAG: LCJ Fragment onDestroyView: 
2019-05-25 20:27:25.741 15437-15437/com.justtest I/TAG: LCJ Fragment onDestroy: 
2019-05-25 20:27:25.741 15437-15437/com.justtest I/TAG: LCJ Fragment onDetach: 
2019-05-25 20:27:25.745 15437-15437/com.justtest I/TAG: LCJ Activity onDestroy: 
2019-05-25 20:27:25.827 15437-15437/com.justtest I/TAG: LCJ Fragment onAttach: 
2019-05-25 20:27:25.827 15437-15437/com.justtest I/TAG: LCJ Fragment onCreate: 
2019-05-25 20:27:25.918 15437-15437/com.justtest I/TAG: LCJ Activity onCreate: 
2019-05-25 20:27:25.921 15437-15437/com.justtest I/TAG: LCJ Fragment onCreateView: 
2019-05-25 20:27:25.928 15437-15437/com.justtest I/TAG: LCJ Fragment onViewCreated: 
2019-05-25 20:27:25.928 15437-15437/com.justtest I/TAG: LCJ Fragment onActivityCreated: 
2019-05-25 20:27:25.928 15437-15437/com.justtest I/TAG: LCJ Fragment onAttach: 
2019-05-25 20:27:25.929 15437-15437/com.justtest I/TAG: LCJ Fragment onCreate: 
2019-05-25 20:27:25.930 15437-15437/com.justtest I/TAG: LCJ Fragment onCreateView: 
2019-05-25 20:27:25.933 15437-15437/com.justtest I/TAG: LCJ Fragment onViewCreated: 
2019-05-25 20:27:25.934 15437-15437/com.justtest I/TAG: LCJ Fragment onActivityCreated: 
2019-05-25 20:27:25.934 15437-15437/com.justtest I/TAG: LCJ Fragment onStart: 
2019-05-25 20:27:25.934 15437-15437/com.justtest I/TAG: LCJ Fragment onStart: 
2019-05-25 20:27:25.935 15437-15437/com.justtest I/TAG: LCJ Activity onStart: 
2019-05-25 20:27:25.937 15437-15437/com.justtest I/TAG: LCJ Activity onPostCreate: 
2019-05-25 20:27:25.942 15437-15437/com.justtest I/TAG: LCJ Activity onResume: 
2019-05-25 20:27:25.943 15437-15437/com.justtest I/TAG: LCJ Fragment onResume: 
2019-05-25 20:27:25.944 15437-15437/com.justtest I/TAG: LCJ Fragment onResume: 

这里为什么会出现两次调用Fragment onAttach和Fragment onCreate我在之前的博客提到过Activity的销毁恢复的问题Activity和Fragment通信遇到的坑——为什么要用setArguments方法?,这篇博客讲了为什么会多出现一个Fragment

从日志里我突然明白了,Activity中使用Fragment我其实一直都没有写对, onCreate代码是有问题:

日常都是这么写的:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        iniFragment();//在这里添加Fragment
        Log.i("TAG", "LCJ Activity onCreate: ");
    }

这么写没啥大毛病,就是多了内存消耗,因为系统已经帮你恢复了一个fragment,但是你在Activity重建的过程中又新建了一个,完全辜负了系统的一片好心,浪费了资源了

优化版本:

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        if(savedInstanceState==null){//如果系统没有保存状态就自己新建,否则使用系统创建的,不去重复创建了
            initFragment();
        }
        Log.i("TAG", "LCJ Activity onCreate: ");
    }

Activity Fragment生命周期到这里还没完,如果使用了ViewPager的话,情况就变得复杂了

3 ViewPager

第一个碎片是ParamFragment,第二个是Testragment,第三个是AppllyFragment

2019-05-25 21:19:27.771 21837-21837/? I/TAG: LCJ Activity onCreate: 
2019-05-25 21:19:27.852 21837-21837/? I/TAG: LCJ ParamFragment isVisibleToUser: false
2019-05-25 21:19:27.853 21837-21837/? I/TAG: LCJ Testragment isVisibleToUser: false
2019-05-25 21:19:27.853 21837-21837/? I/TAG: LCJ ParamFragment isVisibleToUser: true
2019-05-25 21:19:27.855 21837-21837/? I/TAG: LCJ ParamFragment onAttach: 
2019-05-25 21:19:27.855 21837-21837/? I/TAG: LCJ ParamFragment onCreate: 
2019-05-25 21:19:27.855 21837-21837/? I/TAG: LCJ Testragment onAttach: 
2019-05-25 21:19:27.855 21837-21837/? I/TAG: LCJ Testragment onCreate: 
2019-05-25 21:19:27.856 21837-21837/? I/TAG: LCJ ParamFragment onCreateView: 
2019-05-25 21:19:27.864 21837-21837/? I/TAG: LCJ ParamFragment onViewCreated: 
2019-05-25 21:19:27.865 21837-21837/? I/TAG: LCJ ParamFragment onActivityCreated: 
2019-05-25 21:19:27.865 21837-21837/? I/TAG: LCJ ParamFragment onStart: 
2019-05-25 21:19:27.865 21837-21837/? I/TAG: LCJ ParamFragment onResume: 
2019-05-25 21:19:27.866 21837-21837/? I/TAG: LCJ Testragment onCreateView: 
2019-05-25 21:19:27.871 21837-21837/? I/TAG: LCJ Testragment onViewCreated: 
2019-05-25 21:19:27.872 21837-21837/? I/TAG: LCJ Testragment onActivityCreated: 
2019-05-25 21:19:27.872 21837-21837/? I/TAG: LCJ Testragment onStart: 
2019-05-25 21:19:27.872 21837-21837/? I/TAG: LCJ Testragment onResume: 

如果向右滑动到下一个碎片的话,当前碎片的下一个碎片会创建

2019-05-25 21:21:26.163 21837-21837/com.justtest I/TAG: LCJ AppllyFragment isVisibleToUser: false
2019-05-25 21:21:26.164 21837-21837/com.justtest I/TAG: LCJ ParamFragment isVisibleToUser: false
2019-05-25 21:21:26.164 21837-21837/com.justtest I/TAG: LCJ Testragment isVisibleToUser: true
2019-05-25 21:21:26.165 21837-21837/com.justtest I/TAG: LCJ AppllyFragment onAttach: 
2019-05-25 21:21:26.165 21837-21837/com.justtest I/TAG: LCJ AppllyFragment onCreate: 
2019-05-25 21:21:26.169 21837-21837/com.justtest I/TAG: LCJ AppllyFragment onCreateView: 
2019-05-25 21:21:26.179 21837-21837/com.justtest I/TAG: LCJ AppllyFragment onViewCreated: 
2019-05-25 21:21:26.180 21837-21837/com.justtest I/TAG: LCJ AppllyFragment onActivityCreated: 
2019-05-25 21:21:26.180 21837-21837/com.justtest I/TAG: LCJ AppllyFragment onStart: 
2019-05-25 21:21:26.181 21837-21837/com.justtest I/TAG: LCJ AppllyFragment onResume: 

viewpager由于其预加载的特性,每次都会多加载一个,只是我们需要注意的是:

即使调用了Fragment的onStart,onResume方法,Fragment也不是可见的,用户在切换fragment的时候是不会走onPause,onStop方法的
isVisibleToUser 执行顺序是比onAttach提前的,所以在setVisibile方法里面是获取不到context的

退出activity:

2019-05-25 21:32:04.019 22452-22452/com.justtest I/TAG: LCJ ParamFragment onPause: 
2019-05-25 21:32:04.020 22452-22452/com.justtest I/TAG: LCJ Testragment onPause: 
2019-05-25 21:32:04.020 22452-22452/com.justtest I/TAG: LCJ AppllyFragment onPause: 
2019-05-25 21:32:04.540 22452-22452/com.justtest I/TAG: LCJ ParamFragment onStop: 
2019-05-25 21:32:04.541 22452-22452/com.justtest I/TAG: LCJ Testragment onStop: 
2019-05-25 21:32:04.541 22452-22452/com.justtest I/TAG: LCJ AppllyFragment onStop: 
2019-05-25 21:32:04.543 22452-22452/com.justtest I/TAG: LCJ ParamFragment onDestroyView: 
2019-05-25 21:32:04.547 22452-22452/com.justtest I/TAG: LCJ ParamFragment onDestroy: 
2019-05-25 21:32:04.547 22452-22452/com.justtest I/TAG: LCJ ParamFragment onDetach: 
2019-05-25 21:32:04.548 22452-22452/com.justtest I/TAG: LCJ Testragment onDestroyView: 
2019-05-25 21:32:04.549 22452-22452/com.justtest I/TAG: LCJ Testragment onDestroy: 
2019-05-25 21:32:04.549 22452-22452/com.justtest I/TAG: LCJ Testragment onDetach: 
2019-05-25 21:32:04.550 22452-22452/com.justtest I/TAG: LCJ AppllyFragment onDestroyView: 
2019-05-25 21:32:04.551 22452-22452/com.justtest I/TAG: LCJ AppllyFragment onDestroy: 
2019-05-25 21:32:04.551 22452-22452/com.justtest I/TAG: LCJ AppllyFragment onDetach: 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值