Android關於Task的一些實踐之SingleTask, SingleInstance和TaskAffinity
阿新 • • 發佈:2017-05-24
conda tag 我們 創建 真理 enter 設置 com lms
順序打開三個Activity,看看結果:
能夠看到三個Activity,都是在同個Task中的。
再來看看其結果,例如以下:
發現盡管定義了SingleTask,但Second Activity和Main Activity還是在同一個Task中。這跟我們期望的不符。原因事實上在於,設置了launchMode = SingleTask啟動的Activity,在啟動的時候,會去查找跟它的taskAffinity同樣的task,假設存在這樣一個task,就在這個task中啟動,假設不存在這樣一個task,才創建一個新的task,並在新task中啟動。
以下是結果,啟動的順序是Main Activity->Second Activity->Main Activity -> Second Activity -> Third Activity
在上面的結果中,能夠看到在啟動Second Activity的時候,的確是在一個新的Task中啟動了。Second Activity是這個Task中的根Activity。而由Second Activity啟動的Third Activity也是在這個Task中啟動的。
以下是結果:
以下來看看結果,例如以下:
果然。如我們期望的那樣,都是在一個新的Task中啟動當前的Activity的。
結束。
上一篇文章粗略地介紹了一下關於Android中Task的基本知識。只是實踐才是檢驗真理的唯一標準,所以。今天就來試驗一下Task中的launchMode是否真的實現了文檔所說的那樣。
首先。定義三個Activity。MainActivity打開SecondActivity,SecondActivity打開ThirdActivity,例如以下所看到的:
以下。我們定義Second Activity的Launch Mode。分別有以下幾種情況:
1)Standard(即不定義)
首先是默認情況下。什麽都不定義。例如以下:<application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.lms.taskdemo.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.lms.taskdemo.SecondActivity"> </activity> <activity android:name="com.lms.taskdemo.ThirdActivity" > </activity> </application>
04-21 15:23:28.373: V/com.lms.taskdemo(20473): Task : 70 04-21 15:23:28.373: V/com.lms.taskdemo(20473): Base activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.MainActivity} 04-21 15:23:28.373: V/com.lms.taskdemo(20473): Current activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.MainActivity} 04-21 15:23:28.373: V/com.lms.taskdemo(20473): Number of activities : 1 04-21 15:23:28.373: V/com.lms.taskdemo(20473): Number of running activities: 1 04-21 15:23:31.336: V/com.lms.taskdemo(20473): Task : 70 04-21 15:23:31.336: V/com.lms.taskdemo(20473): Base activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.MainActivity} 04-21 15:23:31.336: V/com.lms.taskdemo(20473): Current activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.SecondActivity} 04-21 15:23:31.336: V/com.lms.taskdemo(20473): Number of activities : 2 04-21 15:23:31.336: V/com.lms.taskdemo(20473): Number of running activities: 2 04-21 15:23:33.999: V/com.lms.taskdemo(20473): Task : 70 04-21 15:23:33.999: V/com.lms.taskdemo(20473): Base activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.MainActivity} 04-21 15:23:33.999: V/com.lms.taskdemo(20473): Current activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.ThirdActivity} 04-21 15:23:33.999: V/com.lms.taskdemo(20473): Number of activities : 3 04-21 15:23:33.999: V/com.lms.taskdemo(20473): Number of running activities: 3
能夠看到三個Activity,都是在同個Task中的。
2)SingleTask
為Second Activity,定義其launch mode 為 “singleTask”。例如以下:
<application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.lms.taskdemo.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.lms.taskdemo.SecondActivity" android:launchMode="singleTask"> </activity> <activity android:name="com.lms.taskdemo.ThirdActivity" > </activity> </application>
再來看看其結果,例如以下:
04-22 10:31:26.197: V/com.lms.taskdemo(924): Task : 162 04-22 10:31:26.217: V/com.lms.taskdemo(924): Base activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.MainActivity} 04-22 10:31:26.217: V/com.lms.taskdemo(924): Current activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.MainActivity} 04-22 10:31:26.217: V/com.lms.taskdemo(924): Number of activities : 1 04-22 10:31:26.217: V/com.lms.taskdemo(924): Number of running activities: 1 04-22 10:31:31.112: V/com.lms.taskdemo(924): Task : 162 04-22 10:31:31.112: V/com.lms.taskdemo(924): Base activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.MainActivity} 04-22 10:31:31.112: V/com.lms.taskdemo(924): Current activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.SecondActivity} 04-22 10:31:31.112: V/com.lms.taskdemo(924): Number of activities : 2 04-22 10:31:31.112: V/com.lms.taskdemo(924): Number of running activities: 2 04-22 10:31:32.884: V/com.lms.taskdemo(924): Task : 162 04-22 10:31:32.884: V/com.lms.taskdemo(924): Base activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.MainActivity} 04-22 10:31:32.884: V/com.lms.taskdemo(924): Current activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.ThirdActivity} 04-22 10:31:32.884: V/com.lms.taskdemo(924): Number of activities : 3 04-22 10:31:32.884: V/com.lms.taskdemo(924): Number of running activities: 2
發現盡管定義了SingleTask,但Second Activity和Main Activity還是在同一個Task中。這跟我們期望的不符。原因事實上在於,設置了launchMode = SingleTask啟動的Activity,在啟動的時候,會去查找跟它的taskAffinity同樣的task,假設存在這樣一個task,就在這個task中啟動,假設不存在這樣一個task,才創建一個新的task,並在新task中啟動。
而在這裏,由於沒有為各個activity定義taskAffinity,那麽默認的affinity值就是包名,那麽幾個Activity都是一樣的,所以就在相同的Task中啟動了。
3)Single Task Different Task Affinity
以下。我們分別為Main Activity和 Second Activity設置不同的TaskAffinity值,例如以下:
<application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.lms.taskdemo.MainActivity" android:label="@string/app_name" android:taskAffinity="com.lms.taskdemo.MainActivity" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.lms.taskdemo.SecondActivity" android:launchMode="singleTask" android:taskAffinity="com.lms.taskdemo.SecondActivity" > </activity> <activity android:name="com.lms.taskdemo.ThirdActivity" > </activity> </application>
以下是結果,啟動的順序是Main Activity->Second Activity->Main Activity -> Second Activity -> Third Activity
04-22 10:26:27.818: V/com.lms.taskdemo(32677): Task : 151 04-22 10:26:27.818: V/com.lms.taskdemo(32677): Base activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.MainActivity} 04-22 10:26:27.818: V/com.lms.taskdemo(32677): Current activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.MainActivity} 04-22 10:26:27.818: V/com.lms.taskdemo(32677): Number of activities : 1 04-22 10:26:27.818: V/com.lms.taskdemo(32677): Number of running activities: 1 04-22 10:26:31.362: V/com.lms.taskdemo(32677): Task : 152 04-22 10:26:31.362: V/com.lms.taskdemo(32677): Base activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.SecondActivity} 04-22 10:26:31.362: V/com.lms.taskdemo(32677): Current activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.SecondActivity} 04-22 10:26:31.372: V/com.lms.taskdemo(32677): Number of activities : 1 04-22 10:26:31.372: V/com.lms.taskdemo(32677): Number of running activities: 1 04-22 10:26:36.558: V/com.lms.taskdemo(32677): Task : 151 04-22 10:26:36.558: V/com.lms.taskdemo(32677): Base activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.MainActivity} 04-22 10:26:36.558: V/com.lms.taskdemo(32677): Current activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.MainActivity} 04-22 10:26:36.558: V/com.lms.taskdemo(32677): Number of activities : 1 04-22 10:26:36.558: V/com.lms.taskdemo(32677): Number of running activities: 1 04-22 10:26:39.401: V/com.lms.taskdemo(32677): Task : 153 04-22 10:26:39.401: V/com.lms.taskdemo(32677): Base activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.SecondActivity} 04-22 10:26:39.401: V/com.lms.taskdemo(32677): Current activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.SecondActivity} 04-22 10:26:39.401: V/com.lms.taskdemo(32677): Number of activities : 1 04-22 10:26:39.401: V/com.lms.taskdemo(32677): Number of running activities: 1 04-22 10:26:41.123: V/com.lms.taskdemo(32677): Task : 153 04-22 10:26:41.123: V/com.lms.taskdemo(32677): Base activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.SecondActivity} 04-22 10:26:41.123: V/com.lms.taskdemo(32677): Current activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.ThirdActivity} 04-22 10:26:41.123: V/com.lms.taskdemo(32677): Number of activities : 2 04-22 10:26:41.123: V/com.lms.taskdemo(32677): Number of running activities: 2
在上面的結果中,能夠看到在啟動Second Activity的時候,的確是在一個新的Task中啟動了。Second Activity是這個Task中的根Activity。而由Second Activity啟動的Third Activity也是在這個Task中啟動的。
4)Single Instance
以下,我們再來看看Single Instance,相同的,先不定義Task Affinity。在AndroidManifest文件裏定義例如以下:<application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.lms.taskdemo.MainActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.lms.taskdemo.SecondActivity" android:launchMode="singleInstance"> </activity> <activity android:name="com.lms.taskdemo.ThirdActivity" > </activity> </application>
以下是結果:
04-22 10:29:43.207: V/com.lms.taskdemo(682): Task : 159 04-22 10:29:43.207: V/com.lms.taskdemo(682): Base activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.MainActivity} 04-22 10:29:43.207: V/com.lms.taskdemo(682): Current activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.MainActivity} 04-22 10:29:43.207: V/com.lms.taskdemo(682): Number of activities : 1 04-22 10:29:43.207: V/com.lms.taskdemo(682): Number of running activities: 1 04-22 10:29:46.580: V/com.lms.taskdemo(682): Task : 160 04-22 10:29:46.580: V/com.lms.taskdemo(682): Base activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.SecondActivity} 04-22 10:29:46.580: V/com.lms.taskdemo(682): Current activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.SecondActivity} 04-22 10:29:46.580: V/com.lms.taskdemo(682): Number of activities : 1 04-22 10:29:46.580: V/com.lms.taskdemo(682): Number of running activities: 1 04-22 10:29:48.202: V/com.lms.taskdemo(682): Task : 159 04-22 10:29:48.202: V/com.lms.taskdemo(682): Base activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.MainActivity} 04-22 10:29:48.202: V/com.lms.taskdemo(682): Current activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.ThirdActivity} 04-22 10:29:48.202: V/com.lms.taskdemo(682): Number of activities : 2 04-22 10:29:48.202: V/com.lms.taskdemo(682): Number of running activities: 1 04-22 10:29:57.112: V/com.lms.taskdemo(682): Task : 160 04-22 10:29:57.112: V/com.lms.taskdemo(682): Base activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.SecondActivity} 04-22 10:29:57.112: V/com.lms.taskdemo(682): Current activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.SecondActivity} 04-22 10:29:57.112: V/com.lms.taskdemo(682): Number of activities : 1 04-22 10:29:57.112: V/com.lms.taskdemo(682): Number of running activities: 1能夠看到啟動Second Activity的時候,是在新的Task中,而當啟動Third Activity的時候,它又跑回原來的Task中去了。這是跟文檔描寫敘述中符合的。的確是新建的Task中僅僅能有且僅有一個Activity。
而因為我們未定義Task Affinity,所以當啟動Third Activity的時候。它就會去找同樣Affinity的task,所以就會找到原來的Task。也即是說,假設定義了TaskAffinity的話,那以Third Activity就應該在新的Task中創建了,以下就來驗證一下。
5)Single Instance Different Affinity
在配置文件裏定義例如以下:<application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.lms.taskdemo.MainActivity" android:label="@string/app_name" android:taskAffinity="com.lms.taskdemo.MainActivity" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.lms.taskdemo.SecondActivity" android:launchMode="singleInstance" android:taskAffinity="com.lms.taskdemo.SecondActivity" > </activity> <activity android:name="com.lms.taskdemo.ThirdActivity" > </activity> </application>
以下來看看結果,例如以下:
04-22 10:27:58.866: V/com.lms.taskdemo(391): Task : 155 04-22 10:27:58.866: V/com.lms.taskdemo(391): Base activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.MainActivity} 04-22 10:27:58.866: V/com.lms.taskdemo(391): Current activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.MainActivity} 04-22 10:27:58.866: V/com.lms.taskdemo(391): Number of activities : 1 04-22 10:27:58.866: V/com.lms.taskdemo(391): Number of running activities: 1 04-22 10:28:00.677: V/com.lms.taskdemo(391): Task : 156 04-22 10:28:00.677: V/com.lms.taskdemo(391): Base activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.SecondActivity} 04-22 10:28:00.677: V/com.lms.taskdemo(391): Current activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.SecondActivity} 04-22 10:28:00.677: V/com.lms.taskdemo(391): Number of activities : 1 04-22 10:28:00.677: V/com.lms.taskdemo(391): Number of running activities: 1 04-22 10:28:02.309: V/com.lms.taskdemo(391): Task : 157 04-22 10:28:02.309: V/com.lms.taskdemo(391): Base activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.ThirdActivity} 04-22 10:28:02.309: V/com.lms.taskdemo(391): Current activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.ThirdActivity} 04-22 10:28:02.309: V/com.lms.taskdemo(391): Number of activities : 1 04-22 10:28:02.309: V/com.lms.taskdemo(391): Number of running activities: 1
果然。如我們期望的那樣,都是在一個新的Task中啟動當前的Activity的。
總結:
當使用Launch Mode 來改變系統默認的任務調度的時候。假設是用到Single Task或者Single Instance的時候,還要註意到Affinity的使用,要跟Affinity配合使用。可能才幹達到我們期望中的效果。而Affinity,事實上是Android提供的一個表從屬意義的參數,類似於一個Tag值,它表明當前Activity屬於哪一個Tag,相當的Affinity值的Activity。假設不使用其它的標誌,如Single Instance之類,那麽都會在存在於同一個task中。普通情況下,我們並不定義Task Affinity值。則其默認的值就是當前App的包名。結束。
Android關於Task的一些實踐之SingleTask, SingleInstance和TaskAffinity