一.任务( Task )
Android 系统是使用多任务机制的。 任务就是指在执行特定作业时与用户交互的一系列 Activity,在相同任务中的 Activity 有相同的标识( TaskAffinity ,默认情况下为包名 )因此通常情况下,一个应用中的 Activity 属于一个任务。 任务中的 Activity 按照各自的打开顺序排列在堆栈(即返回栈)中,也就是说每个任务有自己的返回栈。当用户点击应用图标的时候,如果这个应用的任务不存在(即未启动),就会创建一个新的任务,并将这个应用的指定的 MAIN Activity 实例化并压入栈中,如果这个应用的任务存在(已启动,但是在后台),就会将这个任务转换到前台。如果用户开始新的任务或者转到主屏幕的时候,旧任务中的所有 Activity 就会停止,但是这个任务的返回栈不变,仅仅是任务从前台转换到后台。
后台可以同时运行多个任务。但是,如果用户同时运行多个后台任务,则系统可能会开始销毁后台 Activity,以回收内存资源,从而导致 Activity 状态丢失。
二.返回栈(Back Stack)
Android 是使用任务 (Task)来管理 Activity 的进出顺序,一个任务就是一组存放在栈里的 Activity 的集合,这种栈也称为返回栈,是一种后进先出的数据结构。
· 当 Activity A 启动 Activity B 时,Activity A 将会停止,但系统会保留其状态, Activity B 就入栈并置于栈顶。如果用户在处于 Activity B 时按“返回”按钮,则 Activity A 将恢复其状态,继续执行,Activity B 就出栈 ,Activity A 重新回到栈顶。
· 用户通过按“主页”按钮离开任务时,当前 Activity 将停止且其任务会进入后台。 系统将保留任务中每个 Activity 的状态。如果用户稍后通过选择开始任务的启动器图标来恢复任务,则任务将出现在前台并恢复执行堆栈顶部的 Activity。
· 如果用户按“返回”按钮,则当前 Activity 会从堆栈弹出并被销毁。 堆栈中的前一个 Activity 恢复执行。销毁 Activity 时,系统不会保留该 Activity 的状态。
· 即使来自其他任务,Activity 也可以多次实例化
三.状态
(一).运行状态
处于栈顶,可见,面对着用户。
(二).暂停状态
可见但不是最前(比如出现对话框),只有在内存极低的情况下才会考虑回收这种 Activity。
(三).停止状态
不是栈顶且完全不可见,==保存着相应的状态和成员变量==,可能会被系统回收
(四).销毁状态
从栈中移除后,系统最可能回收这种 Activity。
· 一个 Activity 如果处于暂时不可见的状态,系统会保留其状态,当重新可见,回到栈顶的时候系统就会对 Activity 进行恢复。如果系统回收了系统内存资源, Activity 可能会被完全销毁,这时系统仍然知道 Activity 在栈中,所以当这个 Activity 重新回到栈顶的时候就会重新创建 Activity 而不是进行恢复。
四.生命周期
(一).典型状态下
imageresume 的读音 [rɪ'zju:m]
1.生存期
完整的生存期:onCreate -> onDestory
可见生存期:onStart -> onStop
前台生存期:onResume -> onPause
2..几点要注意的
(1).当进程被 kill 掉后重新返回 Activity 后执行的是 onCreate
(2).当Activity 重新回到栈顶,即重新回到这个 Activity 的时候 执行的是 onRestart -> onStart -> onResume
(3).对一个特定的 Activity ,第一次启动时 onCreate->onStart -> onResume
(4).当用户打开一个新的 Activity 或者切换到桌面的时候,执行的是onPause-> onStop
(5).onStart -> onStop 是从 Activity 是否可见这个角度来回调的,onResume -> onPause 是从 Activity 是否位于前台这个角度来回调的。
(6).Activity A 启动 Activity B 时,A 的 onPause 先执行,B 的 onResume 后执行。因此尽量在 onStop中尽量操作而不要在 onPause ,从而使新的 Activity 能够尽快显示。
(二).异常状态下
1.资源相关的系统配置发生改变导致 Activity 被 kill 并重新创建
2.资源内存不足导致低优先级的 Activity 被 kill
在异常情况下,系统会调用 onSaveInstanceState 保存当前的状态,这个方法是在 onStop 之前,在正常情况下系统不会调用这个方法,在 Activity 被重新创建之后 系统会调用 onRestoreInstance 并且把 onSaveInstanceState 保存的 Bundle 对象作为参数传递给 onRestoreInstance 和 onCreate .
注意:和 Activity 一样, 每个 View 也有 onSaveInstanceState 和 onRestoreInstance ,保存和恢复 View 的层次结构的过程是:首先 Activity 被意外终止时,Activity 会调用 onSaveInstanceState 去保存数据,然后 Activity 委托 Window 去保存数据,接着 Window 会委托顶级容器去保存数据,然后顶级容器再去一一通知它的子元素去保存数据。
onRestoreInstance 一旦被调用 Bundle 的值就不为 null, 而 onCreate 的 Bundle 不一定有值。
五.启动模式
启动模式允许定义 Activity 的实例如何与当前任务进行关联,有两种方式:
1.使用清单文件( launchMode )
2.使用 Intent 标志( Flag )
(一).TaskAffinity
affinity 的读音:[əˈfɪnɪti]
taskAffinity 就是任务关联属性,或者说是在 任务中的 Activity 有一个标识, 拥有相同的 taskAffinity 的 Activity 理论上属于相同 任务。任务的 taskAffinity 是由它的根 Activity 决定的。应用程序默认的 taskAffinity 的名字是 <manifest> 元素中设定的 package 名。默认下,一个应用程序中的所有 Activity 都拥有相同的 affinity 。通过设置可以进行修改,甚至可以把不同应用程序中定义的 Activity 放置到相同的 任务中。在两种情况下这个关联会起作用:
1.启动 Activity 的 Intent 包含 FLAG_ACTIVITY_NEW_TASK 标志 ,或者和 singleTask 启动模式配对使用.
2.Activity 将其 allowTaskReparenting 属性设置为 true
假设有应用 A 启动 应用 B 的 Activity ,这个 Activity 的 allowTaskReparenting 设置为 true,那么就会重新创建一个新的任务栈并且将这个 Activity 入栈,这个属性的作用是,如果这个时候启动 应用B ,则 B 将使用原来已经创建的任务栈,且这个时候不会启动 应用 B 的 MAIN Activity ,而是直接显示已经启动的 Activity 。
(二).launchMode
1.Standard 是 Activity 的默认的启动模式,系统在启动 Activity 的任务中创建 Activity 的新实例并向其传送 Intent。Activity 可以多次实例化,在不同任务中都可以创建这个 Activity ,并且一个任务可以拥有多个实例 在这种模式下,每次启动 Activity 都会重新创建一个新的实例置于栈的顶端。注意在默认情况下,这个 Activity 会置于 启动 Activity 的任务栈中,这与 TaskAffinity 的值无关。
standard 的读音 [ˈstændərd]
2.SingleTop 在这种模式下如果启动的 Activity 已经在栈顶就不再创建新的活动,系统会通过调用该实例的 onNewIntent() 方法向其传送 Intent,而不是创建 Activity 的新实例. 如果不是在栈顶就仍然重新创建一个。同样的, Activity 可以多次实例化,且每个实例可以属于不同的任务,并且一个任务可以有多个实例(前提是在启动时栈顶的 Activity 不是目标 Activity )。需要注意的是 Activity 的 onCreate ,onStart 不会执行。
当 Activity 的现有实例处理新 Intent 时,则在新 Intent 到达 onNewIntent() 之前,用户无法按“返回”按钮返回到 Activity 的状态。
3.SingleTask 在这种模式下如果这个 Activity 不存在,系统就会创建新任务并实例化位于新任务底部的 Activity。但是,如果该 Activity 的一个实例已存在于一个单独的任务中,则系统会通过调用现有实例的 onNewIntent() 方法向其传送 Intent,而不是创建新实例即一次只能存在 Activity 的一个实例。 启动的 Activity 如果在栈中已经存在,不管实在栈顶还是在栈内,都会直接使用栈中的实例,并且将栈中这个 Activity 之上的 Activity出栈使得这个 Activity 在栈顶。如果启动指定 singleTask 启动模式的 Activity,则当某后台任务中存在该 Activity 的实例时,整个任务都会转移到前台,并且压入当前任务的返回栈。此时,返回栈包括上移到堆栈顶部的任务中的所有 Activity 。
举几个例子:
(1).如果启动的 Activity 的 taskAffinity 和当前任务栈不一样,就创建新的任务栈。
(2).如果任务栈一样并且没有这个实例就创建实例直接入栈
(3).如果任务栈一样且有这个实例就将实例 Activity 置于栈顶
尽管 Activity 在新任务中启动,但是用户按“返回”按钮仍会返回到前一个 Activity。
需要注意:
如上图,YX 是后台任务栈(都用 singleTask 指定模式)中,启动 Y 后,后台任务栈会添加到前台,如果启动的是X ,那么Y 首先会出栈然后 X 会治愈前台的任务栈中。
网友评论