Activity的生命周期和启动模式

1.1 Activity的生命周期全面分析

activity的生命周期主要分为两部分的内容,一部分是典型情况下的声明周期,另一部分是异常情况下的生命周期。所谓典型情况下的生命周期,是指在用户参与的情况下,Activity所经过的生命周期的改变;而异常情况下的生命周期是指Activity被系统回收或者由于当前设备的Configuration发生改变从而导致Activity被销毁重建。
1.1.1典型情况下的生命周期分析
在正常情况下,Activity会经历如下的生命周期
(1)onCreate:表示Activity正在被创建,这是生命周期的第一个方法。在这个方法中,我们可以做一些初始化工作,比如调用setContentView去加载界面布局资源、初始化Activity所需数据等。
(2)onRestart:表示Activity正在重新启动。一般情况下,当当前Activity从不可见重新变为可见状态时,OnRestract就会被调用。这种情形一般是用户行为所导致的。比如用户按Home键切换到桌面或者用户打开一个新的Activity,这时当前的Activity就会暂停,也就是OnPause和OnStop被执行了,接着用户又回到了这个Activity,就会出现这种情况。
(3)onStart:表示Activity正在被启动,即将开始,这时Activity已经可见了,但是还没有出现在前台,还无法和用户交互。这个时候其实可以理解为Activity已经显示出来了,但是我们还看不到。
(4)onResume:表示Activity已经可见了,并且出现在前台并开始活动。要注意这个和onStart的对比,onStart和onResume都表示Activity已经可见,但是onStart的时候Activity还在后台,onResume的时候Activity才显示到前台。
(5)onPause:表示Activity正在停止,正常情况下,紧接着onStop就会被调用。在特殊情况下,如果这个时候快速的再回到当前Activity,那么onResume会被调用。此时可以做一些存储数据,停止动画等工作,但是不能太耗时,因为这会影响到新Activity的显示,onPause必须先执行完,新Activity的onResume才会执行。
(6)onStop:表示Activity即将停止,可以做一些稍微重量级的回收工作,同样不能太耗时。
(7)onDestroy:表示Activity即将被销毁,这是Activity声明周期中的最后一个回调,在这里,我们可以做一些回收工作和最终的资源释放。

这里写图片描述

例子:
(1)针对一个特定的Activity,第一次启动,回调如下:onCreate->onStart->onResume。
(2)当用户打开新的Activity或者切换到桌面的时候,回调如下:onPause->onStop。这里有一种特殊情况,如果新Activity采用了透明主题,那么当前Activity不会回调onStop。
(3)当用户再次回到Activity时,回到如下:onRestart->onStart->onResume。
(4)当用户按back键回退时,回调如下:onPause->onStop->onDestroy。
(5)从整个生命周期来说,onCreate和onDestory是配对的,分别标识着Activity的创建和销毁,并且只可能有一次调用。从Activity是否可见来说,onStart和onStop是配对的,随着用户的操作或者屏幕的点亮和熄灭,这两个方法可能会被调用多次;从Activity是否在前台来说,onResume和onPause是配对的,随着用户操作或者设备屏幕的点亮和熄灭,这两个方法可能会被调用多次。
OnResume 和onPause是从Activity是否位于前台这个角度去回调函数,OnStart和OnStop是从Activity
另外第一个Activity的OnPause调用后,才会调用第二个Activity的OnStop。
第一:前台进程
前台进程是Android系统中最重要的进程,是与用户正在交互的进程。
第二高:可见进程
可见进程指部分程序界面能够被用户看见,却不在前台与用户交互。
第三高:服务进程
一个包含已启动服务的进程就是服务进程,服务没有用户界面,不与用户直接交互,但能够在后台长期运行,提供用户所关心的重要功能。
第四高:后台进程
如果一个进程不包含任何已经启动的服务,而且没有用户可见的Activity,则这个进程就是后台进程。
第五高:空进程
空进程是不包含任何活跃组件的进程。在系统资源紧张时会被首先清楚。

1.1.2异常情况下的生命周期分析
1.情况1:资源相关的系统配置发生改变导致Activity被杀死并重新创建
当系统配置发生改变后,Activity会被销毁,其onPause、onStop、onDestroy均会被调用,同时由于Activity是在异常情况下终止的,系统会调用onSaveInstanceState来保存当前Activity的状态。这个方法的调用时机是在onStop之前,他和onPause没有既定的时序关系,它既可能在onPause之前调用,也可能在onPause之后调用,只会出现在Ativity被异常终止的情况下。当Activity被重新创建后,系统会调用onRestoreInstanceState,并且把Activity销毁时onSaveInstanceState方法所保存的Bundle对象作为参数同时传递给OnRestoreInstanceState和onCreate方法。因此,我们可以通过onRestoreInstanceState和onCreate方法来判断Activiy是否被重建了,如果被重建了,那么我们就可以去除之前保存的数据并回复,从时序上来说,onRestoreInstanceState的调用时机在onStart之后。
同时,在onSaveInstanceState和onRestoreInstance方法中,系统自动为我们做了一定的恢复工作。当Activity在异常情况下需要重新创建时,系统会默认为我们保存当前Activity的视图结构,并且在Activity重启后为我们恢复这些数据,比如文本框中用户输入的数据、ListView滚动的位置等,这些View相关的状态系统都能够默认为我们恢复。具体针对某一个特性的View系统能为我们恢复哪些数据,我们可以查看View的源码,和Activity一样,每个View都有onSaveInstanceState和onRestoreInstanceState这两个方法,看一下他们的具体实现,就能知道系统能够自动为每个View恢复哪些数据。
关于保存和恢复View层次结构,系统的工作流程是这样的:首先Activity被意外终止时,Activity会调用onSaveInstanceState去保存数据,然后Activity会委托Window去保存数据,接着Window再委托它上面的顶级容器去保存数据。顶层容器是一个ViewGroup,一般来说它很可能是DecorView。最后顶层容器再去一一通知它的子元素来保存数据,这样整个数据保存过程就完成了。可以发现,这是一种典型的委托思想,上层委托下层、父容器委托子元素去处理意见事情,这种思想在 Android中有很多应用,比如View的绘制过程、事件分发等都采用了类似的思想。恢复的过程也类似。
理论上恢复是可以选择onRestoreInstanceState或者onCreate,二者的区别是:OnRestoreInstanceState一旦被调用,其参数Bundle savedInstanceState一定是有值的,我们不用额外地判断是否为空。
另外如果Activity的配置发生变化,会调用Activity的onConfigurationChanged方法,这个时候我们就可以做一些自己的特殊处理了。
1.2.1 Activity的启动模式
(1)standard:标准模式,系统的默认模式。每次启动一个Activity都会重新创建一个新的实例,不管这个实例是否已经存在。被创建的实例的生命周期符合典型情况下Activity的生命周期,如上节描述,它的onCreate、onStart、onResume都会被调用。这是一种典型的多实例实现,一个任务栈中可以有多个实例,每个实例也可以属于不同的任务栈。在这种模式下,谁启动这个Activity,那么这个Activity就运行在启动它的那个Activity所在的栈中。
(2)singleTop:栈顶复用模式。在这种模式下,如果新Activity已经位于任务栈的栈顶,那么此Activity不会被重新创建,同时它的onNewIntent方法会被回调,通过此方法的参数我们可以取出当前请求的信息。需要注意的是,这个Activity的onCreate、onStart不会被系统调用,因为他并没有发生改变。如果新Activity的实例已经存在但不是位于栈顶,那么新Activity仍然会重新创建。
(3)singleTask:栈内复用模式。这是一种单实例模式,在这种模式下,只要Activity在一个栈中存在,那么多次启动此Activity都不会重新创建实例,和singleTop一样,系统也会回调其onNewIntent。具体一点,当一个具有SingleTask模式的Activity请求启动后,比如Activity A,系统首先会寻找是否存在A想要的任务栈,如果不存在,就重新创建一个任务栈,然后创建A的实例后把A放到栈中。如果存在A所需的任务栈,这时要看A是否在栈中有实例存在,如果实例不存在,就创建A的实例并把A压入栈中。举几个例子:
比如目前任务栈S1中的情况为ABC,这个时候ActivityD以singleTask模式请求启动,,其所需要的任务栈为S2,由于S2和D的实例均不存在,所以系统会先创建任务栈S2,然后在创建D的实例并将其入栈到S2。
另外一种情况,假设D所需的任务栈为S1,其他情况如上面的例子,那么由于S1已经存在,所以系统会直接创建D的实例并将其入栈到S1。
如果D所需的任务栈为S1,并且当前任务栈S1的情况为ADBC,根据栈内复用的原则,此时D不会重新创建,系统会把D切换到栈顶并调用其onNewIntent方法,同时由于singleTask默认具有clearTop的效果,会导致栈内所有在D上面的Activity全部出栈,于是最终S1中的情况为AD。这一点比较特殊。
SingleInstance:单实例模式。这是一种加强的singleTask模式,它除了具有singleTask模式的所有特性外,还加强了一点,那就是具有此模式的Activity只能单独的位于一个任务栈中,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值