本人水平有限,文章中如果出现什么不正确或者模糊的地方,还请各位小伙伴留下评论,多多指教 : )
<准备工作>
【活动是什么?】
它是一种可以包含用户界面的组件,主要负责和用户进行交互。
【为什么要掌握生命周期】
1、写出更加流畅连贯的程序
2、合理管理应用资源反面——资源内存的分配与的释放
3、有更好的用户体验
【活动的基本概念】
1、活动是通过任务(Task)或者说栈来管理的,一个任务就是一组存放在栈里的活动的集合。
2、栈是一种后进先出的数据结构,上一条,说的那个栈,也被称为返回栈
3、每当我们启动了一个新的活动,它会在返回栈中入栈,并且处于栈顶的位置
4、每当我们按下back或者finish()销毁一个活动时,处于栈顶的活动会出栈。这时前一个入栈的活动就会重新处于栈顶的位置
5、系统总是会显示处于栈顶的活动给用户
举个生动一点的栗子。
这个小玩意叫压式零钱筒,筒套可以看做是栈,里面的钱就相当于活动,其工作方式和栈在逻辑上是一样的。先放进去的硬币后出来,处于表面上的第一个硬币就是好比是处于栈顶的活动,对于用户来说就是可见的,而其他在筒中的活动,对于用户来说都是不可见的。
<基本内容>
【活动的四种状态】
1、运行状态
重要特征——活动位于返回栈的栈顶。用户可见且可以与之交互
2、暂停状态
重要特征——活动不在栈顶,但是可见。也就是说有一个透明或者非全屏的Activity被激活,你之前的Activity可视但是它没有焦点,即无法在与用户交互。
3、停止状态
重要特征——活动不在栈顶,也不可见。
Intent intent =new Intent(aActivity.this,bActivity.class);
startActivity(intent);
a活动在跳转完成后便会进入暂停状态,因为不可见且不在栈顶。
4、销毁状态
重要特征——活动从栈中移除。此时系统会回收资源,从而保证手机内存充足。
接着再来说一下系统在回收资源时的一个优先策略问题:
在android的Activity类中有7个回调方法覆盖了上述的四种状态,所以小伙伴们无比要对上述的内容了熟于心。
【活动的生存周期】
1.onCreate()
——回调时期:在活动第一次创建的时候。
——操作事件:活动的部分初始化操作,例如事件绑定,加载布局
2、onStart()
——回调时期:活动由不可见变为可见时。
——操作事件:活动的部分初始化操作
3、onResume()
——回调时期:活动准备好和用户进行交互的时候
——操作事件:无特殊说明
此时活动一定位于返回栈的栈顶且处于运行状态。
4、onPause()
——回调时期:在系统准备去启动或者恢复另一个活动的时候调用。
——操作事件:将一些消耗CPU的资源释放掉,以及保存一些关键数据
这个方法内的执行速度一定要快,不然会影响新栈顶活动的使用
5、onStop()
——回调时期:在活动不可见的时候调用
——操作事件:无特殊说明
与onPause()方法 区别在于:如果启动的活动是一个对话框式的活动,那么onPause()方法会执行,但onStop()方法不会被执行
6、onDestory()
——回调时期:在活动被销毁之前调用
——操作事件:释放内存及相关资源
之后活动的状态就将变为销毁状态
7、onRestar()
——回调时期:在活动由停止状态变为运行状态前调用,也就是活动被重新启动了。
——操作事件:无特殊说明
以上的七个方法中除了onRestart()方法,其他都是两两相对的,又可以划分三种生存期:
完整生存周期
onCreate()——onDestroy():在onCreate()方法中完成各种初始化操作,而在onDestroy()方法中完成释放内存的操作。可见生产周期
onStart()——onStop():在可见生命周期内,活动对用户总是可见的,即便有可能无法和用户进行交互。 我们可以通过这两个方法,合理地管理那些对用户可见的资源。在onStart()方法中对资源进行加载,在onStop方法中对资源进行释放,从而保证处于停止状态的活动不会占用太多的内存。前台生命周期
onResume()——onPause():就是只前台生命周期,在这个周期内,活动总是处于运行状态的,此时活动是可以和用户进行交互的。
最后再附上一张大家喜闻乐见的图片,是一张Activity活动的生命周期图:
【关于切换屏幕时的生命周期】
屏幕由横屏切换到竖屏(或竖屏切换到横屏时),其活动的生命周期是和该活动在配置清单文件中的设定有关。
1、若不设置android:configChanges,切换屏幕时即可理解为活动销毁然后重新加载
2、若设置了android:configChanges=”orientation|keyboardHidden”,切换屏幕时不会调用各个生命周期,只会调用onConfigurationChanged方法
【活动的启动模式】
在实际的开发过程中,我们可以在 AndroidManifest.xml 中通 过给activity标签 指定android:launchMode属性来选择启动模式。活动的启动模式,一共有4种,分别是:standard,singleTop,SingleTask,SingleInstance。接下来,就简单介绍一下这四种启动模式。
Standard
前面已经介绍过,android是通过返回栈来管理Activity的,那么在介绍活动的启动模式时,自然也会跟栈有关。
默认情况下,Activity的启动模式都是standard,它的含义是:每次激活Activity时,它就会在返回栈中入栈,并处于栈顶的位置。对于使用standard 模式的活动,系统不会在乎这个活动是否已经在返回栈中存在,即每次启动都会创建该活动的一个新的实例。
原图来自《第一行代码》
SingleTop
当活动的启动模式指定为 singleTop,在启动活动时如果发现返回栈的栈顶已经是该活动,则认为可以直接使用它,不会再创建新的活动实例,即栈中已经存在该该Activity实例,只要不在栈顶,都会创建实例。
原图来自《第一行代码》
SingleTask
如果在栈中已经有该Activity的实例,就重用该实例(会调用实例的onNewIntent())。重用时,会让该实例回到栈顶,因此在它上面的实例将会被移除栈。如果栈中不存在该实例,将会创建新的实例放入栈中
原图来自《第一行代码》
SingleInstance
在一个新栈中创建该Activity实例,并让多个应用共享该栈中的该Activity实例。一旦该模式的Activity的实例存在于某个栈中,任何应用再激活该Activity时都会重用该栈中的实例,其效果相当于多个应用程序共享一个应用,不管谁激活该Activity都会进入同一个应用中。
原图来自《第一行代码》
<补充>
关于Activity生命周期的使用还应该知道的事情:
在onCreate()函数中我们需要配置一些必要的信息,但并不是所有的操作都要放在onCreate()当中。在onCreate()之后还有onStart()和onResume()方法,在执行onResume()之后活动才会处于可见状态。
那么在一个Activity真正启动之前(onResume()方法执行之前),任何相当耗时的操作都会导致Activity启动缓慢。特别是在onCreate()里面耗时过长的话可能导致极差的用户体验。
例如加载数据库数据,读取文件信息,读取SMI卡信息等等,这些操作都是可能抛出异常的,而且耗时操作的时间也是不确定的。在面对活动启动优化的时候,需要注意几点
在Activity启动之前,少做耗时操作
对于布局比较复杂的时候,可以考虑不要一次性全部加载上,动态加载是一个不错的解决方法。
对于及时需要的数据,加载起来耗时又有异常危险的,一定要记得开辟一个新的线程来做这些动作,千万不要阻塞主线程(UI线程)的任何事情。
细化活动启动过程(onCreate、onStart、onResume)其目的之一是让你要启动的组建尽快上场,不一定要将组建完全构建好。
如果所有的操作都放在了onCreate()当中,在activity被调用的时候,Activity实际上还是不可见的,如果有动画之类的操作,既然视图此时还不存在,那么在onCreate()当中启动动画肯定是有问题的。而且当一个活动从暂停状态变为运行状态时(从栈中重新回到栈顶),由于活动已经实例化了,所以onCreate()方法是不会被执行的,有可能需要一些初始化操作,那就没办法调用了。
如果所有的初始化操作都放在onStart()方法中会有怎么样?
首先,onCreate()注释中,是明确建议setContentView()、findViewById()要放在onCreate()中被调用。但是在onStart()方法中上述两个方法也是可以正常使用的。onStart() 被调用时,Activity可能是可见了,但还不是可交互的, onResume() 的注释中都明确地说了这不是Activity对用户是可见的最好的指示器,onStart() 在这之前被调用,那有一些特殊的初始化相关的逻辑在这里被调用也会有问题。如果把所有的去初始化都在onStop()中实现,会有什么问题?
1、 在 onResume() 的注释中,建议是在onResume()中打开独占设备(比如相机),与onResume()对应的是onPause(),所以所有的去初始化操作放在onStop()中执行,可能会引出新的问题;
2、 onStop() 的注释中明确地写了,在内存不足而导致系统无法保留此进程的情况下,onStop() 可能都不会被执行。后台activity被系统回收了怎么办?如果后台activity由于某种原因被系统回收了,如何保存之前状态?
除了在栈顶的activity,其他的activity都有可能在内存不足的时候被系统回收,一个activity越处于栈底,被回收的可能性越大.
解决办法:
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putLong("id", 1234567890);
}
public void onCreate(Bundle savedInstanceState) {
//判断savedInstanceState是不是空.
//如果不为空就取出来
super.onCreate(savedInstanceState);
}