您的位置:首页 > 移动开发 > Android开发

《Android群英传》读书笔记(9)第八章:Activity与Activity调用栈分析

2015-12-21 15:20 309 查看

一、Activity

1.Activity形态

Activity拥有多种形态,并且可以在多种形态间切换,以此来控制自己的生命周期:

Active/Running

这时候Activity处于Activity栈的最顶层,可见并与用户进行交互

Paused

当Activity失去焦点,被一个新的非全屏的Activity或者一个透明的Activity放置在栈顶的时候,Activity就转化为Paused形态,但它只是失去了与用户交互的能力,所有状态信息、成员变量都还保存着,只有在系统内存极低的情况下,才会被系统回收

Stopped

如果一个Activity被另一个Activity完全覆盖,那么Activity就会进入Stopped状态,此时它不再可见,但却依然保持了所有状态信息和成员变量。

Killed

当Activity被系统回收掉或者Activity从来没有创建过,Activity就处于Killed状态。

2.生命周期

Activity的生命周期包括onCreate()->onStart()->onResume()(Resumed)->onPause()(Paused)->onStop()(Stopped)->onDestroy()和onRestart()这几个过程。不必实现所有的生命周期方法,但要知道每个状态的含义才能更好的掌控Activity。
Activity的生命周期状态中只有三个是稳定的,其他状态都是过渡状态,下面列出了这三个稳定状态:

Resumed

这个状态时Activity处于栈顶,处理用户的交互。

Paused

当Activity的一部分被挡住的时候进入这个状态,这个状态下的Activity不会接收用户的输入。

Stopped

当Activity完全被覆盖时进入这个状态,此时Activity不可见,仅在后台运行。

Activity的启动与销毁过程

在系统调用onCreate()之后,就会马上调用onStart(),然后继续调用onResume()以进入Resumed状态,最后会停在Resumed状态完成启动,系统会调用onDestroy()来结束一个Activity的生命周期让它回到Killed状态。

onCreate()中:创建基本的UI元素。

onPaused()与onStop()中:清除Activity的资源,避免浪费。

onDestroy()中:因为引用会在Activity销毁的时候销毁,而线程不会,所以在此清除开启的线程。

Activity的暂停与恢复过程:

当栈顶的Activity部分不可见后,就会导致Activity进入Pause状态,此时就会调用onPause()方法,当结束阻塞后,就会调用onResume()方法来恢复到Resume状态。

onPause():释放系统资源,如Camera、sensor、receivers。

onResume():重新初始化在onPause()中释放的资源。

Activity的停止过程

栈顶的Activity部分不可见时,实际上后续会有两种可能,从部分不可见到可见,也就是恢复过程;从部分不可见到完全不可见,也就是停止过程。系统在当前Activity不可见的时候,总会调用onPause()方法。当一个Activity由不可见到可见的时候总会调用onStart()方法。

Activity的重新创建过程

当Activity长时间处于Stopped状态且此时系统需要更多内存或者系统内存极为紧张时,系统就会回收你的Activity,而此时Activity状态会通过调用onSaveInstanceState()保存,你也可以增加额外的键值对存入Bundle对象以保存这些状态。当你需要重新创建这些Activity的时候,Bundle对象会传递到onCreate()和onRestoreSavedInstanceState()方法中。

不过需要注意的是当用户调用finish()来结束Activity时,系统并不会调用onSaveInstanceState()方法。

二、Activity任务栈

Android中系统通过栈结构来保存整个App的Activity,栈底的元素是整个任务栈的发起者。当一个App启动时,如果当前环境中不存在该App的任务栈,那么系统会创建一个任务栈,此后这个App所启动的Activity都将在这个任务栈中被管理,这个掌握也称为一个Task,表示若干个Activity的集合,他们组合在一起形成一个Task。需要特别注意的是一个Task中的Activity可以来自不同的App,同一个App的Activity也可能不在同一个Task中。

在一个Activity栈中,当一个Activity启动了另一个Activity的时候,新启动的Activity就会置于栈顶,并处于活动状态,启动它的Activity依然会保留在任务栈中处于停止状态,当用户按下返回键或者调用finish()方法时,系统会移除顶部的Activity。让后面的Activity恢复活动状态。

1.AndroidMainfest启动模式

这四种启动模式通过在AndroidManifest文件中设置Activity的launchMode属性来指定

standard

默认的启动模式,每次都会创建新的示例,每次以Standard模式启动的Activity都会创建新的Activity覆盖在原Activity上。

singleTop

在Activity启动时,系统会判断当前栈顶Activity是否是要启动的Activity,如果是则不再创建新实例,而是直接引用这个Activity,并调用这个Activity的onNewIntent()方法。这种模式常用于收到消息后显示的界面,例如QQ收到消息后弹出的界面,如果一次来10条消息,总不能一次弹出10个Activity。

singleTask

与singleTop模式类似,singleTask是检测整个Activity栈中是否存在当前需要启动的Activity,如果存在,则将该Activity置于栈顶,并将该Activity以上的Activity都销毁。不过这里指在同一个App中启动这个singleTask的Activity,如果在其他App中以singleTask启动这个Activity,那么它将创建一个新的任务栈。需要注意的是,如果启动的模式为singleTask的Activity已经在后台的任务栈中了,那么启动后后台的这个任务栈将一起切换到前台,在点击返回键时,也会先返回这个Activity所在Task的Activity。

可见这个模式创建的Activity不是在新的任务栈中被打开,就是将已打开的Activity切换到前台,所以这种模式通常可以用来退出整个应用:将主Activity设为singleTask模式,然后在要退出的Activity中转到主Activity,从而将主Activity之上的Activity都清除,然后重写主Activity的onNewIntent()方法,在方法中加上一句finish(),将最后一个Activity结束掉。

singleInstance

声明为singleInstance的Activity会出现在一个新的任务栈中,而且该任务栈中只存在这一个Activity。例如A应用的任务栈中创建了MainActivity实例,且启动模式为singleInstance,如果应用B也要激活MainActivity,则不需要创建,两个应用共享该Activity实例,这种启动模式常用于需要与程序分离的界面,如在SetupWizard中调用紧急呼叫。

关于singleTop和singleInstance模式还有一点需要说明:当以这两种模式启动的Activity通过startActivityForResult()来启动另一个Activity,那么系统将直接返回Activity.RESULT_CANCELED而不会再去等待返回,因为Android开发者认为不同Task之间默认是不能传递数据的,如果一定要传,只能通过Intent来绑定数据。

2.Intent flag启动模式

Intent.FLAG_ACTIVITY_NEW_TASK

使用一个新的Task来启动一个Activity,启动的每个Activity都将在一个新的Task中,通常用在Service中启动Activity的场景,由于Service中并不存在Activity栈。

Intent.FLAG_ACTIVITY_SINGLE_TOP

使用singleTop来启动一个Activity。

Intent.FLAG_ACTIVITY_CLEAR_TOP

使用singleTask来启动一个Activity

Intent.FLAG_ACTIVITY_NO_HISTORY

使用这种模式启动的Activity,当该Activity启动其他Activity后,该Activity就消失了,不会保存在Activity栈中,例如A-B,B中以这种模式启动C,C再启动D,则当前的Activity栈为ABD。

3.清空任务栈

系统提供了清空任务栈的方法来让我们将一个Task全部清除,通常情况下可以在AndroidManifest文件中的Activity标签使用下面这几种属性来清理任务栈:

clearTaskOnLaunch

每次返回该Activity时,都将该Activity之上的所有Activity都清除,通过这个属性可以让这个Task每次在初始化的时候都只有这一个Activity。

finishOnTaskLaunch

通过这个属性,当离开这个Activity所处的Task,当用户再返回这个Task,该Activity就会被finish()掉。

alwaysRetainTaskState

该Activity所在的Task将不接受任何清理命令,一直保持当前Task的状态。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: