Activity啓動模式--《Android開發藝術探索》閱讀筆記--第一章part2

版權聲明:本文爲博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/hfy8971613/article/details/79683137

一、LaunchMode

預備知識:任務棧(回退棧),後進先出

1.standard(標準模式):默認啓動模式,每創建一個新Activity,都會產生一個新的Activity實例並且放入相應的任務棧中。和典型的棧調用數據類似沒多大區別。

2.singleTop(棧頂複用模式):如果要新建的Activity本身已經有一個Activity實例位於棧頂時,那麼這個Activity不會被重新創建,而是會回調onNewIntent方法取出當前請求的信息,而這個新建的Activity不會被系統調用onCreate、onStart方法。注意的是,該模式只使用於新Activity已經位於棧頂。否則的話還是會創建新的Activity並且進行壓棧操作。

3.singTask(棧內複用模式):只要Activity在想要的任務棧中存在,會將棧內存在的Activity做置頂操作(由於“後進先出”,會clear top)。而如果在棧內不存在時,會直接創建並壓棧。具體一點,想要的任務棧如果不存在,則創建一個任務棧然後創建實例入棧;如果想要的任務棧存在,則看是否存在實例,若存在則clearTop且onNewIntent,不存在則創建實例入棧。

4.singleInstance(單實例模式):加強的singleTask模式,除了具有singTask的一切特性外,還加強了一點,就是具有此模式的Activity只能單獨的位於一個任務棧中。也就是說,在它啓動的時候,系統會爲它分配一個新的任務棧。由於singleTask的複用性,在其他需要創建Activity的時候,都不會創建新的Activity。

擴展:TaskAffinity(Activity想要的任務棧

每個Activity都會有TaskAffinity參數,標識了Activity所需要進入的任務棧的名字。默認是包名,也就是當前應用下的任務棧。兩種情況(其他情況沒有意義):

1.當TaskAffinity和singleTask啓動模式配對使用的時候:singleTask的activity會運行在TaskAffinity指定名字的任務棧中。

2.當TaskAffinity與allowTaskReparenting結合的時候:在這種情況下,如果該Activity的allowTaskReparenting設置爲true的時候,這個Activity會直接進入後臺,直到當和TaskAffinity名字相同的任務棧進入前臺的時候,此時的Activity會轉移到該任務棧中並處於棧頂位置。 書中例子:先有應用A、B。當在A中啓動B的一個ActivityC,然後按Home鍵回到桌面,打開B應用。此時你會發現顯示出來的是ActivityC。

用法<application android:allowTaskReparnting="true/false"></application>:是否允許activity更換從屬的任務,比如從短信息任務 切換到瀏覽器任務。用來標記Activity能否從啓動的Task移動到有着affinity的Task(當這個Task進入到前臺時)——“true”,表示能移動,“false”,表示它必須呆在啓動時呆在的那個Task裏。
        如果這個特性沒有被設定,設定到<application>元素上的allowTaskReparenting特性的值會應用到Activity上。默認值爲“false”。
       一般來說,當Activity啓動後,它就與啓動它的Task關聯,並且在那裏耗盡它的整個生命週期。噹噹前的Task不再顯示時,你可以使用這個特性來強制Activity移動到有着affinity的Task中。典型用法是:把一個應用程序的Activity移到另一個應用程序的主Task中。
       例如,如果e-mail中包含一個web頁的鏈接,點擊它就會啓動一個Activity來顯示這個頁面。這個Activity是由Browser應用程序定義的,但是,現在它作爲e-mail Task的一部分。如果它重新宿主到Browser Task裏,當Browser下一次進入到前臺時,它就能被看見,並且,當e-mail Task再次進入前臺時,就看不到它了。
       Actvity的affinity是由taskAffinity特性定義的。Task的affinity是通過讀取根Activity的affinity 決定。因此,根據定義,根Activity總是位於相同affinity的Task裏。由於啓動模式爲“singleTask”和 “singleInstance”的Activity只能位於Task的底部,因此,重新宿主只能限於“standard”和“singleTop”模式。

注:在Intent中設置標誌位來指定啓動模式 比 通過AndroidMenifest.xml爲Activity指定啓動模式 優先級高。


二、IntentFilter匹配規則(隱式啓動)

IntentFilter的過濾信息包括三種:action、category、data。一個Activity可以設定多個IntentFilter,只要有其中一組IntentFilter完全匹配,可以開啓該Activity。

action的匹配規則

action的本質是一個字符串,其作用是描述Intent所觸發的動作的名稱。在IntentFilter中,我們可以定義多個action,只要有一個action和Intent傳遞的信息匹配,那麼就算配合成功。注意的是,系統本身預定義了一些action,代表可啓動的一些預定義的Activity,比如撥號界面等這些預定義的action集中放在android.intent.action下,調用的時候從裏面選取,比如Intent.ACTION_CALL

category匹配規則

category和action的本質是一致的,但代表的意義不同,category描述的是目標組件的類別信息,表明這個目標可以幹些什麼。當然,我們也可以給它進行自定義的設置。 而關於category的匹配規則,大致如下:如果Intent中含有category,那麼不管你有幾個,都需要和目標Activity在IntentFilter中設定的category匹配。

data的組成

data由兩部分組成:mimeTypeURI。其中,mimeType指的媒體類型,可以表示圖片image/jpeg,文本text/html ,音頻audio/mpeg4-generic 和視頻video/*等。而URI表示統一資源標識符(Uniform Resource Identifier),用以制定所需資源的存儲路徑。其結構如下:

<scheme>://<host>:<port>:/[<path>|<pathPrefix>|<pathfrefix>]

結構說明如下:
scheme:URI的模式,比如http、file等
host:URI的主機名,即當前資源所在的主機的IP地址,可以用域名錶示,如www.baidu.com
port:URI的端口號,比如80,指獲得資源的窗口路徑。
path、pathPrefix、pathPattern:表示路徑信息

data匹配規則與action類似。


補充:在隱式啓動時,可以先判斷是否有activity能匹配我們的隱式Intent,方法如下:

Intent intent = new Intent();
intent.setAction("com.hfy.test.action");Intent.ACTION_CALL
intent.setDataAndType(Uri.parse("hfy://www.hfy.com"),"text/plain");
intent.addCategory(CATEGORY_DEFAULT);

ComponentName componentName = intent.resolveActivity(getPackageManager());
if (componentName != null) {
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(intent);
}


另外,



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章