標籤:
參考:http://blog.csdn.net/ljz2009y/article/details/26621815
一個應用 三個頁面 第二個版面設定為 singlTask
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.jg.zhang.androidtasktest" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="10" android:targetSdkVersion="17" /> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name"> <activity android:label="@string/app_name" android:name="com.jg.zhang.androidtasktest.MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <!--android:taskAffinity="com.jg.zhang.androidtasktest.second" android:alwaysRetainTaskState="true" android:allowBackup="true" --> <activity android:name="com.jg.zhang.androidtasktest.SecondActivity" android:launchMode="singleTask"> <intent-filter > <action android:name="com.jg.zhang.androidtasktest.SecondActivity"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> </activity> <activity android:name="com.jg.zhang.androidtasktest.ThirdActivity" android:label="@string/app_name" > </activity> </application> </manifest>
在命令列中執行以下命令 adb shell dumpsys activity , 有以下輸出:
TaskRecord{412ded08 #8 A com.jg.zhang.androidtasktest}
Run #2: ActivityRecord{412c91e8 com.jg.zhang.androidtasktest/.SecondActivity}
Run #1: ActivityRecord{412c08a0 com.jg.zhang.androidtasktest/.MainActivity}
且點擊MainActivity介面中的按鈕,開啟SecondActivity。在該樣本中SecondActivity的啟動模式為singleTask。按照官方文檔的說法,SecondActivity會在一個新的任務中開啟。但是查看列印出的log,發現MainActivity和SecondActivity所在的任務的Id相同。
所以,和官方文檔表述的不同,MainActivity和SecondActivity是啟動在同一個任務中的。其實,把啟動模式設定為singleTask,framework在啟動該activity時只會把它標示為可在一個新任務中啟動,至於是否在一個新任務中啟動,還要受其他條件的限制。現在在SecondActivity增加一個taskAffinity屬性
<activity android:name="com.jg.zhang.androidtasktest.SecondActivity" android:launchMode="singleTask" android:taskAffinity="com.jg.zhang.androidtasktest.second"> <intent-filter > <action android:name="com.jg.zhang.androidtasktest.SecondActivity"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> lt;/activity>
重新運行該樣本
在命令列中執行adb shell dumpsys activity命令,有以下輸出:
TaskRecord{411e6a88 #6 A com.jg.zhang.androidtasktest.second}
Run #3: ActivityRecord{411c8ea0 com.jg.zhang.androidtasktest/.ThirdActivity}
Run #2: ActivityRecord{412bc870 com.jg.zhang.androidtasktest/.SecondActivity}
TaskRecord{412ece18 #5 A com.jg.zhang.androidtasktest}
Run #1: ActivityRecord{412924c0 com.jg.zhang.androidtasktest/.MainActivity}
由此可見,MainActivity和SecondActivity運行在不同的任務中了,並且被SecondActivity啟動的ThirdActivity和SecondActivity運行在同一個任務中。
taskAffinity可以影響當activity以FLAG_ACTIVITY_NEW_TASK標誌啟動時,它會被啟動到哪個任務中。這句話的意思是,當新啟動的activity(SecondActivity)是以FLAG_ACTIVITY_NEW_TASK標誌啟動時(可以認為FLAG_ACTIVITY_NEW_TASK和singleTask作用相同,當啟動模式為singleTask時,framework會將它的啟動標誌設為FLAG_ACTIVITY_NEW_TASK),framework會檢索是否已經存在了一個affinity為com.jg.zhang.androidtasktest.second的任務(即一個TaskRecord對象)
- 如果存在這樣的一個任務,則檢查在這個任務中是否已經有了一個SecondActivity的執行個體,
- 如果已經存在一個SecondActivity的執行個體,則會重用這個任務和任務中的SecondActivity執行個體,將這個任務調到前台,清除位於SecondActivity上面的所有Activity,顯示SecondActivity,並調用SecondActivity的onNewIntent();
- 如果不存在一個SecondActivity的執行個體,會在這個任務中建立SecondActivity的執行個體,並調用onCreate()方法
- 如果不存在這樣的一個任務,會建立一個新的affinity為com.jg.zhang.androidtasktest.second的任務,並且將SecondActivity啟動到這個新的任務中
上面討論的是設定taskAffinity屬性的情況,如果SecondActivity只設定啟動模式為singleTask,而不設定taskAffinity,即三個Activity的taskAffinity相同,都為應用的包名,那麼SecondActivity是不會開啟一個新任務的,framework中的判定過程如下:
- 在MainActivity啟動SecondActivity時,發現啟動模式為singleTask,那麼設定他的啟動標誌為FLAG_ACTIVITY_NEW_TASK
- 然後獲得SecondActivity的taskAffinity,即為包名com.jg.zhang.androidtasktest
- 檢查是否已經存在一個affinity為com.jg.zhang.androidtasktest的任務,這個任務是存在的,就是MainActivity所在的任務,這個任務是在啟動MainActivity時開啟的
- 既然已經存在這個任務,就檢索在這個任務中是否存在一個SecondActivity的執行個體,發現不存在
- 在這個已有的任務中啟動一個SecondActivity的執行個體
為了作一個清楚的比較,列出SecondActivity啟動模式設為singleTask,並且taskAffinity設為com.jg.zhang.androidtasktest.second時的啟動過程
- 在MainActivity啟動SecondActivity時,發現啟動模式為singleTask,那麼設定他的啟動標誌為FLAG_ACTIVITY_NEW_TASK
- 然後獲得SecondActivity的taskAffinity,即com.jg.zhang.androidtasktest.second
- 檢查是否已經存在一個affinity為com.jg.zhang.androidtasktest.second的任務,這個任務是不存在的
- 建立一個新的affinity為com.jg.zhang.androidtasktest.second的任務,並且將SecondActivity啟動到這個新的任務中
android Activity launch mode 一個執行個體