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