名詞解釋:
ActivityManagerService,簡稱AmS:系統重要服務,管理四大元件,有一個特别重要就是管理所有的java層程序,包括它自己運作在的系統程序。
一.Task到底是什麼?
Task可以了解為實作一個功能,負責管理所有用到的Activity的棧。
元件可以跨應用被調用,但是一個元件必須運作在元件所在的Aplication的程序中。
由于android強化了元件概念,弱化了Aplication的概念,是以在android程式開發中,A應用的A元件想要使用拍照或錄像的功能就可以不用去針對Camera類進行開發,直接調用系統自帶的攝像頭應用(稱其B應用)中的元件(稱其B元件)就可以了,但是這就引發了一個新問題,A元件跑在A應用中,B元件跑在B應用中,自然都不在同一個程序中,那麼從B元件中傳回的時候,如何實作正确傳回到A元件呢?Task 就是來負責實作這個功能的,它是從使用者角度來了解應用而建立的一個抽象概念。
在AmS中就是使用TaskRecord類來管理所有運作在該Task中的Activity。TaskRecord成員變量mActivities就是儲存所有運作在該Task中的ActivityRecord執行個體。
二.誰負責管理Activity?
1.真正排程一個Application中的所有Activity的是ActivityThread類,每個程序隻有一個ActivityThread。換句話說,每個ActivityThread排程該程序中所有應用的Activity。
2. AmS管理整個系統中所有Activity的是系統服務,整個系統隻有一個。
3.在KitKat中Ams通過ActivityStack管理一個Activity棧中所有的Activity,使用ActivityStackSupervisor來管理所有的ActivityStack。而AmS隻需要管理好ActivityStackSupervisor單執行個體就可以了。
4.真正啟動Activity的類是Instrument,每個程序隻有一個Instrument執行個體。
5.TaskRecord也負責管理Activity。
有以上内容可以知道,在AmS使用了一個層級結構來管理Activity。
三、Activity、Application與Process的關系
首先來了解下啟動一個Activity與Application和Process的關系。
在所屬應用第一個Activity啟動之前會啟動該Activity所在Application的程序,因為一個Activity隻能運作在所屬Application所在的程序中。
結論:
1. 一般情況下每個Application都是運作在一個程序中,特列:Application中的Service在AndroidManifest.xml中對android:process屬性指派,進而是Service運作在其他程序中。例如:
android:process="android.process.media" |
2. 每個程序可以運作多個Application,擁有相同的sharedUserId,例如系統應用:“音樂”,“下載下傳内容”就都是運作在android.media程序中的,例如:
android:sharedUserId="android.media" |
3. 一個java程序等價于一個java虛拟機。
四、Activity和Task的關系
影響Activity啟動關鍵點大緻有三個因素:
因素一:Activity注冊資訊中的launchMode;
因素二:啟動Activity時Intent中的launchFlags;
因素三:Activity注冊資訊中的 taskAffinity、allowTaskReparenting、clearTaskOnLaunch、alwaysRetainTaskState、finishOnTaskLaunch等資訊。
通常情況下,我們隻需要針對第一個因素進行合理設定就能滿足我們應用開發的需求了。
launchMode的四種方式:
launchMode的設定方法是在apk的AndroidManifest.xml檔案中針對每一個Activity的 android:launchMode屬性進行設定的方式,共有四種模式可以設定,分别是standard、singleTop、singleTask、singleInstance。
standard
standard是預設模式,即假設使用者在AndroidManifest.xm中對Activity不指定 android:launchMode的情況下,預設啟動模式即為standard。在啟動一個以standard為launchMode的Activity時,AmS隻是簡單的建立一個新的Activity執行個體,設定它的TaskId則與啟動它的Activity相同,并将其放到相應TaskRecord的mActivities的棧頂。這種是最常見的使用方式。
singleTop
啟動一個以singleTop為lauchMode的Activity時,Ams會查詢目前獲得焦點的ActivityStack中的所有Task: 假如在Task頂端正是要啟動的Activity執行個體,那麼Ams就不會重新啟動一個Activity執行個體,而是調用Task棧頂的該Activity執行個體的OnNewIntent()函數;假如在Task棧頂不是該Activity的執行個體,然後将Activity的執行個體壓入調用者所在的Task,這種方式主要用于避免自調自過程中,産生多個執行個體的情況。
singleTask
啟動一個以singleTask為lauchMode的Activity時,Ams會查詢所有的Task:如果某個Task内有一個該Activity的執行個體,那麼這個Activity執行個體一定是該Task的根Activity,這個是由于singleTask特性決定的,銷毀位于該Task中,該Activity執行個體之上的其他Activity執行個體,實際上就是銷毀該Task中其他的Activity執行個體。如果所有的Task中都沒有Activity的執行個體,那麼建立一個Task,該Activity成為該Task的根Activity,該Task可以運作其他的Activity,這個特性是與singleInstance的差別。
,
singleInstance
啟動一個以singleInstance為launchmode的Activity時,假如某個Task中已經有一個該類執行個體,那麼調用其onNewIntent()函數,自啟動;否則就會建立一個新的Task,該Task中隻有該Activity運作,不會再有其他Activity進入該Task。這也是與singleTask的唯一差別。
總結: 聲明為SingleInstance和SingleTask的Activity隻能是一個棧的棧底,而且SingleInstance與SingleTask的差別也僅僅是SingleInstance自己獨占一個Task,而SingleTask隻是一個Task的棧底,該Task還可以有其他的Activity。是以本圖中畫得不是特别正确,也隻是示意一下。對SingleTop而言,如果task中目标Activity在task的棧頂,那麼直接調用該Activity的onNewIntent()方法,自啟動;如果目标Activity不在task的棧頂,那麼就建立一個Activity對象壓入調用者所在的棧頂。 |