文章出處

概述

一個Activity允許用戶完成一些操作,甚至,Android中設計Activity為組件的形式,這樣,多個Activity——甚至是其它App的Activity可以一起完成一項任務。

Task

多個Activity一起完成一項工作時,它們的集合被稱作一個Task。
A task is a collection of activities that users interact with when performing a certain job.

Back Stack

一個Task所有的Activity被放置在一個stack結構中,根據它們的啟動順序被添加。
stack不會進行重新排列,只會在打開新Activity時添加其到棧頂,或finish時從棧頂移除。所以Activity在此stack中表現為"last in, first out"。

因為上述特點,多個Activity在打開和關閉時,stack表現出“回退棧”這樣的效果。

Task的底層實現

系統中,每一個Activity組件實例被使用一個ActivityRecord對像表示,所有的Activity組件都保存在一個ActivityStack對象的字段ArrayList mHistory中。
ActivityRecord.task字段表示其所在Task,類型是TaskRecord。
假設把所有Activities指定編號:a0,a1,a2...an,表示mHistory中第0,1,2...n個Activity,那么,Task就是從a0到an中連續的一個個“子序列”,一個Task包括1或多個Activity。
可見:Task中的Activity的“棧結構”是通過ArrayList間接實現的

在啟動一個Activity時,可以在Intent中添加標記,指示其運行在新的Task中,還是已經存在的Task中。

若為Activity指定為NEW_TASK,那么它被添加到mHistory的末尾,并且作為新Task的棧底的Activity—— root activity。

若啟動的Activity運行在已有的Task中,此時:
對mHistory進行倒序遍歷,找到task和對應newActivity一致的ActivityRecord record對像,然后添加其到此record后面。

前臺和后臺Task

當一個Activity中棧頂Activity正在顯示時,它就是前臺Task。
棧頂topActivity轉為stopped狀態時Task也變為后臺的。
一個Activity總是屬于某個Task,它的Resumed或Stopped狀態影響其Task狀態。

每次Task棧頂的Activity被finish,那么它出棧。新的棧頂的Activity被resume。
若所有Activity都finish并出棧,此Task不再存在,之前啟動此Task時的前臺Task被轉到前臺。

Activity和Task默認的表現是:

  • When Activity A starts Activity B, Activity A is stopped, but the system retains its state (such as scroll position and text entered into forms). If the user presses the Back button while in Activity B, Activity A resumes with its state restored.

  • When the user leaves a task by pressing the Home button, the current activity is stopped and its task goes into the background. The system retains the state of every activity in the task. If the user later resumes the task by selecting the launcher icon that began the task, the task comes to the foreground and resumes the activity at the top of the stack.

  • If the user presses the Back button, the current activity is popped from the stack and destroyed. The previous activity in the stack is resumed. When an activity is destroyed, the system does not retain the activity's state.

  • Activities can be instantiated multiple times, even from other tasks.

Activity的狀態保存

處于stopped狀態的Activity,它的內存狀態和Resumed比并沒有變化。這樣稍后用戶回到界面時可以從Stopped狀態轉為Resumed狀態,即從后臺轉到前臺。

不過系統為了內存利用,可能回收長期處于后臺的Activity,這樣,
用戶再回到界面時,Activity會重新創建,未保存的狀態會丟失。
為了之后用戶回到當前Task時繼續原先的操作,需要主動保存view和activity對象的一些狀態。
通過:
onSaveInstanceState(Bundle outState)
onRestoreInstanceState(Bundle savedInstanceState)
onCreate(Bundle savedInstanceState)

管理Task

可以通過manifest文件中配置

attribute有:

taskAffinity
launchMode
allowTaskReparenting
clearTaskOnLaunch
alwaysRetainTaskState
finishOnTaskLaunch

flag有:

FLAG_ACTIVITY_NEW_TASK
FLAG_ACTIVITY_CLEAR_TOP
FLAG_ACTIVITY_SINGLE_TOP

Activity的啟動模式

可以通過配置

 使用manifest

使用launchModeattribute。

"standard" (the default mode)

Default. The system creates a new instance of the activity in the task from which it was started and routes the intent to it. The activity can be instantiated multiple times, each instance can belong to different tasks, and one task can have multiple instances.

singleTop

如果當前Task棧頂是對應Activity類的實例,則將intent傳遞給它的onNewIntent()方法,不創建新實例。

特點:一個Task中可以存在多個,多個實例可以存在于不同Task中。

singleTask

若當前Task或其它Task中存在要啟動的Activity的實例,就發送intent給它,并且設置了flag:Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT。已有的Activity的onNewIntent()被執行,位于其上的stack中的其它Activity都會被finish,只留下此rootActivity被resume。

若系統中還不存在Activity實例,就創建一個新Task,并且將此Activity作為其root activity。此時,若finish此實例,將回到啟動它時的前一個Activity。

特點:只能有一個。

singleInstance

Same as "singleTask", except that the system doesn't launch any other activities into the task holding the instance. The activity is always the single and only member of its task; any activities started by this one open in a separate task.

特點:只能有一個,且其Task只包含此Activity。

返回規則

不論啟動的Activity在當前Task還是新的Task中,返回按鈕總是把用戶帶到前一個Activity界面。

若啟動singleTask的Activity在其它Task2中,那么其中的Activity都會被添加到當前Task的返回路徑的前面,所以僅在用戶關閉對應Task2中的所有Activity后,才返回到當前啟動操作時的Task1。

diagram_backstack_singletask_multiactivity

A representation of how an activity with launch mode "singleTask" is added to the back stack. If the activity is already a part of a background task with its own back stack, then the entire back stack also comes forward, on top of the current task.

使用Intent flags

FLAG_ACTIVITY_NEW_TASK

和 "singleTask" 的行為一樣。

FLAG_ACTIVITY_SINGLE_TOP

和"singleTop"一樣。

FLAG_ACTIVITY_CLEAR_TOP

If the activity being started is already running in the current task, then instead of launching a new instance of that activity, all of the other activities on top of it are destroyed and this intent is delivered to the resumed instance of the activity (now on top), through onNewIntent()).

There is no value for the launchMode attribute that produces this behavior.

FLAG_ACTIVITY_CLEAR_TOP is most often used in conjunction with FLAG_ACTIVITY_NEW_TASK. When used together, these flags are a way of locating an existing activity in another task and putting it in a position where it can respond to the intent.

Note: If the launch mode of the designated activity is "standard", it too is removed from the stack and a new instance is launched in its place to handle the incoming intent. That's because a new instance is always created for a new intent when the launch mode is "standard".

官方文檔亂寫?

使用affinities

The affinity indicates which task an activity prefers to belong to.
默認的每個activity的affinity是其包名。
可以使用android:taskAffinity改變application或某個activity的taskAffinity。

使用taskAffinity用途一般是:

  • 結合FLAG_ACTIVITY_NEW_TASK
    此時系統尋找affinity 相同的 的Task來放置Activity,如果沒有就創建新的Task,此Activity作為其root。
    一個Task的root activity的affinity就是此Task的affinity。

  • 標簽屬性 allowTaskReparenting為true
    In this case, the activity can move from the task it starts to the task it has an affinity for, when that task comes to the foreground.

清空back stack

默認情況下,系統會保持Task中的stack,即便對應Activity的進程被回收,它還會重建。
若較長時間再回到當前Task,系統會選擇清除root外的所有Activity。

可以通過對Activity設置標簽屬性定制行為:

  • alwaysRetainTaskState
    為root activity設置,無論多久都不會清除任何activity。

  • clearTaskOnLaunch
    為root activity設置,一旦用戶離開當前Task,再回來時總是只剩下root。

  • finishOnTaskLaunch
    針對某個activity,包括root,一旦離開再返回Task,設置此屬性的activity一定會移除。

入口Task

入口Activity所在的Task一般認為是application的main Task。
當app啟動后,點擊桌面的icon可以在任何時候返回到main Task。

(本文使用Atom編寫)


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()