哪些 Context調(diào)用 startActivity 需要設(shè)置NEW_TASK,為什么帘营?
- 最常見(jiàn)的就是 Application 需要設(shè)置 NEW_TASK了尉姨,為什么需要呢?
在開(kāi)發(fā)中我們直接接觸的Context主要有:Application,Activity和Service拂檩,他們?nèi)叨际情g接繼承自Context的侮腹;Context是一個(gè)抽象類,我們可以看它的最終實(shí)現(xiàn)類ContextImpl的startActivity,我們可以發(fā)現(xiàn)在ContextImpl#startActivity中稻励,會(huì)對(duì)Intent.flag進(jìn)行一系列的檢查父阻,用于判斷把啟動(dòng)的Activity加入到哪個(gè)任務(wù)棧中,判斷的大概意思就是除了Activity(Activity類覆蓋了startActivity方法望抽,允許新啟動(dòng)的Activity和當(dāng)前Activity在同一個(gè)任務(wù)棧中)之外加矛,其它的Context調(diào)用startActivity都必須加上FLAG_ACTIVITY_NEW_TASK,否者會(huì)直接拋出異常煤篙;判斷后最終會(huì)調(diào)用Instrumentation.execStartActivity 執(zhí)行跳轉(zhuǎn)
比較有意思的是在TargetSDKVersion為24,25,26,27這些版本上斟览,這個(gè)判斷出現(xiàn)了Bug,也就是在這之間的版本上你可以不設(shè)置FLAG_ACTIVITY_NEW_TASK也可以利用非Activity的Context進(jìn)行Activity的跳轉(zhuǎn),本應(yīng)該為options == null的判斷被寫(xiě)成了options != null,所以沒(méi)有進(jìn)入拋出異常的分支判斷
聯(lián)想到Android的四種啟動(dòng)模式(Standard,SingleTask,SingleTop,SingleInstance)辑奈,Activity有一個(gè)Activity棧去管理它苛茂,如果你用一個(gè)非Activity的Context去啟動(dòng)一個(gè)Activity的話,新的Activity并不知道自己應(yīng)該放在哪個(gè)Activity任務(wù)棧中,而設(shè)置上 FLAG_ACTIVITY_NEW_TASK 標(biāo)記鸠窗,就會(huì)直接創(chuàng)建一個(gè) Activity 棧來(lái)管理它了妓羊。實(shí)際上,這樣的啟動(dòng)方式就是以SingleTask模式啟動(dòng)的稍计。
- 其他的 Context 呢躁绸?
BroadcastReceiver和ContentPrider都沒(méi)有直接或者間接的繼承Context,ContentProvider#getContext()得到的是Application的實(shí)例,而B(niǎo)roadcastReceiver#onReceiver中的Context參數(shù)是發(fā)送廣播的那個(gè)Context實(shí)例