> 向前面說的那樣,一個activity可以啟動另一個activity,包括在其他應用程序里定義的activity。假如你想讓用戶顯示一些街道地圖的位置信息,已經(jīng)存在這樣一個功能的activity了,所以你只需填好Intent信息并曾通過startActivity()方法傳遞Intent,地圖瀏覽器就會顯示地圖。當用戶按Back鍵時,會回到原來的activity。
對于用戶來說,地圖瀏覽器就像你程序的一部分一樣,盡管他是在另一個應用程序里定義并且運行的。Android為了良好的用戶體驗而讓兩個activity運行在同一個任務里。簡單地說,用戶認為一個task就是一個“應用程序”。應用程序是一組相關的activity,排列在一個堆棧里。通常,堆棧里的主activity會啟動用戶在啟動器里選擇的那個activity。棧頂?shù)腶ctivity就是當前運行的,得到用戶焦點的。當啟動了另一個activity,新的activity就會到棧頂,然后運行。上一個activity仍然留在棧里。當用戶按返回Back鍵時,當前activity就被彈出棧,上一個activity繼續(xù)運行。
棧里保存著很多的對象。如果一個任務有很多個activity實例例如多個地圖瀏覽器,那么棧會給每一個實例分配單獨的入口,棧里的activity實例永遠不會重新分配,只會被彈進,彈出。
一個任務是整個activity的堆棧,不是指一個類或者manifest文件中的一個元素。所以不可能單獨的設置棧里的某一個activity的值。事實上軟任務的值是主activity里設定的。例如我們以后會提到的“任務的affinity”。從affinity讀取的值可以設置到任務的主activity中。 任務里的所有activity被看做一個整體。這個整理可以被拿到前臺或者放在后臺運行。假設當前任務有四個activity,一個正在運行的和三個在堆棧里的。用戶按下HOME鍵后,會轉(zhuǎn)到程序觸發(fā)器里,讓用戶選擇一個新的應用程序,實際上是一個新的任務。當前任務轉(zhuǎn)到后臺,新任務的主activity開始運行。一段時間后,用戶又回到HOME屏,選擇啟動剛才隱藏的任務,隱藏的任務中四個activity都會轉(zhuǎn)到前臺。當用戶按下BACK鍵時,屏幕不會顯示剛剛離開的activity(上一個任務的主activity),而會顯示當前任務中,當前棧中的上一個activity。(即不會在任務間返回只會在activity間返回)。
上面只是說了activity和任務的默認的行為,其實可以修改他們幾乎所有的方面。activity和任務的聯(lián)系、任務里activity的行為、被Intent對象的標記和<activity>里的元素影響著,無論是請求者還是回應者都有一定決定權(quán)。
FLAG_ACTIVITY_NEW_TASK FLAG_ACTIVITY_CLEAR_TOP FLAG_ACTIVITY_RESET_TASK_IF_NEEDED FLAG_ACTIVITY_SINGLE_TOP
taskAffinity launchMode allowTaskReparenting clearTaskOnLaunch finishOnTaskLaunch
接下來會介紹這些標記和屬性的作用,之間的相互影響,和使用它們時的應考慮到的問題。
(這段很別扭) 默認情況下,一個程序里的各個activity之間都有聯(lián)系,他們共屬于同一個任務task,然而,通過taskAffinity的<activity>屬性可以給每個activity設置個人的Affinities 。定義在不同應用程序里的activity可以共享自己的affinities,定義在相同的程序里的activity也可以聲明不同的affinities。affinity 在兩種情況下起作用:一種是當通過Intent啟動的activity中包含有FLAG_ACTIVITY_NEW_TASK標記時,一種是activity的allowTaskReparenting屬性被設置成true時。
如前所述,被其他activity通過startActivity()方法啟動的activity,他和啟動他的前一個activity屬于同一個堆棧。然而,如果傳遞的Intent對象中被設置了FLAG_ACTIVITY_NEW_TASK標記,那么系統(tǒng)會在一個新的任務里啟動activity。通常,啟動的activity就像名字那樣,是一個新的任務。然后,那不是必須的,如果已經(jīng)存在了和要啟動的activity相同affinity的任務,已存在的任務會被運行,如果不存在才會重啟一個新的任務。
如果一個activity的allowTaskReparenting 屬性為true,那么這個activity可以從啟動他的任務里移動到和他擁有相同affinity的activity所在的任務里,如果那個后者的activity正在頂端運行時。例如,假設一個activity(一個旅行程序的一部分)報告所選城市的天氣情況。這個天氣activity和程序里的其他的activity擁有相同的affinity,并且天氣activity的allowTaskReparenting屬性為true,如果程序的其中一個activity啟動天氣報告的話,那么這個天氣報告部分將會屬于你的activity。然而,當旅行的程序接下去運行時,報告天氣這部分會在另一個任務里顯示和運行。
如果一個apk包含多個應用程序,你最好分配不同的affinity給activity。
// TODO Launch modes 運行模式 Clearing the stack 清理堆棧 Starting tasks 啟動任務
|