在上篇文章中已經(jīng)介紹了和啟動(dòng)模式相關(guān)的基礎(chǔ)知識(shí),想了解的小伙伴可以戳下方鏈接:https://blog.csdn.net/qq_42171948/article/details/90168514
在對(duì)activity四種啟動(dòng)模式有所理解之后。這篇文章將會(huì)繼續(xù)解決上篇所留下的問(wèn)題
1.如何設(shè)置不同的任務(wù)棧?
2.當(dāng)activityA以標(biāo)準(zhǔn)模式啟動(dòng)B的時(shí)候,B的實(shí)例被創(chuàng)建且處于activityA任務(wù)棧的頂端,那么這個(gè)時(shí)候B啟動(dòng)了A(standard)呢?
3.這兩種設(shè)置方式有什么區(qū)別呢?常用的標(biāo)志位有好幾個(gè),組合起來(lái)使用又有什么不同的效果呢?
我們知道,默認(rèn)情況下,所有activity都運(yùn)行在同一個(gè)任務(wù)棧中,此棧名為<manifest> 元素設(shè)置的軟件包名稱(chēng)。那么如何設(shè)置不同的任務(wù)棧,很簡(jiǎn)單,用taskAffinity。
taskAffinity
taskAffinity是一個(gè)表明activity想在哪個(gè)任務(wù)棧的參數(shù)。在manifest里面可以進(jìn)行設(shè)置。
<activity android:name=".MainActivity"
android:taskAffinity="com.example.administrator.test">
- 每個(gè)Activity都有taskAffinity屬性,這個(gè)屬性指出了它希望進(jìn)入的Task。默認(rèn)是包名。
- 每個(gè)task有affinity屬性,等于它的根 Activity的taskAffinity的值。
- 在不設(shè)置其他的前提下,經(jīng)檢驗(yàn),只有在singleTask,和singleInstance模式中,taskAffinity才會(huì)起到應(yīng)有的作用。
貼上代碼:
當(dāng)兩個(gè)activity的taskAffinity不一樣時(shí):
manifest:
<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:
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:
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);
}
}
現(xiàn)象是:


當(dāng)兩個(gè)activity的taskAffinity一樣時(shí):


由此可以得出結(jié)論:
以1啟動(dòng)2來(lái)說(shuō)
(1) 當(dāng)1和2的taskAffinity相同時(shí):當(dāng)?shù)谝淮蝿?chuàng)建2 的實(shí)例時(shí),并不會(huì)創(chuàng)建新的task,乃是將在1的task中創(chuàng)建2的實(shí)例;當(dāng)1的task已經(jīng)存在2的實(shí)例時(shí),此時(shí)啟動(dòng)2,則會(huì)檢查一下task中是否有2實(shí)例,然后將2上的其他實(shí)例出棧,將2實(shí)例置于棧頂,從而實(shí)現(xiàn)了跳轉(zhuǎn)。
(2) 當(dāng)1和2的taskAffinity不同時(shí):當(dāng)?shù)谝淮蝿?chuàng)建2 的實(shí)例時(shí),將會(huì)創(chuàng)建新的task,在指定的task中創(chuàng)建2的實(shí)例;當(dāng)指定task已經(jīng)存在2的實(shí)例時(shí),此時(shí)啟動(dòng)2,則會(huì)檢查一下task中是否有2實(shí)例,然后將2上的其他實(shí)例出棧,將2實(shí)例置于棧頂,從而實(shí)現(xiàn)了跳轉(zhuǎn)。
說(shuō)了這么多,其實(shí)就是很簡(jiǎn)單的一句話,taskAffinity設(shè)置新啟動(dòng)的activity應(yīng)處于哪個(gè)task,一種是在創(chuàng)建它的activity所處棧,一種是新棧,其他的分析就是對(duì)singleTask的理解而已。
另外,文檔給我們提供了一種會(huì)出現(xiàn):本來(lái)在某一個(gè)Task中,之后出現(xiàn)了轉(zhuǎn)移的情況。
如果該Activity的allowTaskReparenting屬性設(shè)置為true,當(dāng)啟動(dòng)它的任務(wù)棧進(jìn)入后臺(tái),一個(gè)和它有相同affinity的Task進(jìn)入前臺(tái)時(shí),該Activity會(huì)進(jìn)入到該前臺(tái)的task中。
(以下是翻譯)
例子是,如果電子郵件包含網(wǎng)頁(yè)鏈接,則點(diǎn)擊鏈接會(huì)調(diào)出可顯示網(wǎng)頁(yè)的 Activity。 該 Activity 由瀏覽器應(yīng)用定義,但作為電子郵件任務(wù)的一部分啟動(dòng)。 如果將其父項(xiàng)更改為瀏覽器任務(wù),它會(huì)在瀏覽器下一次轉(zhuǎn)至前臺(tái)時(shí)顯示,當(dāng)電子郵件任務(wù)再次轉(zhuǎn)至前臺(tái)時(shí)則會(huì)消失。
我的理解:當(dāng)一個(gè)應(yīng)用A啟動(dòng)了應(yīng)用B的某個(gè)ActivityC后(C的taskAffinity 為B),如果我們將ActivityC的allowTaskReparenting屬性設(shè)置為true,當(dāng)應(yīng)用B被啟動(dòng)后,系統(tǒng)會(huì)發(fā)現(xiàn)Activity C所需的任務(wù)棧已經(jīng)存在,ActivityC就會(huì)從A的任務(wù)棧轉(zhuǎn)移到B的任務(wù)棧中。
(以下還是翻譯)
Activity 的親和關(guān)系由 taskAffinity 屬性定義。 任務(wù)的親和關(guān)系通過(guò)讀取其根 Activity 的親和關(guān)系來(lái)確定。因此,按照定義,根 Activity 始終位于具有相同親和關(guān)系的任務(wù)之中。 由于具有“singleTask”或“singleInstance”啟動(dòng)模式的 Activity 只能位于任務(wù)的根,因此更改父項(xiàng)僅限于“standard”和“singleTop”模式。
我的理解: 每個(gè)task有affinity屬性,等于它的根 Activity的taskAffinity的值。singletask和singleinstance模式下,Atask中只能有一個(gè)A實(shí)例,且為根,那么就不能重新宿主,要不然的話這個(gè)棧就崩了呢~而另外兩種的話,因?yàn)椴皇歉钥梢栽谔囟ㄇ榫诚伦杂捎问帯?/p>
寫(xiě)在最后
由于篇幅和時(shí)間關(guān)系,文章就到此結(jié)束,剩下的問(wèn)題待Android初級(jí)開(kāi)發(fā)筆記-- activity啟動(dòng)模式的學(xué)習(xí)(3)再進(jìn)行討論~