在上篇文章中已經介紹了和啓動模式相關的基礎知識,想了解的小夥伴能夠戳下方連接:blog.csdn.net/qq_42171948…android
在對activity四種啓動模式有所理解以後。這篇文章將會繼續解決上篇所留下的問題瀏覽器
1.如何設置不一樣的任務棧?bash
2.當activityA以標準模式啓動B的時候,B的實例被建立且處於activityA任務棧的頂端,那麼這個時候B啓動了A(standard)呢?app
3.這兩種設置方式有什麼區別呢?經常使用的標誌位有好幾個,組合起來使用又有什麼不一樣的效果呢?ide
咱們知道,默認狀況下,全部activity都運行在同一個任務棧中,此棧名爲 元素設置的軟件包名稱。那麼如何設置不一樣的任務棧,很簡單,用taskAffinity。學習
taskAffinity是一個代表activity想在哪一個任務棧的參數。在manifest裏面能夠進行設置。ui
<activity android:name=".MainActivity"
android:taskAffinity="com.example.administrator.test">
複製代碼
<activity android:name=".MainActivity"
android:taskAffinity="com.example.administrator.test">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".MainActivity2"
android:launchMode="singleTask"
android:taskAffinity="com.example.administrator.test1">
</activity>
複製代碼
mainactivity:this
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView show = (TextView) findViewById(R.id.tv_show);
show.setText(this.toString() + "\ntaskId:" + this.getTaskId());
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
Log.e("task", "intent1=" + intent);
}
public void jump(View v) {
Intent intent = new Intent(this,MainActivity2.class);
startActivity(intent);
}
}
複製代碼
mainactivity2:spa
public class MainActivity2 extends AppCompatActivity{
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
TextView show = (TextView) findViewById(R.id.tv_show);
show.setText(this.toString() + "\ntaskId:" + this.getTaskId());
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
Log.e("task","intent2"+intent);
}
}
複製代碼
現象是: .net
當兩個activity的taskAffinity同樣時:
由此能夠得出結論: 以1啓動2來講
(1) 當1和2的taskAffinity相同時:當第一次建立2 的實例時,並不會建立新的task,乃是將在1的task中建立2的實例;當1的task已經存在2的實例時,此時啓動2,則會檢查一下task中是否有2實例,而後將2上的其餘實例出棧,將2實例置於棧頂,從而實現了跳轉。
(2) 當1和2的taskAffinity不一樣時:當第一次建立2 的實例時,將會建立新的task,在指定的task中建立2的實例;當指定task已經存在2的實例時,此時啓動2,則會檢查一下task中是否有2實例,而後將2上的其餘實例出棧,將2實例置於棧頂,從而實現了跳轉。
說了這麼多,其實就是很簡單的一句話,taskAffinity設置新啓動的activity應處於哪一個task,一種是在建立它的activity所處棧,一種是新棧,其餘的分析就是對singleTask的理解而已。
另外,文檔給咱們提供了一種會出現:原本在某一個Task中,以後出現了轉移的狀況。 若是該Activity的allowTaskReparenting屬性設置爲true,當啓動它的任務棧進入後臺,一個和它有相同affinity的Task進入前臺時,該Activity會進入到該前臺的task中。
(如下是翻譯) 例子是,若是電子郵件包含網頁連接,則點擊連接會調出可顯示網頁的 Activity。 該 Activity 由瀏覽器應用定義,但做爲電子郵件任務的一部分啓動。 若是將其父項更改成瀏覽器任務,它會在瀏覽器下一次轉至前臺時顯示,當電子郵件任務再次轉至前臺時則會消失。
個人理解:當一個應用A啓動了應用B的某個ActivityC後(C的taskAffinity 爲B),若是咱們將ActivityC的allowTaskReparenting屬性設置爲true,當應用B被啓動後,系統會發現Activity C所需的任務棧已經存在,ActivityC就會從A的任務棧轉移到B的任務棧中。
(如下仍是翻譯) Activity 的親和關係由 taskAffinity 屬性定義。 任務的親和關係經過讀取其根 Activity 的親和關係來肯定。所以,按照定義,根 Activity 始終位於具備相同親和關係的任務之中。 因爲具備「singleTask」或「singleInstance」啓動模式的 Activity 只能位於任務的根,所以更改父項僅限於「standard」和「singleTop」模式。
個人理解: 每一個task有affinity屬性,等於它的根 Activity的taskAffinity的值。singletask和singleinstance模式下,Atask中只能有一個A實例,且爲根,那麼就不能從新宿主,要否則的話這個棧就崩了呢~而另外兩種的話,由於不是根因此能夠在特定情境下自由遊蕩。(若理解得不對,望小夥伴指正)
因爲篇幅和時間關係,文章就到此結束,剩下的問題待Android初級開發筆記-- Activity啓動模式的學習(3)再進行討論~
- 咱們正在招募小夥伴,有興趣的小夥伴能夠把簡歷發到 app@talkmoney.cn,備註:來自簡書社區
- 詳情能夠戳這裏--> 廣州蘆葦信息科技