先拖张图压压惊,没错,就是官方的介绍图片
生命周期
正常的执行流程(完整生存期)
1
onCreate() -> onStart() -> onResume() -> 运行中 -> 另一个活动来到前台 -> onPause() -> onStop() -> onDestroy()
从不可见到可见(可见生存期)
1
onStop() -> onRestart() -> onStart() -> onResume() -> ...
可见无焦点到可见有焦点(前台生存期)
1
onPause() -> onResume() -> ...
进程被杀死时(App process killed)
1
onStop() -> onCreate() -> ...
解释一下这几种状态
- 可见、无焦点:onResume(),onPause()
- 不可见:onStart(),onStop()
- 启动、停止:onCreate(),onDestroy()
设备旋转与Activity生命周期
设备处于水平方向时,Android会找到并使用res/layout-land目录下的布局资源。其他情况下会默认使用res/layout目录下布局资源(两个布局需要使用相同的文件名)。
当设备旋转时,Android可自动完成最佳匹配资源的调用,但它必须要新建一个Activity(即设备旋转时首先销毁当前Activity然后新建一个Activity来完成onCreate方法,从而实现最佳资源匹配)
解决方案:
设备旋转前保存数据
1
protected void onSaveInstanceState(Bundle outState)
- 该方法会在onPause()之前调用
- 可以将一些数据存到Bundle中,然后在protected void onCreate(Bundle savedInstanceState)方法中取出来
- 一个比较好的做法:通过其他方式保存定制类对象,在Bundle中保存对应的标识符
启动模式
1 | <!--AndroidManifest.xml--> |
standard(默认)
standard是活动默认的启动模式,Android是使用返回栈来管理活动的,所谓栈就是先进后出,后进先出。该模式下,每启动一个新的活动,就会在返回栈中入栈,并处于栈顶的位置(即用户当前见到的活动)。系统不会 检查该活动的实例已经在返回栈中存在,每次启动都新建一个。当前返回栈为A->B(B为栈顶),新建活动B, 返回栈变为A->B->B。
singleTop(避免重复顶栈)
standard模式有时并不合理,比如活动实例已经在栈顶了,再次启动时还需再创建一个实例, 这会造成资源的浪费。singleTop模式下,如果当前栈顶已经是该活动实例,则认为可以直接使用,而不再创建新的活动。当前返回栈为A->B(B为栈顶),新建活动B, 返回栈仍为A->B。
singleTask(避免重复栈)
singleTop模式可以避免重复创建栈顶活动的问题,但是如果启动活动不在栈顶,而之前已经创建过,还是会重复创建。例如A->B->C,当前已有三个活动A、B、C,C位于栈顶,再创建B,返回栈变为A->B->C->B(另一个实例)。singleTask模式可以让返回栈中每个活动只存在一个实例,如果发现当前需要启动活动已经在栈中,则直接使用,但是该活动之上的所有活动全部出栈;如没有发现,则创建新的实例。例如A->B->C,如此时创建活动B,则返回栈变为A->B(B存在,使用B,C出栈);若此时创建活动D,则返回栈变为A->B->C->D
singleInstance
singleInstance模式是四种启动模式中最复杂的,不同于上述三种模式,指定为singleInstance模式的活动会启动一个新的返回栈来管理这个活动。例如当前有活动A、B、C,活动A、C为默认启动模式,B指定为singleInstance模式,首先新建A,A活动页面启动B,B启动C,此时的返回栈并不是A->B->C,而是存在2个返回栈,一个是A->C,另一个是B。此时按下BACK键返回,将从C返回到A,再按一次,A返回到B,按第三次,程序退出。即返回时,先清空栈A->C,再清空栈B。