说起Activity大家都不陌生,它主要是跟用户去打交道,其实,它并不仅仅将视图显示给用户,它的背后隐藏的很大的知识点,今天就来讲讲它的一些背后隐藏的故事
生命周期分析
Activity的生命周期主要是7个,onCreate,onRestart,onStart,onResume,onPause,onStop,onDestroy
1,onCreate:当Activity被创建时首先调用的方法,onContentView会去加载视图并且显示出来,我们也可以在这个方法里实例化一些对象
2,onRestart:当Activity的视图绘制完成后,从不可见到重新可见时该方法会被调用,例如,如果当前的Activity被创建了,用户按了home键返回了页面或者说被其他的Activity覆盖了,然后再返回该Activity时,该方法也会被调用,如果是正常启动,该方法不会被调用
3,onStart:当Activity已经创建完成会调用该方法,注意的是,这里仅仅是创建完成,并不代表显示给用户了,也就是说,Activity已经创建完成了,但是我们还没有看得见
4,onResume:Activity创建完成并且显示给用户了,这里跟onStart的差别是,虽然两者都已经创建完,但是onStart还没有显示出来,而onResume则显示出来了,可以跟用户交互了
5,onPause:当Activity不可见时,该方法会被调用,表示Activity即将不可见,相当于准备工作
6,onStop:当onPause执行完之后,该方法被调用,真正的不可见,但注意的是,不可见不代表Activity销毁了,例如我们跳转到另外一个Activity的话,那当前的Activity执行了onStop,但是并没有被销毁,还会存储在栈中
7,onDestroy:当Activity真正被销毁后会回调该方法,什么是销毁,例如用户退出了当前的应用,或者当前Activity调用了finish()方法,都会销毁当前Activity
来张生命周期的图,生命周期图网上太多了,就不注明出处了
总的一点概述,Activity生命周期的变化是:
1,第一次创建时:onCreate ——> onStart ——> onResume
2,当Activity从可见到不可见时:onPause ——> onStop,如果ActivityB使用的是透明背景,那么当前Activity的onStop方法不会被执行
3,当Activity从不可见到可见时:onRestart ——> onStart ——> onResume
4,当Activity被销毁后:onPause ———> onStop ——> onDestroy
5,如果多个Activity交互:
ActivityA:onCreate ——> onStart ——> onResume——> onPause
ActivityB:onCreate ——> onStart ——> onResume
ActivityA:onStop
6,如果ActivityB点击了Back键后:
ActivityB:onPause
ActivityA:onRestart ——> onStart ——> onResume
ActivityB:onStop ——> onDestroy
注意的是:
1,onCreate和onDestroy只会被调用一次
2,只有当onResume调用完之后,才会显示出界面,onStop调用完之后,才会消失界面,onStart和onPause相当于显示界面前和消失界面前的准备工作
3,onRestart只有在重新可见时才会被调用,正常启动是不会被调用
4,不要在onStart和onPause方法中进行耗时操作,因为只有在这两个方法执行完之后,才会调用onResume和onStop方法,耗时操作会延迟显示和消失的时间,并且对于性能来说也不好,如果需要进行耗时操作,尽量在onResume和onStop中操作
5,如果第二个Activity是出于透明状态时,当前的Activity不会调用onStop方法
6,如果多个Activity交互,首先当前Activity会调用onPause,需等第二个Activity创建完并且显示出来之后,第一个Activity才会执行onStop或者销毁
现在提出2个问题:
1,当多个Activity交互时,为什么当前的Activity需要先执行onPause方法?
2,为什么要先执行第二个Activity的onCreate,onStart,onResume方法,再执行第一个Activity的onStop方法呢
Google的开发人员这样的设计是有道理的,我们就Activity的生命周期分析下,来看下原因:
问题1:
假设当前是一款视频APP,用户正在看着视频(ActivityA),这时候有电话打进来了,系统会调用电话的ActivityB,这时,如果不执行onPause方法,那么ActivityA的声音一直存在,而ActivityB的声音也在,这就很尴尬了
问题2:
我们知道Activity需要执行了onStop方法才会消失页面,当启动ActivityB时,ActivityA执行了onStop方法,那么ActivityA页面就消失了,而这时ActivityB还没有显示,这也很尴尬,所以说,ActiivtyA先出于一种暂停状态,预防ActivityB出现的各种情况,当ActivityB完成了之后,Activity才会真正的消失
异常时期的生命周期分析
当我们Activity发生异常时,我们可想到,Activity被创建了,然后发生了异常,然后消失不可见,最后销毁,所以我们不难想到Activity发生了异常,则它的生命周期:
1,创建的时候发生:onCreate ——>onPause ———> onStop ——> onDestroy
2,onStart时发生:onCreate ——>onStart ——>onPause ———> onStop ——> onDestroy
3,onResume时发生:onCreate ——>onStart ——>onResume——>onPause ———> onStop ——> onDestroy
不难发现,异常发生时都会调用onPause ———> onStop ——> onDestroy,也就是完整的销毁流程
如果异常发生了,系统会调用onSaveInstanceState方法来保存当前的状态信息,这个方法会再onStop之前调用,跟onPause没有关系,可能在onPause之前,也可能之后,但是注意的是,这个方法只会在发生异常时被调用,正常情况下不会被调用,onSaveInstanceState是以Bundle对象来保存数据,保存了数据之后,会传递给onCreate,我们知道,onCreate方法中有个Bundle类型参数是savedInstanceState,这也就是说,异常出现了,我们可以通过savedInstanceState判断Activity是否被重建了,如果重建了,则可以在onCreate中获取到保存的数据
横竖屏切换的生命周期
很多时候我们的应用都是竖屏操作,但也有很多时候需要切换到横屏,那么它们的生命周期会是怎样的变化呢?
首先我们知道了第一次创建时候Activity的生命周期,我们不妨想象下横竖屏有什么不一样的地方,首先当我们的Activity创建完成之后,界面已经显示出来了,也就是说明,view也就是确定了,然而切换横屏的时候,我们知道view的显示和竖屏的时候不一样,我们回想下,view的加载是在onCreate的setContentView方法中引入的,而onCreate方法只能被调用一次,所以我们不难推断出,横竖屏切换之后,view重新被创建了,也就是说onCreate会被执行,就是说切换之后新的Activity会被重新创建一次,那么旧的Activity呢?如果说旧的Activity没有隐藏,那么我们就会看到两个Activity交叉显示,然而我们并没有,而Activity是执行了onStop方法才会隐藏,所以我们知道了旧的Activity会执行onStop方法,那么会不会销毁呢?如果说没有被销毁,那么无限的横竖屏切换,就会导致Activity越来越多,特别是Activity中执行了耗时的操作时,后果可想而知,所以,我们就得出一个结论,当横竖屏切换的时候,旧的Activity会执行一次完整的生命周期,而新的Activity会被重新创建
横竖屏切换时的生命周期:
1,ActivityA:
onCreate ——> onStart ——> onResume ——> onPause ——> onStop ——> onDestroy
2,ActivityB:
onCreate ——> onStart ——> onResume
如果我们需要在切换时保存信息状态,方法跟异常出现时一样,在onSaveInstanceState中保存信息,然后再onCreate中取出
好了,这篇文章就先写到这里,下篇讲讲Activity的启动模式