进程、线程与任务程序之间的关系
1,Aplication 一個(gè).apk包就可以稱一個(gè)application,一般application會(huì)有很多Activity 或其他service組成。
2,task:完成用戶的一個(gè)目的的所有activity 組成一個(gè)task.提到task就該提到task stack任務(wù)棧也有人叫活動(dòng)棧。Android系統(tǒng)用一個(gè)棧來記錄一個(gè)任務(wù),既然一個(gè)任務(wù)是由許多activity組成的,那棧里存的就是所有的 activity。為什么需要記錄呢?因?yàn)橛涗浛梢酝ㄟ^按back 鍵回到上一個(gè)activity.這也是為什么我們按back鍵可以回到上一個(gè)活動(dòng)的原因。那么什么時(shí)會(huì)開啟一個(gè)新的任務(wù)呢?A)Notification 啟動(dòng)Activity會(huì)開啟一個(gè)task,因?yàn)橥ㄟ^notification開啟activity之后不需要返回到notification,所以需要開啟一個(gè)新的task,這就是為什么我們?cè)趎ofication里面啟動(dòng)一個(gè)Activity需要設(shè)置Intent的Flag為 Intent.FLAG_ACTIVITY_NEW_TASK.
3,explicit intent 是明確指定啟動(dòng)哪個(gè)Activity,比如 Intent intent= new Intent(ActivityA.this, ActivityB.class).而implicit intent并不明確指定啟動(dòng)那個(gè)Activity,而是通過設(shè)置一些Intent Filter來讓系統(tǒng)去帥選合適的activity來處理。為什么需要分這兩種Intent呢?我覺得好處有兩個(gè):第一,Activity 的重用,當(dāng)一個(gè)Activity在其manifest里設(shè)置了許多intent filter,當(dāng)發(fā)生了implicit intent時(shí),系統(tǒng)就會(huì)去匹配這些filter,是否符合目標(biāo)。所以在設(shè)計(jì)Activity的時(shí)候就要考慮到是否重用問題,若需要重用就要設(shè)置 intent filter. 第二,Implicit intent可以讓用戶選擇自己喜歡的Activity來處理。若在系統(tǒng)匹配filter時(shí),發(fā)現(xiàn)多個(gè)符合目標(biāo)的activtiy就會(huì)彈出對(duì)話框讓用戶來選擇Activity.
4,啟動(dòng)一個(gè)Activity可以是同一個(gè)application也可以是不同的application來啟動(dòng),這就是為什么每個(gè) Activity需要自己獨(dú)立的生命周期。這意味著task stack里有可能不同application的activity組成。也就是說一個(gè)task是可以有不同的application組成或者說一個(gè) task由不同的application完成的。
Back 鍵與Home鍵
android的手機(jī)的back鍵默認(rèn)行為是finish處于前臺(tái)的Activity的即Activity的狀態(tài)為Destroy狀態(tài),再次啟動(dòng)該Activity是從onCreate開始的。
而Home鍵默認(rèn)是stop前臺(tái)的Activity即狀態(tài)為onStop而不是Destroy,若再次啟動(dòng)它,則是從OnResume開始的,即會(huì)保持上次Activityd的狀態(tài)。
back鍵也有例外的,按back鍵不會(huì)關(guān)閉Activity的,比如播放音樂,按了back鍵之后仍可以繼續(xù)播放音樂,這是Music這支ap已經(jīng)重寫了back鍵的事件處理。
為什么需要Home鍵和Back鍵呢?一個(gè)使得Activity 為Stop一個(gè)使得為Destroy呢?我想原因的原因在于是android也是一個(gè)多任務(wù)的操作系統(tǒng),通過Home鍵切換不同的任務(wù),而通過back關(guān)閉任務(wù)中的某一個(gè)活動(dòng)。若仔細(xì)想想就覺得PC的多任務(wù)行為一樣的。
應(yīng)用程序模型:應(yīng)用、任務(wù)、進(jìn)程、線程
在多數(shù)操作系統(tǒng)中,在應(yīng)用程序駐留的可執(zhí)行映像文件、運(yùn)行的進(jìn)程和用戶交互的圖標(biāo)和應(yīng)用之間有強(qiáng)1對(duì)1的關(guān)系。在Android操作系統(tǒng)中,這些關(guān)聯(lián)更多的是不固定,重要的是理解不同的部分怎么整合在一起。
因?yàn)锳ndroid應(yīng)用成需的靈活的特性,當(dāng)實(shí)現(xiàn)程序的各個(gè)部分的時(shí)候,有一些基本術(shù)語需要理解。
1、android包(簡稱.apk)是包容程序代碼和資源的文件。這也是發(fā)布應(yīng)用程序的文件,當(dāng)用戶在其設(shè)備上安裝應(yīng)用程序時(shí),由用戶下載這個(gè)文件。
2、一般一個(gè)任務(wù)是用戶覺察出的作為一個(gè)能運(yùn)行的應(yīng)用程序的東西:通常一個(gè)任務(wù)在HOME屏幕有一個(gè)圖標(biāo),通過這個(gè)圖標(biāo)可以被用戶訪問,作為頂層條目,任務(wù)可獲得,能在其他任務(wù)前面放到前臺(tái)。
3、進(jìn)程是低級(jí)核心處理過程,用于運(yùn)行應(yīng)用程序代碼。通常,在.apk中的所有代碼只運(yùn)行在一個(gè)進(jìn)程中,每個(gè).apk都有專用的進(jìn)程。但是,進(jìn)程標(biāo)簽?zāi)苡糜谛薷拇a運(yùn)行的地方,要么針對(duì)整個(gè).apk,要么針對(duì)單個(gè)活動(dòng)、接收器、服務(wù)、提供者、組件。
任務(wù)
這里關(guān)鍵點(diǎn):當(dāng)用戶看到認(rèn)為他們是一個(gè)應(yīng)用程序時(shí),實(shí)際上處理的東西就是一個(gè)任務(wù)。如果你僅僅創(chuàng)建一個(gè)帶有大量活動(dòng)的.apk,其中一個(gè)活動(dòng)是頂級(jí)入口點(diǎn)(通過一個(gè)intent過濾器針對(duì)操作android.intent.action.MAIN和分類 android.intent.category.LAUNCHER),那么的確有一個(gè)任務(wù)針對(duì)你的.apk創(chuàng)建起來,從這里啟動(dòng)的任何活動(dòng)也作為那個(gè)任務(wù)的一部分運(yùn)行。
一個(gè)任務(wù),來自用戶的眼中看,是應(yīng)用程序;從程序開發(fā)者眼中看,是一到多個(gè)活動(dòng),用戶已經(jīng)越過進(jìn)入那個(gè)任務(wù),但是還沒有關(guān)閉,或者,一個(gè)活動(dòng)堆棧。一個(gè)新任務(wù)是通過使用Intent.FLAG_ACTIVITY_NEW_TASK 標(biāo)志啟動(dòng)一個(gè)活動(dòng)Intent來創(chuàng)建的;這個(gè)Intent會(huì)用于作為任務(wù)的根Intent,定義是什么任務(wù)。任何沒有使用這個(gè)標(biāo)志啟動(dòng)的活動(dòng)會(huì)運(yùn)行在和正在運(yùn)行的那個(gè)活動(dòng)所在的相同的任務(wù)中(除非活動(dòng)已經(jīng)請(qǐng)求一個(gè)特殊的啟動(dòng)模式,稍后討論)。任務(wù)能被排序:如果你使用FLAG_ACTIVITY_NEW_TASK 但是已經(jīng)有一個(gè)任務(wù)運(yùn)行于那個(gè)Intent,當(dāng)前任務(wù)的活動(dòng)堆棧會(huì)送到前臺(tái)而不是啟動(dòng)一個(gè)新的任務(wù)。
FLAG_ACTIVITY_NEW_TASK 必須小心地單獨(dú)使用:使用這個(gè)標(biāo)志就說明,從用戶的角度看,一個(gè)新的應(yīng)用程序在這個(gè)點(diǎn)啟動(dòng)。如果這不是你喜歡的行為,你應(yīng)該不創(chuàng)建一個(gè)新任務(wù)。另外,如果用戶可能從HOME屏幕回退到原來的位置,你應(yīng)該僅僅使用新任務(wù)標(biāo)志,以運(yùn)行和新任務(wù)同樣的Intent。否則,如果用戶從正在運(yùn)行的任務(wù)中按下HOME鍵而不是BACK鍵,你的任務(wù)機(jī)器活動(dòng)將會(huì)在home屏幕之后被排序,而沒有辦法返回。
任務(wù)親和力
在一些情況下,Android需要知道活動(dòng)屬于哪一個(gè)任務(wù),即使當(dāng)活動(dòng)沒有運(yùn)行在指定的任務(wù)中時(shí)。這是通過任務(wù)親緣關(guān)系完成的,任務(wù)親緣關(guān)系提供一個(gè)唯一的任務(wù)靜態(tài)名稱,一到多個(gè)活動(dòng)打算運(yùn)行在具有靜態(tài)名稱的任務(wù)中。一個(gè)活動(dòng)默認(rèn)的任務(wù)親和力是實(shí)現(xiàn)活動(dòng)的.apk包的名稱。這就提供了通常的可期望的行為,其中,在指定.apk文件中所有活動(dòng)對(duì)用戶來說是單個(gè)應(yīng)用程序的一個(gè)部分。
當(dāng)啟動(dòng)一個(gè)新活動(dòng)而不是Intent.FLAG_ACTIVITY_NEW_TASK 標(biāo)志的時(shí)候,任務(wù)親緣關(guān)系沒有影響新活動(dòng)運(yùn)行的任務(wù):總是運(yùn)行在觸發(fā)任務(wù)的活動(dòng)的任務(wù)中。但是,如果NEW_TASK被使用,那么親緣關(guān)系會(huì)用于決定一個(gè)任務(wù)是否和一個(gè)相同的親緣關(guān)系已經(jīng)存在。如果是已經(jīng)存在,那么任務(wù)將會(huì)被提到前臺(tái),新活動(dòng)運(yùn)行在那個(gè)任務(wù)的頂層。
這種行為對(duì)于必須使用NEW_TASK標(biāo)志的情況是非常有用的,特別是從狀態(tài)欄通知或者h(yuǎn)ome屏幕快捷方式運(yùn)行活動(dòng)時(shí)。結(jié)果是:當(dāng)用戶使用這種方式運(yùn)行你的程序時(shí),當(dāng)前任務(wù)狀態(tài)會(huì)拉到前臺(tái),用戶現(xiàn)在想看到的活動(dòng)被放到頂層。
你能在manifest的應(yīng)用程序標(biāo)簽中指定你自己的任務(wù)親緣關(guān)系,針對(duì).apk的所有活動(dòng),或者針對(duì)單個(gè)活動(dòng)的活動(dòng)標(biāo)簽。怎么使用親緣關(guān)系的例子如下:
1、如果你的.apk包含多個(gè)頂層的用戶能運(yùn)行的應(yīng)用程序,那么你會(huì)可能想分派不同的親和力到用戶從你的.apk中找到的每個(gè)活動(dòng)。使用不同的名稱的好的慣例是添加你的.apk包名稱,使用克隆的獨(dú)立的字符串。例如,"com.android.contacts".apk文件可能有親緣關(guān)系"com.android.contacts:Dialer" 和 "com.android.contacts:ContactsList"。
2、如果你正在替換通知、快捷方式、其他內(nèi)嵌的在內(nèi)部運(yùn)行的活動(dòng),那么你可能需要顯式設(shè)置你替換的活動(dòng)的任務(wù)親緣關(guān)系為與你替換的應(yīng)用程序相同。例如,如果你正在替換通訊錄詳細(xì)視圖(用戶可以創(chuàng)建和調(diào)用快捷方式),那么你會(huì)想設(shè)置任務(wù)親緣關(guān)系到"com.android.contacts"。
運(yùn)行模式和運(yùn)行標(biāo)志
控制活動(dòng)和任務(wù)交互的主要方法是通過活動(dòng)的launchMode屬性和與Intent關(guān)聯(lián)的標(biāo)志。這兩個(gè)參數(shù)能一同工作在控制活動(dòng)運(yùn)行的結(jié)果的各種方法之下,正如在關(guān)聯(lián)文檔中描述的那樣。在這里,我們將會(huì)看到一些常用的用例和這些參數(shù)的組合。
最常用的運(yùn)行模式(除了默認(rèn)的標(biāo)準(zhǔn)模式外)是singleTop。這不會(huì)對(duì)任務(wù)有影響,這種模式恰好避免不同時(shí)間啟動(dòng)同一個(gè)活動(dòng)(在堆棧頂層)
singleTask 運(yùn)行模式對(duì)任務(wù)有一個(gè)主要的影響:導(dǎo)致活動(dòng)總是啟動(dòng)在新任務(wù)里(或者,已存在的任務(wù)被拉到前臺(tái))。使用這種模式要求關(guān)心怎么和系統(tǒng)的其他部分交互,因?yàn)樗绊懙交顒?dòng)的每個(gè)路徑。這種模式應(yīng)該僅被用于作為應(yīng)用程序前門的活動(dòng)(即,支持MAIN操作和LAUNCHER分類)
singleInstance運(yùn)行模式更多地是專用的,應(yīng)該僅僅用于完全作為一個(gè)活動(dòng)來實(shí)現(xiàn)應(yīng)用程序的情況下。
你經(jīng)常會(huì)運(yùn)行進(jìn)入的一種情況是另外一個(gè)實(shí)體(比如:SearchManager、NotificationManager)啟動(dòng)你的其中一個(gè)活動(dòng)。在這種情況下,Intent.FLAG_ACTIVITY_NEW_TASK 標(biāo)志必須使用,因?yàn)榛顒?dòng)在任務(wù)的外部啟動(dòng)(應(yīng)用程序和任務(wù)甚至可以不存在)。正如前面描述的,這種情況下的標(biāo)準(zhǔn)行為是,把當(dāng)前任務(wù)提到前臺(tái),當(dāng)前任務(wù)匹配新活動(dòng)的affinity,并在頂層啟動(dòng)新活動(dòng)。但是,有您能實(shí)現(xiàn)的其他類型的行為。
一個(gè)普通的方法是,與NEW_TASK一起使用Intent.FLAG_ACTIVITY_CLEAR_TOP標(biāo)志。通過這樣做,如果你的任務(wù)已經(jīng)在運(yùn)行,那么將會(huì)被提到前臺(tái),堆棧中的所有活動(dòng)將被清除,除了根活動(dòng),根活動(dòng)的onNewIntent(Intent)在Intent被啟動(dòng)的時(shí)候被調(diào)用。注意,當(dāng)使用這種方法的時(shí)候,活動(dòng)經(jīng)常使用singleTop或者singleTask運(yùn)行模式,因此,當(dāng)前實(shí)例給予新Intent而不是請(qǐng)求銷毀和產(chǎn)生新實(shí)例。
你能采用的另外一個(gè)辦法是,設(shè)置通知活動(dòng)的任務(wù)affinity為空串(表示無affinity),并設(shè)置 finishOnBackground屬性。這種辦法是有用的,如果你將會(huì)希望通知把用戶帶到一個(gè)分離的活動(dòng),勝于返回到應(yīng)用程序的任務(wù)。通過指定這個(gè)屬性,不論用戶是否使用BACK或者HOME離開活動(dòng),活動(dòng)都會(huì)完成。如果屬性沒有被指定,按HOME將會(huì)導(dǎo)致進(jìn)入活動(dòng),其任務(wù)保持在系統(tǒng)中,可能沒有辦法返回。
保證閱讀launchMode屬性和Intent標(biāo)志相關(guān)文檔,以了解這些選項(xiàng)。
進(jìn)程
在Android操作系統(tǒng)中,進(jìn)程完全是應(yīng)用程序的具體實(shí)現(xiàn),不是用戶通常認(rèn)為的那種東西。他們的主要用途是簡單的:
1、改善穩(wěn)定性或者安全性,通過把未信任或者不穩(wěn)定的代碼放入獨(dú)立的進(jìn)程的方法來解決
2、簡化在同一進(jìn)程中多個(gè).apk文件的代碼的運(yùn)行
3、有助于系統(tǒng)管理資源,通過吧重量級(jí)代碼放入獨(dú)立的進(jìn)程,可以被殺掉,而且和程序的其他部分無關(guān)。
正如前面描述的那樣,進(jìn)程屬性用于控制細(xì)小程序組件運(yùn)行的進(jìn)程。注意,這些進(jìn)程屬性不能用于違反系統(tǒng)安全規(guī)則:如果沒有共享同一個(gè)用戶ID的兩個(gè).apk文件試圖運(yùn)行在同一個(gè)進(jìn)程中,那么,這是不允許的,不同的進(jìn)程將會(huì)分別針對(duì)每個(gè).apk文件被創(chuàng)建。
參見安全相關(guān)的文件了解更多的關(guān)于安全規(guī)則的信息。
線程
每個(gè)進(jìn)程有一到多個(gè)線程運(yùn)行在其中。在多數(shù)情況下,Android避免在進(jìn)程中創(chuàng)建額外的線程,保證應(yīng)用程序是單線程的,除非應(yīng)用程序自己又創(chuàng)建了線程。重要印證是,注意,新線程不會(huì)針對(duì)每個(gè)Activity/BroadcastReceiver/Servie/ContentProvider實(shí)例:這些程序組件在對(duì)應(yīng)的進(jìn)程中實(shí)例化(除非另作說明所有的組件都位于同一個(gè)進(jìn)程),在那個(gè)進(jìn)程的主線程中。這意味著,當(dāng)被系統(tǒng)調(diào)用的時(shí)候,沒有組件(包括服務(wù))應(yīng)該在進(jìn)程中執(zhí)行長的或者阻塞的組件(例如網(wǎng)絡(luò)調(diào)用或者計(jì)算循環(huán)),因?yàn)檫@將會(huì)阻塞所有進(jìn)程中的其他組件。你可以使用標(biāo)準(zhǔn)庫線程類或者Android的 HandleThread類來在另外一個(gè)線程中執(zhí)行長操作。
There are a few important exceptions to this threading rule:
線程規(guī)則有幾處例外:
1、到IBinder的訪問或者在IBinder上實(shí)現(xiàn)的接口從調(diào)用它們的線程被調(diào)度,或者如果來自其他進(jìn)程則從本地進(jìn)程中的線程池被調(diào)度,不是從他們的進(jìn)程的主線程被調(diào)度。特別地,到服務(wù)的IBinder的訪問將會(huì)以這種方式調(diào)用。(雖然到在服務(wù)自身的調(diào)用來自主線程。)這意味著,IBinder接口的實(shí)現(xiàn)必須總是在線程安全模式下編寫,因?yàn)樗麄兡茉谕粫r(shí)間從許多隨機(jī)線程中被調(diào)用。
2、到ContentProvider的調(diào)用從調(diào)用線程或者IBinder所在的主線程被調(diào)度。在ContentProvider類的相關(guān)文檔中這個(gè)方法有描述。這意味著,這些方法的實(shí)現(xiàn)必須總是以線程安全方式編寫,因此,他們能在同一時(shí)刻從許多隨機(jī)線程被調(diào)用。
3、在View和它的子類上調(diào)用來自視圖窗口運(yùn)行的線程。正常情況下,這將會(huì)是進(jìn)程的主線程,但是如果你創(chuàng)建一個(gè)線程,然后從線程中顯示一個(gè)窗口,那么這個(gè)窗口的視圖層次將會(huì)從那個(gè)線程被調(diào)用。
?
?
__________________________________________________________________________________________________________________________
?
在大多數(shù)操作系統(tǒng)里,存在獨(dú)立的一個(gè)1對(duì)1的可執(zhí)行文件(如Windows里的exe文件), 它可以產(chǎn)生進(jìn)程,并能和界面圖標(biāo)、應(yīng)用進(jìn)行用戶交互。但在Android里,這是不固定的,理解將這些分散的部分如何進(jìn)行組合是非常重要的。
由于Android這種可靈活變通的,在實(shí)現(xiàn)一個(gè)應(yīng)用不同部分時(shí)你需要理解一些基礎(chǔ)技術(shù):
一個(gè)android 包(簡稱.apk ) ,里面包含應(yīng)用程序的代碼以及資源。這是一個(gè)應(yīng)用發(fā)布,用戶能下載并安裝他們?cè)O(shè)備上的文件。
一個(gè) 任務(wù) ,通常用戶能當(dāng)它為一個(gè)“應(yīng)用程序”來啟動(dòng):通常在桌面上會(huì)有一個(gè)圖標(biāo)可以來啟動(dòng)任務(wù),這是一個(gè)上層的應(yīng)用,可以將你的任務(wù)切換到前臺(tái)來。
一個(gè) 進(jìn)程 是一個(gè)底層的代碼運(yùn)行級(jí)別的核心進(jìn)程。通常.apk包里所有代碼運(yùn)行在一個(gè)進(jìn)程里,一個(gè)進(jìn)程對(duì)于一個(gè).apk包;然而, 進(jìn)程 標(biāo)簽常用來改變代碼運(yùn)行的位置,可以是 全部的.apk包 或者是獨(dú)立的 活動(dòng), 接收器, 服務(wù), 或者 提供器組件。
任務(wù)
記住關(guān)鍵的一點(diǎn):當(dāng)用戶看到的“應(yīng)用”,無論實(shí)際是如何處理的,它都是一個(gè)任務(wù)。如果你僅僅通過一些活動(dòng)來創(chuàng)建一個(gè).apk包,其中有一個(gè)肯定是上層入口(通過動(dòng)作的intent-filter 以及分類android.intent.category.LAUNCHER),然后你的.apk包就創(chuàng)建了一個(gè)單獨(dú)任務(wù),無論你啟動(dòng)哪個(gè)活動(dòng)都會(huì)是這個(gè)任務(wù)的一部分。
一個(gè)任務(wù),從使用者的觀點(diǎn),他是一個(gè)應(yīng)用程序;對(duì)開發(fā)者來講,它是貫穿活動(dòng)著任務(wù)的一個(gè)或者多個(gè)視圖,或者一個(gè)活動(dòng)棧。當(dāng)設(shè)置Intent.FLAG_ACTIVITY_NEW_TASK標(biāo)志啟動(dòng)一個(gè)活動(dòng)意圖時(shí),任務(wù)就被創(chuàng)建了;這個(gè)意圖被用作任務(wù)的根用途,定義區(qū)分哪個(gè)任務(wù)。如果活動(dòng)啟動(dòng)時(shí)沒有這個(gè)標(biāo)記將被運(yùn)行在同一個(gè)任務(wù)里(除非你的活動(dòng)以特殊模式被啟動(dòng),這個(gè)后面會(huì)討論)。如果你使用FLAG_ACTIVITY_NEW_TASK標(biāo)記并且這個(gè)意圖的任務(wù)已經(jīng)啟動(dòng),任務(wù)將被切換到前臺(tái)而不是重新加載。
FLAG_ACTIVITY_NEW_TASK必須小心使用:在用戶看來,一個(gè)新的應(yīng)用程序由此啟動(dòng)。如果這不是你期望的,你想要?jiǎng)?chuàng)建一個(gè)新的任務(wù)。另外,如果用戶需要從桌面退出到他原來的地方然后使用同樣的意圖打開一個(gè)新的任務(wù),你需要使用新的任務(wù)標(biāo)記。否則,如果用戶在你剛啟動(dòng)的任務(wù)里按桌面(HOME)鍵,而不是退出(BACK)鍵,你的任務(wù)以及任務(wù)的活動(dòng)將被放在桌面程序的后面,沒有辦法再切換過去。
任務(wù)親和力(Affinities)
一些情況下Android需要知道哪個(gè)任務(wù)的活動(dòng)附屬于一個(gè)特殊的任務(wù),即使該任務(wù)還沒有被啟動(dòng)。這通過任務(wù)親和力來完成,它為任務(wù)中一個(gè)或多個(gè)可能要運(yùn)行的活動(dòng)提供一個(gè)獨(dú)一無二的靜態(tài)名字。默認(rèn)為活動(dòng)命名的任務(wù)親和力的名字,就是實(shí)現(xiàn)該活動(dòng).apk包的名字。這提供一種通用的特性,對(duì)用戶來說,所有在.apk包里的活動(dòng)都是單一應(yīng)用的一部分。
?
當(dāng)不帶Intent.FLAG_ACTIVITY_NEW_TASK 標(biāo)記啟動(dòng)一個(gè)新的活動(dòng),任務(wù)親和力對(duì)新啟動(dòng)的活動(dòng)將沒有影響作用:它將一直運(yùn)行在它啟動(dòng)的那個(gè)任務(wù)里。然而,如果使用NEW_TASK標(biāo)記,親和力會(huì)檢測(cè)已經(jīng)存在的任務(wù)是否具有相同的親和力。如果是,該任務(wù)會(huì)被切換到前臺(tái),新的活動(dòng)會(huì)在任務(wù)的最上面被啟動(dòng)。
你可以在你的表現(xiàn)文件里的應(yīng)用程序標(biāo)簽里為.apk包里所有的活動(dòng)設(shè)置你自己的任務(wù)親和力,當(dāng)然也可以為單獨(dú)的活動(dòng)設(shè)置標(biāo)簽。這里有些例子演示如何使用:
如果你的.apk包里包含多個(gè)用戶可啟動(dòng)的上層應(yīng)用程序,那么你可能想要為每個(gè)活動(dòng)分配不同的親和力。這里有一個(gè)不錯(cuò)的協(xié)定,你可以將不同的名字字串加上冒號(hào)附加在.apk包名字的后面 。 例如,"com.android.contacts"的親和力命名可以是"com.android.contacts:Dialer" and "com.android.contacts:ContactsList"。
如果你想替換一個(gè)通知,快捷鍵,或者其它能從外部啟動(dòng)的應(yīng)用程序的內(nèi)部活動(dòng),你需要在你想替換的活動(dòng)里明確的設(shè)置任務(wù)親和力(taskAffinity)。例如,如果你想替換聯(lián)系人詳細(xì)信息瀏覽界面(用戶可以直接操作或者通過快捷方式調(diào)用),你需要設(shè)置任務(wù)親和力(taskAffinity)為“com.android.contacts”。
啟動(dòng)模式以及啟動(dòng)標(biāo)記
你控制活動(dòng)和任務(wù)通信的最主要的方法是通過設(shè)置啟動(dòng)模式的屬性以及意圖相應(yīng)的標(biāo)記。這兩個(gè)參數(shù)能以不同的組合來共同控制活動(dòng)的啟動(dòng)結(jié)果,這在相應(yīng)的文檔里有描述。這里我們只描述一些通用的用法以及幾種不同的組合方式。
你最通常使用的模式是singleTop(除了默認(rèn)為standard模式)。這不會(huì)對(duì)任務(wù)產(chǎn)生什么影響;僅僅是防止在棧頂多次啟動(dòng)同一個(gè)活動(dòng)。
singleTask模式對(duì)任務(wù)有一些影響:它能使得活動(dòng)總是在新的任務(wù)里被打開(或者將已經(jīng)打開的任務(wù)切換到前臺(tái)來)。使用這個(gè)模式需要加倍小心該進(jìn)程是如何和系統(tǒng)其他部分交互的,它可能影響所有的活動(dòng)。這個(gè)模式最好被用于應(yīng)用程序入口活動(dòng)的標(biāo)記中。(支持MAIN活動(dòng)和LAUNCHER分類)。
singleInstance啟動(dòng)模式更加特殊,該模式只能當(dāng)整個(gè)應(yīng)用只有一個(gè)活動(dòng)時(shí)使用。
有一種情況你會(huì)經(jīng)常遇到,其它實(shí)體(如搜索管理器SearchManager 或者 通知管理器NotificationManager)會(huì)啟動(dòng)你的活動(dòng)。這種情況下,你需要使用Intent.FLAG_ACTIVITY_NEW_TASK 標(biāo)記,因?yàn)榛顒?dòng)在任務(wù)(這個(gè)應(yīng)用/任務(wù)還沒有被啟動(dòng))之外被啟動(dòng)。就像之前描述的一樣, 這種情況下標(biāo)準(zhǔn)特性就是當(dāng)前和任務(wù)和新的活動(dòng)的親和性匹配的任務(wù)將會(huì)切換到前臺(tái),然后在最頂端啟動(dòng)一個(gè)新的活動(dòng)。當(dāng)然,你也可以實(shí)現(xiàn)其它類型的特性。
一個(gè)常用的做法就是將Intent.FLAG_ACTIVITY_CLEAR_TOP 和NEW_TASK一起使用。這樣做,如果你的任務(wù)已經(jīng)處于運(yùn)行中,任務(wù)將會(huì)被切換到前臺(tái)來, 在棧里的所有的活動(dòng)除了根活動(dòng),都將被清空,根活動(dòng)的onNewIntent(Intent) 方法傳入意圖參數(shù)后被調(diào)用。當(dāng)使用這種方法的時(shí)候singleTop 或者singleTask啟動(dòng)模式經(jīng)常被使用,這樣當(dāng)前實(shí)例會(huì)被置入一個(gè)新的意圖,而不是銷毀原先的任務(wù)然后啟動(dòng)一個(gè)新的實(shí)例。
另外你可以使用的一個(gè)方法是設(shè)置活動(dòng)的任務(wù)親和力為空字串(表示沒有親和力),然后設(shè)置finishOnBackground屬性。 如果你想讓用戶給你提供一個(gè)單獨(dú)的活動(dòng)描述的通知,倒不如返回到應(yīng)用的任務(wù)里,這個(gè)比較管用。要指定這個(gè)屬性,不管用戶使用BACK還是HOME,活動(dòng)都會(huì)結(jié)束;如果這個(gè)屬性沒有指定,按HOME鍵將會(huì)導(dǎo)致活動(dòng)以及任務(wù)還留在系統(tǒng)里,并且沒有辦法返回到該任務(wù)里。
請(qǐng)確保閱讀過文檔啟動(dòng)模式屬性(launchMode attribute) 以及 意圖標(biāo)記(Intent flags) ,關(guān)注這些選項(xiàng)的詳細(xì)信息。
進(jìn)程
在Android中,進(jìn)程是應(yīng)用程序的完整實(shí)現(xiàn),而不是用戶通常了解的那樣。他們主要用途很簡單:
提高穩(wěn)定性和安全性,將不信任或者不穩(wěn)定的代碼移動(dòng)到其他進(jìn)程。
可將多個(gè).apk包運(yùn)行在同一個(gè)進(jìn)程里減少系統(tǒng)開銷。
幫助系統(tǒng)管理資源,將重要的代碼放在一個(gè)單獨(dú)的進(jìn)程里,這樣就可以單獨(dú)銷毀應(yīng)用程序的其他部分。
像前面描述的一樣,進(jìn)程的屬性被用來控制那些有特殊應(yīng)用組件運(yùn)行的進(jìn)程。注意這個(gè)屬性不能違反系統(tǒng)安全: 如果兩個(gè).apk包不能共享同一個(gè)用戶ID,卻試圖運(yùn)行在通一個(gè)進(jìn)程里,這種情況是不被允許的,事實(shí)上系統(tǒng)將會(huì)創(chuàng)建兩個(gè)不同的進(jìn)程。
請(qǐng)查看安全相關(guān)文檔以獲取更多關(guān)于安全限制方面的信息。
?
線程
每個(gè)進(jìn)程包含一個(gè)或多個(gè)線程。多數(shù)情況下,Android 避免在進(jìn)程里創(chuàng)建多余的線程,除非它創(chuàng)建它自己的線程,我們應(yīng)保持應(yīng)用程序的單線程性。 一個(gè)重要的結(jié)論就是所有呼叫實(shí)例, 廣播接收器, 以及 服務(wù)的實(shí)例都是由這個(gè)進(jìn)程里運(yùn)行的主線程創(chuàng)建的。
注意新的線程不是為活動(dòng),廣播接收器,服務(wù)或者內(nèi)容提供器實(shí)例創(chuàng)建:這些應(yīng)用程序的組件在進(jìn)程里被實(shí)例化(除非另有說明,都在同一個(gè)進(jìn)程處理),實(shí)際上是進(jìn)程的主線程。這說明當(dāng)系統(tǒng)調(diào)用時(shí)這些組件(包括服務(wù))不需要進(jìn)程遠(yuǎn)距離或者封鎖操作(就像網(wǎng)絡(luò)呼叫或者計(jì)算循環(huán)),因?yàn)檫@將阻止進(jìn)程中的所有其他組件。你可以使用標(biāo)準(zhǔn)的線程 類或者Android的HandlerThread 類去對(duì)其它線程執(zhí)行遠(yuǎn)程操作。
這里有一些關(guān)于創(chuàng)建線程規(guī)則的例外:
呼叫IBinder或者IBinder實(shí)現(xiàn)的接口,如果該呼叫來自其他進(jìn)程,你可以通過線程發(fā)送的IBinder或者本地進(jìn)程中的線程池呼叫它們,從進(jìn)程的主線程呼叫是不可以的。特殊情況下,,呼叫一個(gè)服務(wù) 的IBinder可以這樣處理。(雖然在服務(wù)里呼叫方法在主線程里已經(jīng)完成。)這意味著IBinder接口的實(shí)現(xiàn)必須要有一種線程安全的方法,這樣任意線程才能同時(shí)訪問它。
呼叫由正在被調(diào)用的線程或者主線程以及IBinder派發(fā)的內(nèi)容提供器 的主方法。被指定的方法在內(nèi)容提供器的類里有記錄。這意味著實(shí)現(xiàn)這些方法必須要有一種線程安全的模式,這樣任意其它線程同時(shí)可以訪問它。
呼叫視圖以及由視圖里正在運(yùn)行的線程組成的子類。通常情況下,這會(huì)被作為進(jìn)程的主線程,如果你創(chuàng)建一個(gè)線程并顯示一個(gè)窗口,那么繼承的窗口視圖將從那個(gè)線程里啟動(dòng)。
___________________________________________________________________________________________________________________________________
轉(zhuǎn)載于:https://www.cnblogs.com/crazywenza/archive/2012/11/28/2792997.html
總結(jié)
以上是生活随笔為你收集整理的进程、线程与任务程序之间的关系的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CVS代码库管理安装配置
- 下一篇: 理解关于java反射中类的域及修饰符