Android應(yīng)用程序模型之應(yīng)用程序,任務(wù),進(jìn)程,線程分析
本文講述了Android應(yīng)用程序模型之應(yīng)用程序,任務(wù),進(jìn)程,線程。分享給大家供大家參考,具體如下:
大多數(shù)操作系統(tǒng),在應(yīng)用程序所寄存的可執(zhí)行程序映像(如Windows系統(tǒng)里的.exe)、它所運(yùn)行的進(jìn)程以及和用戶(hù)交互的圖標(biāo)和應(yīng)用之間有一種嚴(yán)格的1對(duì)1關(guān)系。在Android系統(tǒng)里,這些關(guān)聯(lián)要松散得多。并且重要的是要理解各種概念怎么樣組成整體。
由于Android應(yīng)用固有的靈活性,當(dāng)實(shí)現(xiàn)這些不同方面的時(shí)候有一些基本術(shù)語(yǔ)需要加以理解:
① 一個(gè)Android包 (.apk)文件,其中包含一個(gè)應(yīng)用程序的代碼和資源。這是應(yīng)用程序分發(fā)和下載的文件,用戶(hù)用來(lái)安裝該應(yīng)用程序在他們的設(shè)備上。
② 一個(gè)任務(wù)一般而言是指用戶(hù)視為的一個(gè)可啟動(dòng)應(yīng)用程序:通常任務(wù)在桌面(home screen)有一個(gè)可訪問(wèn)的圖標(biāo),且可以被切換到前臺(tái)。
③ 一個(gè)進(jìn)程是一個(gè)運(yùn)行著應(yīng)用程序代碼的底層核心過(guò)程。通常所有.apk里的代碼運(yùn)行在一個(gè)專(zhuān)有的進(jìn)程里。不過(guò),進(jìn)程標(biāo)記也可以用來(lái)限定代碼運(yùn)行位置,或者為整個(gè).apk或者為個(gè)別的活動(dòng)activity,接收者receiver,服務(wù)或提供者provider,組件。
任務(wù)
這里的一個(gè)關(guān)鍵點(diǎn)是:當(dāng)用戶(hù)看到一個(gè)“應(yīng)用”時(shí),他們實(shí)際上在和任務(wù)打交道。如果您剛剛創(chuàng)建一個(gè)包含若干活動(dòng)的.apk,其中之一是頂層入口點(diǎn)(通過(guò)動(dòng)作android.intent.action.MAIN的意圖過(guò)濾器intent-filter和類(lèi)別android.intent.category.LAUNCHER),那么這事實(shí)上將為您的.apk創(chuàng)建一個(gè)任務(wù),并且您從那兒起動(dòng)的任何活動(dòng)都將作為那個(gè)任務(wù)的一部分運(yùn)行。
一個(gè)任務(wù),那么,從用戶(hù)的角度來(lái)看是您的應(yīng)用程序;而從應(yīng)用程序開(kāi)發(fā)者的角度來(lái)看,它是一個(gè)或多個(gè)用戶(hù)在那個(gè)任務(wù)中已經(jīng)經(jīng)歷過(guò)且未關(guān)閉的活動(dòng),或者說(shuō)是一個(gè)活動(dòng)棧。一個(gè)新的任務(wù)通過(guò)以Intent.FLAG_ACTIVITY_NEW_TASK標(biāo)志起動(dòng)一個(gè)活動(dòng)意圖來(lái)創(chuàng)建;這一意圖將被用來(lái)作為任務(wù)的根意圖,定義任務(wù)是什么。任何不以這個(gè)標(biāo)志起動(dòng)的活動(dòng)將和起動(dòng)它的活動(dòng)在相同的任務(wù)中運(yùn)行(除非該活動(dòng)已請(qǐng)求特別啟動(dòng)模式,稍后會(huì)討論)。任務(wù)可以被重新安排:如果您使用FLAG_ACTIVITY_NEW_TASK標(biāo)志但已經(jīng)有一個(gè)任務(wù)以這個(gè)意圖運(yùn)行,則當(dāng)前任務(wù)的活動(dòng)棧將被切換到前臺(tái)而不是開(kāi)始一個(gè)新的任務(wù)。
FLAG_ACTIVITY_NEW_TASK必 須謹(jǐn)慎使用:使用它意味著,在用戶(hù)看來(lái),一個(gè)新的應(yīng)用程序由此起動(dòng)。如果這不是你所期望的行為,你就不該去創(chuàng)建一個(gè)新的任務(wù)。另外,僅在用戶(hù)可以從桌面返 回到他原來(lái)的地方和以一個(gè)新任務(wù)啟動(dòng)相同意圖的情況下,你才應(yīng)該使用新的任務(wù)標(biāo)記。否則,如果用戶(hù)在你已經(jīng)啟動(dòng)的任務(wù)里按桌面(HOME)鍵,而不是返回(BACK)鍵,你的任務(wù)及其活動(dòng)將被放置到桌面后面,沒(méi)有辦法再切換回去。
任務(wù)共用性Affinity
在某些情況下,Android需要知道一個(gè)活動(dòng)屬于哪個(gè)任務(wù)即使它沒(méi)有被啟動(dòng)到一個(gè)具體的任務(wù)里。這是通過(guò)任務(wù)共用性(Affinities)完成的。任務(wù)共用性(Affinities)為這個(gè)運(yùn)行一個(gè)或多個(gè)活動(dòng)的任務(wù)提供了一個(gè)獨(dú)特的靜態(tài)名稱(chēng),默認(rèn)的一個(gè)活動(dòng)的任務(wù)共用性(Affinity)是實(shí)現(xiàn)了該活動(dòng)的.apk包的名字。這提供了預(yù)期的標(biāo)準(zhǔn)特性,即所有在一個(gè)特定的.apk包里的活動(dòng)是單個(gè)用戶(hù)應(yīng)用程序的一部分。
當(dāng)開(kāi)始一個(gè)沒(méi)有Intent.FLAG_ACTIVITY_NEW_TASK標(biāo)志的活動(dòng)時(shí),任務(wù)共用性affinities不會(huì)影響將會(huì)運(yùn)行該新活動(dòng)的任務(wù):它總是運(yùn)行在啟動(dòng)它的任務(wù)里。但是,如果使用了NEW_TASK標(biāo)志,那么共用性(affinity)將被用來(lái)判斷是否已經(jīng)存在一個(gè)有相同共用性(affinity)的任務(wù)。如果是這樣,這項(xiàng)任務(wù)將被切換到前面而新的活動(dòng)會(huì)啟動(dòng)于這個(gè)任務(wù)的頂層。
這種特性在您必須使用NEW_TASK標(biāo)志的情況下最有用,尤其是從狀態(tài)欄通知或桌面快捷方式啟動(dòng)活動(dòng)時(shí)。結(jié)果是,當(dāng)用戶(hù)用這種方式啟動(dòng)您的應(yīng)用程序時(shí),它的當(dāng)前任務(wù)將被切換到前臺(tái),而且想要查看的活動(dòng)被放在最上面。
你可以在程序清單(Manifest)文件的應(yīng)用程序application標(biāo)簽中為.apk包中所有的活動(dòng)分配你自己的任務(wù)共用性Affinites,或者在活動(dòng)標(biāo)記中為各個(gè)活動(dòng)進(jìn)行分配。一些說(shuō)明其如何使用的例子如下:
① 如果您的.apk包含多個(gè)用戶(hù)可以啟動(dòng)的高層應(yīng)用程序,那么您可能需要對(duì)用戶(hù)看到的每個(gè)活動(dòng)指定不同的affinities。一個(gè)不錯(cuò)的命名慣例是以附加一個(gè)以冒號(hào)分隔的字符串來(lái)擴(kuò)展您的.apk包名。例如,“ com.android.contacts ”.apk可以有affinities:“com.android.contacts:Dialer”和“ com.android.contacts:ContactsList”。
② 如果您正在替換一個(gè)通知,快捷方式,或其他可以從外部發(fā)起的應(yīng)用程序的“內(nèi)部”活動(dòng),你可能需要明確設(shè)定您替代活動(dòng)的taskAffinity和您準(zhǔn)備替代的應(yīng)用程序一樣。例如,如果您想替換contacts詳細(xì)信息視圖(用戶(hù)可以創(chuàng)建并調(diào)用快捷方式),你得把taskAffinity設(shè)置成“com.android.contacts”。
啟動(dòng)模式和啟動(dòng)標(biāo)志
您控制活動(dòng)和任務(wù)交互的主要途徑是通過(guò)活動(dòng)的launchMode 屬性和意圖相關(guān)的標(biāo)志flags。這兩個(gè)參數(shù)可以以各種方式合作來(lái)控制活動(dòng)啟動(dòng)的結(jié)果,正如它們相關(guān)文檔中描述的那樣。在這里,我們將看看一些常見(jiàn)的用例和參數(shù)組合。
你將使用的最常見(jiàn)的啟動(dòng)模式(除了默認(rèn)的standard模式)是singleTop。這并不影響任務(wù);它只是避免多次在一個(gè)堆棧頂部起動(dòng)同一活動(dòng)。
singleTask啟動(dòng)模式對(duì)任務(wù)有重大的影響:它使活動(dòng)始終是開(kāi)始于一項(xiàng)新的任務(wù)(或其現(xiàn)有的任務(wù)被帶到前臺(tái)) 。使用這種模式需要謹(jǐn)慎對(duì)待你如何與系統(tǒng)其他部分進(jìn)行交互,因?yàn)檫@影響到這個(gè)活動(dòng)中的每一個(gè)路徑。它應(yīng)當(dāng)僅在活動(dòng)處于應(yīng)用程序前臺(tái)時(shí)使用(也就是支持MAIN動(dòng)作和LAUNCHER類(lèi)別)。
singleInstance啟動(dòng)模式更是專(zhuān)業(yè),并應(yīng)僅用于整個(gè)就是被實(shí)現(xiàn)為一個(gè)活動(dòng)的應(yīng)用程序中。
有一種你會(huì)經(jīng)常遇到的情況是當(dāng)另一個(gè)實(shí)體(如SearchManager 或NotificationManager)開(kāi)始您的一個(gè)活動(dòng)。在這種情況下,必須使用Intent.FLAG_ACTIVITY_NEW_TASK 標(biāo)簽,因?yàn)樵擁?xiàng)活動(dòng)是在任務(wù)之外起動(dòng)的(而且應(yīng)用/任務(wù)可能根本不存在)。正如前面所述,這種情況下的標(biāo)準(zhǔn)行為是把匹配新活動(dòng)affinity的任務(wù)帶到前臺(tái)和在此之上起動(dòng)新的活動(dòng)。不過(guò),也有其他您可以實(shí)施的行為類(lèi)型。
一種通常的辦法是和NEW_TASK聯(lián)合起來(lái)使用Intent.FLAG_ACTIVITY_CLEAR_TOP標(biāo)志。這樣,如果您的任務(wù)已經(jīng)運(yùn)行,那么它將會(huì)被帶到前臺(tái),除根活動(dòng)外其它所有堆棧中的活動(dòng)都被清除,而且這個(gè)根活動(dòng)的方法onNewIntent(Intent)會(huì)在該意圖起動(dòng)時(shí)被調(diào)用。注意這個(gè)活動(dòng)使用這個(gè)方法時(shí)經(jīng)常使用singleTop或者singleTask起動(dòng)模式,這樣當(dāng)前實(shí)例被賦予新的意圖而不是需要銷(xiāo)毀它然后重新起動(dòng)一個(gè)新的實(shí)例。
您能采取的另外的方法是設(shè)置通知活動(dòng)的任務(wù)affinity為空字符串“”(表示沒(méi)有affinity),并設(shè)置finishOnBackground屬性。這種方法是有用的如果你希望這個(gè)通知把用戶(hù)帶到一個(gè)單獨(dú)的描述它的活動(dòng)中,而不是返回到應(yīng)用程序的任務(wù)。通過(guò)指定這個(gè)屬性,該活動(dòng)將被結(jié)束不管用戶(hù)通過(guò)BACK還是HOME離開(kāi)它;如果這個(gè)屬性沒(méi)有指定,按首頁(yè)將導(dǎo)致這個(gè)活動(dòng)及其任務(wù)仍保留在系統(tǒng)里,且可能沒(méi)有辦法返回它。
請(qǐng)務(wù)必閱讀關(guān)于launchMode屬性和Intent標(biāo)志的文檔以獲取這些選項(xiàng)的詳細(xì)說(shuō)明。
進(jìn)程
在Android里,進(jìn)程完全是應(yīng)用的實(shí)現(xiàn)細(xì)節(jié),而不是用戶(hù)通常了解的那樣。其主要用途就是:
① 通過(guò)安置不受信任的或不穩(wěn)定的代碼到另一個(gè)進(jìn)程來(lái)提高穩(wěn)定性或安全性。
② 通過(guò)在同一進(jìn)程里運(yùn)行多個(gè).apks的代碼來(lái)減少開(kāi)銷(xiāo)。
③ 通過(guò)把重量級(jí)代碼放在單獨(dú)的進(jìn)程中來(lái)幫助系統(tǒng)管理資源,該進(jìn)程可以在不影響應(yīng)用程序其他部分的情況下被終止。
正如前面所述,這個(gè)進(jìn)程屬性用來(lái)控制運(yùn)行著特定應(yīng)用程序組件的進(jìn)程,注意,此屬性不能用于違反系統(tǒng)安全性:如果有兩個(gè)不共享相同用戶(hù)ID的.apks嘗試運(yùn)行在同一進(jìn)程中,這將不會(huì)被允許,相反會(huì)為它們每一個(gè)創(chuàng)建不同的進(jìn)程。
參見(jiàn)安全文檔以獲取更多關(guān)于安全限制方面的信息。
線程
每個(gè)進(jìn)程包含一個(gè)或多個(gè)線程。多數(shù)情況下,Android避免在進(jìn)程里創(chuàng)建額外的線程,以保持應(yīng)用程序單線程,除非它創(chuàng)建自己的線程。一個(gè)重要的結(jié)果就是所有對(duì)活動(dòng)Activity,廣播接收器BroadcastReceiver以及服務(wù)Service實(shí)例的調(diào)用都是由這個(gè)進(jìn)程的主線程創(chuàng)建的。
注意新的線程并不會(huì)為每個(gè)活動(dòng),廣播接收器,服務(wù)或者內(nèi)容提供器(ContentProvider) 實(shí)例而創(chuàng)建:這些應(yīng)用程序的組件在進(jìn)程里被實(shí)例化(除非另有說(shuō)明,都在同一個(gè)進(jìn)程處理),實(shí)際上是進(jìn)程的主線程。這說(shuō)明當(dāng)被系統(tǒng)調(diào)用時(shí)沒(méi)有哪個(gè)組件(包括 服務(wù))會(huì)進(jìn)行遠(yuǎn)程或者阻塞操作(就像網(wǎng)絡(luò)調(diào)用或者計(jì)算循環(huán)),因?yàn)檫@將阻止進(jìn)程中的所有其他組件。你可以使用標(biāo)準(zhǔn)的線程類(lèi)Thread或者Android的HandlerThread便捷類(lèi)去對(duì)其它線程執(zhí)行遠(yuǎn)程操作。
這里有一些關(guān)于這個(gè)線程規(guī)則的重要的例外:
① 對(duì)IBinder或者IBinder實(shí)現(xiàn)的接口的調(diào)用由調(diào)用線程或本地進(jìn)程的線程池(如果該呼叫來(lái)自其他進(jìn)程)分發(fā),而不是它們的進(jìn)程的主線程。特殊情況下,一個(gè)服務(wù)的IBinder可以這樣調(diào)用。(盡管調(diào)用服務(wù)里的方法已經(jīng)在主線程里完成。)這意味著IBinder接口的實(shí)現(xiàn)必須要有一種線程安全的方法,這樣任意線程才能同時(shí)訪問(wèn)它。
② 對(duì)ContentProvider主要方法的調(diào)用由調(diào)用線程或者主線程分發(fā),如同IBinder一樣。被指定的方法在內(nèi)容提供器的類(lèi)里有記錄。這意味著實(shí)現(xiàn)這些方法必須要有一種線程安全的模式,這樣任意其它線程可以同時(shí)訪問(wèn)它。
③ 視圖及其子類(lèi)中的調(diào)用由正在運(yùn)行著視圖的線程產(chǎn)生。通常情況下,這會(huì)被作為進(jìn)程的主線程,如果你創(chuàng)建一個(gè)線程并顯示一個(gè)窗口,那么繼承的窗口視圖將從那個(gè)線程里啟動(dòng)。
希望本文所述對(duì)大家Android程序設(shè)計(jì)有所幫助。
相關(guān)文章
Android實(shí)現(xiàn)簡(jiǎn)易版彈鋼琴效果
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)簡(jiǎn)易版彈鋼琴效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-05-05
Android下拉刷新SwipeRefreshLayout控件使用方法
這篇文章主要介紹了Android下拉刷新SwipeRefreshLayout控件使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11
Android使用Handler實(shí)現(xiàn)倒計(jì)時(shí)功能
這篇文章主要為大家詳細(xì)介紹了Android使用Handler實(shí)現(xiàn)倒計(jì)時(shí)功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-06-06
android 監(jiān)聽(tīng)SD卡文件變化的實(shí)現(xiàn)代碼
這篇文章主要介紹了android 監(jiān)聽(tīng)SD卡文件變化的實(shí)現(xiàn)代碼,需要的朋友可以參考下2017-11-11
Android動(dòng)態(tài)替換Application實(shí)現(xiàn)
這篇文章主要介紹了Android動(dòng)態(tài)替換Application實(shí)現(xiàn),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-05-05
Android自定義View實(shí)現(xiàn)仿網(wǎng)易音樂(lè)唱片播放效果
這篇文章主要為大家詳細(xì)介紹了Android自定義View實(shí)現(xiàn)仿網(wǎng)易音樂(lè)唱片播放效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-04-04
Android 修改Preferences默認(rèn)樣式的步驟
這篇文章主要介紹了Android 修改Preferences默認(rèn)樣式的步驟,幫助大家更好的理解和學(xué)習(xí)使用Android開(kāi)發(fā),感興趣的朋友可以了解下2021-04-04

