在AndroidQ或例如Vivo皇耗、小米等第三方廠商ROM中南窗,都對(duì)后臺(tái)啟動(dòng)Activity做了限制,AndroidQ中并沒(méi)有設(shè)計(jì)有權(quán)限申請(qǐng)來(lái)進(jìn)行設(shè)置郎楼,而Vivo万伤、小米則是在App權(quán)限設(shè)置中加入了后臺(tái)啟動(dòng)Activity的權(quán)限。
而默認(rèn)該項(xiàng)權(quán)限都是關(guān)閉的呜袁,并且因?yàn)闆](méi)有Api可以調(diào)用申請(qǐng)敌买。當(dāng)App第一次在后臺(tái)情況下跳轉(zhuǎn)Activity時(shí),系統(tǒng)會(huì)進(jìn)行攔截阶界,并彈出一條通知告訴用戶虹钮,后續(xù)則不會(huì)重復(fù)提醒,而原生AndroidQ則是不提醒膘融,直接攔截芙粱。
為什么要后臺(tái)時(shí)跳轉(zhuǎn),場(chǎng)景呢
- 場(chǎng)景一:?jiǎn)?dòng)頁(yè)氧映,展示品牌Logo和廣告春畔,5秒后跳轉(zhuǎn)
有些小伙伴會(huì)問(wèn)了,什么情況我們會(huì)后臺(tái)進(jìn)行跳轉(zhuǎn)Activity呢岛都?用戶都不在操作界面律姨,怎么會(huì)有跳轉(zhuǎn)操作呢?其實(shí)有一種情況就足以解釋了臼疫。
例如我們App一般都會(huì)設(shè)計(jì)一個(gè)SplashActivity或者一個(gè)WelcomeActivity來(lái)作為啟動(dòng)頁(yè)择份,顯示品牌Logo或者廣告(一般都有),顯示頁(yè)面5秒后跳轉(zhuǎn)到主頁(yè)烫堤,只要設(shè)置用戶點(diǎn)擊了Home鍵回到桌面或者點(diǎn)擊了其他App的通知(例如微信荣赶、QQ等)凤价,就會(huì)跳轉(zhuǎn)到通知來(lái)源的App,這是App還在計(jì)時(shí)讯壶,當(dāng)過(guò)了5秒后,就會(huì)執(zhí)行跳轉(zhuǎn)操作湾盗,這時(shí)例如突然收到老板緊急微信伏蚊,馬上點(diǎn)擊通知,去到微信中打字格粪,就會(huì)突然被這個(gè)跳轉(zhuǎn)的App拉回去躏吊,造成很不好的體驗(yàn)。(如果是我肯定很煩躁U饰)
相比iOS比伏,跳轉(zhuǎn)ViewController則不會(huì)拉回App。重新點(diǎn)擊App時(shí)是已經(jīng)跳轉(zhuǎn)好的了疆导。
- 場(chǎng)景二:電腦版登錄赁项,彈出界面確定登錄
這種情況在多端登錄時(shí),可能會(huì)遇到澈段,例如:在電腦端微信悠菜,請(qǐng)求登錄微信,這時(shí)手機(jī)微信就會(huì)彈出一個(gè)Activity讓我們點(diǎn)擊確認(rèn)败富,電腦端再進(jìn)行登錄悔醋。這時(shí)剛好撞到槍口上了,如果在AndroidQ中兽叮,界面就跳轉(zhuǎn)失敗了芬骄。
找出廠商后臺(tái)打開(kāi)Activity的權(quán)限開(kāi)關(guān)(不推薦)
和以前權(quán)限被關(guān)閉,讓用戶去設(shè)置中打開(kāi)權(quán)限類似鹦聪,例如用獲取當(dāng)前Activity應(yīng)用账阻,找出廠商的打開(kāi)后臺(tái)Activity的權(quán)限頁(yè)面,其實(shí)這種方式工作量是最大的泽本,要適配各大廠商的ROM宰僧,而且ROM又有不同的版本(例如MIUI9、MIUI10等)观挎,而且權(quán)限申請(qǐng)還有個(gè)理由請(qǐng)求獲取琴儿,這個(gè)后臺(tái)打開(kāi)Activity的權(quán)限理由,也不好編嘁捷,讓用戶覺(jué)得你要獲取后臺(tái)彈出的權(quán)限造成,十有八九都覺(jué)得你會(huì)干壞事,也自然不會(huì)允許了雄嚣。
解決方案晒屎,怎么適配
-
啟動(dòng)頁(yè)延時(shí)5秒后跳轉(zhuǎn)的場(chǎng)景
一般Android端中進(jìn)行定時(shí)喘蟆、延時(shí)功能,一種是使用Timer定時(shí)器鼓鲁,一種是使用Handler循環(huán)調(diào)用來(lái)實(shí)現(xiàn)蕴轨。
- 對(duì)于Timer,我們可以在啟動(dòng)頁(yè)的onPause()中骇吭,將Timer停止橙弱,計(jì)算剩余時(shí)間,并在下一次的onResume()中重新啟動(dòng)一個(gè)Timer繼續(xù)計(jì)時(shí)燥狰。
- 對(duì)于Handler棘脐,和上面Timer的處理方式一樣,onPause()中removeCallbacksAndMessages(null)來(lái)去掉跳轉(zhuǎn)的Message()或Runnable龙致,再在下一次的onResume()中繼續(xù)sendMessage()或postDelayed()繼續(xù)計(jì)時(shí)蛀缝。
- 之前有小伙伴提出過(guò)一種粗暴的手法,在跳轉(zhuǎn)前目代,開(kāi)啟一個(gè)定時(shí)器屈梁,預(yù)估個(gè)2秒左右,判斷當(dāng)前Activity是否是本次跳轉(zhuǎn)的Activity來(lái)判定跳轉(zhuǎn)是否被攔截榛了。對(duì)于該方案俘闯,我不是很推薦,因?yàn)轭A(yù)估的時(shí)間怎么評(píng)定比較不靠譜忽冻,不是每個(gè)頁(yè)面跳轉(zhuǎn)都是2秒真朗,例如像淘寶、支付寶這種量級(jí)比較大的App僧诚,他們的跳轉(zhuǎn)未必有那么快遮婶,尤其是冷啟動(dòng)的時(shí)候,往往會(huì)比較卡湖笨、比較久旗扑,低配置的機(jī)子會(huì)更加明顯。
-
微信電腦端登錄的場(chǎng)景
其實(shí)對(duì)于微信的自動(dòng)跳轉(zhuǎn)慈省,QQ則是更加優(yōu)雅的方式臀防,QQ的方案是發(fā)出一個(gè)通知,用戶點(diǎn)擊通知边败,回到QQ進(jìn)行確認(rèn)授權(quán)登錄袱衷,而在跳轉(zhuǎn)確定頁(yè)面中,一種是在通知中笑窜,我們可以給PendingIntent設(shè)置跳轉(zhuǎn)去Activity來(lái)進(jìn)行跳轉(zhuǎn)致燥,而QQ則應(yīng)該是考慮到了以下場(chǎng)景:
- 如果用戶手滑,劃走了通知排截,跳轉(zhuǎn)確定需要再次在電腦端申請(qǐng)嫌蚤,再?gòu)椧淮巍?/li>
- 用戶沒(méi)有點(diǎn)擊通知辐益,而是直接點(diǎn)開(kāi)QQ,卻沒(méi)有確定信息可以直接確認(rèn)脱吱,因?yàn)樾枰c(diǎn)擊通知才能跳轉(zhuǎn)智政。
那么QQ的做法是什么呢?我預(yù)估就是發(fā)起通知的同時(shí)箱蝠,再棧頂?shù)腁ctivity跳轉(zhuǎn)一個(gè)Fragment续捂,或者使用一個(gè)View、Layout進(jìn)行覆蓋來(lái)顯示抡锈。而通知的操作則是將應(yīng)用的Activity棧拉回前臺(tái)疾忍。
官方適配方案
Google推薦方式是乔外,類似QQ的友好提示床三,在應(yīng)用在后臺(tái)時(shí),應(yīng)該發(fā)起一個(gè)通知杨幼,用戶點(diǎn)擊后跳轉(zhuǎn)撇簿。
- 如果需要考慮到上面QQ考慮到的情況,發(fā)送通知差购,讓用戶點(diǎn)擊通知將應(yīng)用拉回前臺(tái)四瘫,棧頂Activity跳轉(zhuǎn)一個(gè)Fragment。
但是上面這種方式也有缺點(diǎn):
跳轉(zhuǎn)Framgnet必須依賴Activity欲逃,如果應(yīng)用被殺死了找蜜,所有Activity都回銷毀回收,用戶再點(diǎn)擊通知時(shí)稳析,拉起QQ后洗做,再在最前的Activity進(jìn)行跳轉(zhuǎn)Fragment。對(duì)于一般流程彰居,我們是先啟動(dòng)一個(gè)啟動(dòng)頁(yè)再跳轉(zhuǎn)到首頁(yè)诚纸,很有可能出現(xiàn)在啟動(dòng)頁(yè)中跳轉(zhuǎn)了Fragment,然后在5秒后跳轉(zhuǎn)到首頁(yè)陈惰,恰巧跳轉(zhuǎn)過(guò)去同時(shí)畦徘,啟動(dòng)頁(yè)被銷毀,這個(gè)Fragment順帶被銷毀了抬闯。
一般的路由框架井辆,例如ARouter,F(xiàn)ragment跳轉(zhuǎn)并不支持?jǐn)r截溶握,例如登錄確認(rèn)的頁(yè)面掘剪,需要跳轉(zhuǎn)前判斷是否登錄,未登錄跳轉(zhuǎn)到登錄頁(yè)面奈虾。當(dāng)然一般不會(huì)夺谁,除非出現(xiàn)了Bug廉赔,就會(huì)可能在未登錄時(shí)收到了確認(rèn)登錄的通知。例如某些極端情況匾鸥,在電腦端進(jìn)行申請(qǐng)登錄蜡塌,手機(jī)端剛好選擇退出登錄,如果推送消息或長(zhǎng)連接稍微因?yàn)榫W(wǎng)絡(luò)卡了一點(diǎn)勿负,在退出登錄之后收到了馏艾,就可能跳轉(zhuǎn)去了確認(rèn)的頁(yè)面(我司的測(cè)試小姐姐、小哥哥們就是這么變態(tài)啊~他們真的會(huì)這么做的E洹)琅摩。作為嚴(yán)謹(jǐn)?shù)某绦騿T,我們還是需要加上登錄判斷锭硼,如果是舊頁(yè)面就已經(jīng)使用路由攔截器來(lái)驗(yàn)證房资,修改為Fragment就不能使用該功能了。
如果是新模塊這么寫固然可以檀头,但是如果是舊模塊轰异,已經(jīng)是用跳轉(zhuǎn)Activity的方式寫了,改為Fragment會(huì)有些不現(xiàn)實(shí)暑始,例如該界面有startActivity()的操作搭独,耦合到了Activity的onActivityResult(),需要將原本的onActivityResult()挪到依附的Activity廊镜,改動(dòng)太大了牙肝,并且依附到哪個(gè)Activity都是不確定的(只是棧頂就可以),代碼放哪里都不合適嗤朴,當(dāng)時(shí)你可以將onActivityResult()的調(diào)用分發(fā)給所有依附的Fragment來(lái)解決配椭,需要改動(dòng)原有代碼,總體來(lái)說(shuō)不合適播赁,我們需要通用方案颂郎,遵循開(kāi)閉原則,對(duì)修改關(guān)閉容为,對(duì)拓展開(kāi)放乓序。
解決方案
既然跳轉(zhuǎn)Fragment依賴Activity,造成了耦合坎背,我來(lái)講一下我的解決方案吧~
首先跳轉(zhuǎn)Activity會(huì)強(qiáng)行拉起我們的App替劈,對(duì)用戶造成了不好的影響,那么我們可以在跳轉(zhuǎn)前得滤,判斷應(yīng)用處于前臺(tái)還是后臺(tái)陨献。
- 前臺(tái):直接跳轉(zhuǎn)即可。
- 后臺(tái):則等到下一次用戶回到App時(shí)繼續(xù)跳轉(zhuǎn)懂更,與此同時(shí)眨业,發(fā)送一個(gè)通知急膀,讓用戶點(diǎn)擊后將App拉回前臺(tái)(并不是所有的跳轉(zhuǎn)操作都需要發(fā)送通知,類似微信登錄確認(rèn)這種強(qiáng)調(diào)馬上確認(rèn)的場(chǎng)景才進(jìn)行發(fā)送龄捡,不然用戶頻繁在跳轉(zhuǎn)前將App后臺(tái)了卓嫂,就會(huì)頻繁發(fā)出通知,一般來(lái)講用戶不會(huì)這樣做聘殖,但是測(cè)試小姐姐晨雳、小哥哥會(huì)醬紫做呀!(大部分是我自己強(qiáng)迫癥的原因))奸腺。
對(duì)于前后臺(tái)判斷和監(jiān)控有很多種方式餐禁,這里推薦我之前寫的一篇文章Android App前后臺(tái)監(jiān)控,對(duì)于前后臺(tái)判斷突照、以及前帮非、后臺(tái)監(jiān)聽(tīng),都有現(xiàn)成的Api使用绷旗。
實(shí)現(xiàn)步驟
- 統(tǒng)一在跳轉(zhuǎn)前判斷前喜鼓、后臺(tái)情況副砍。
- 在前臺(tái)直接跳轉(zhuǎn)衔肢,再后臺(tái)則注冊(cè)一個(gè)回到前臺(tái)時(shí)的監(jiān)聽(tīng)回調(diào),回調(diào)時(shí)再進(jìn)行跳轉(zhuǎn)豁翎。
- 發(fā)送通知角骤,用戶點(diǎn)擊通知,將App拉回前臺(tái)心剥,就會(huì)觸發(fā)步驟二時(shí)注冊(cè)的監(jiān)聽(tīng)邦尊,從而繼續(xù)跳轉(zhuǎn)。
這樣子的好處是优烧,一是并沒(méi)有強(qiáng)制改動(dòng)為Fragment導(dǎo)致代碼大改蝉揍,而是在后臺(tái)時(shí)暫停跳轉(zhuǎn),回到前臺(tái)時(shí)繼續(xù)跳轉(zhuǎn)畦娄。
示例代碼
- 例如跳轉(zhuǎn)到訂單詳情又沾,我使用ARouter來(lái)跳轉(zhuǎn),再用kotlin來(lái)對(duì)ARouter的navigation()跳轉(zhuǎn)方法做了一個(gè)拓展方法來(lái)統(tǒng)一跳轉(zhuǎn)熙卡。
/**
* 跳轉(zhuǎn)到訂單詳情
*/
fun goWorkOrderDetail(
activity: Activity,
workOrderId: String,
source: RouteSource = RouteSource.NORMAL,
callback: NavigationCallback? = null
) {
ARouter.getInstance()
.build(ARouterUrl.WORK_ORDER_DETAIL)
//傳遞訂單Id
.withString(WorkConstant.Args.WORK_ORDER_ID, workOrderId)
.startNavigation(activity, source = source, callback = callback)
}
-
RouteSource枚舉杖刷,代表跳轉(zhuǎn)時(shí)的來(lái)源,暫時(shí)定義了3種來(lái)源
- NORMAL驳癌,普通跳轉(zhuǎn)滑燃,正常的Activity應(yīng)用內(nèi)跳轉(zhuǎn),會(huì)進(jìn)行前颓鲜、后臺(tái)判斷表窘。
- NOTIFICATION典予,點(diǎn)擊通知進(jìn)行的跳轉(zhuǎn),不會(huì)判斷前乐严、后臺(tái)判斷熙参。(不然,在后臺(tái)時(shí)發(fā)送給用戶的通知被點(diǎn)擊了麦备,又會(huì)因?yàn)樵诤笈_(tái)被攔截掉)
- SHORTCUT孽椰,8.0的Shortcut快捷方式來(lái)進(jìn)行跳轉(zhuǎn),也不行前凛篙、后臺(tái)判斷黍匾。
enum class RouteSource(val code: Int) {
/**
* 普通跳轉(zhuǎn)
*/
NORMAL(1),
/**
* 通知欄跳轉(zhuǎn)
*/
NOTIFICATION(2),
/**
* 桌面快捷方式
*/
SHORTCUT(3)
}
-
startNavigation()拓展方法。
- continueNavigation()呛梆,正在發(fā)起跳轉(zhuǎn)的方法锐涯,kotlin的方法支持內(nèi)嵌方法,如果大家用Java來(lái)寫填物,則可以將方法中的代碼封裝為Runnable即可纹腌。navigation()方法中,我統(tǒng)一包裹了一個(gè)NavigationCallback回調(diào)來(lái)包裹用戶傳入的跳轉(zhuǎn)回調(diào)監(jiān)聽(tīng)callback滞磺,目的是為了統(tǒng)一處理攔截的情況升薯。
- 我使用AppMonitor.isAppBackground()方法判斷當(dāng)前是否在后臺(tái),并且傳入的跳轉(zhuǎn)來(lái)源RouteSource枚舉是否為普通跳轉(zhuǎn)击困,是則使用AppMonitor.register()方法來(lái)注冊(cè)一個(gè)回到前臺(tái)時(shí)的回調(diào)涎劈。被回調(diào)時(shí),再調(diào)用continueNavigation()方法來(lái)繼續(xù)完成跳轉(zhuǎn)阅茶,記得取消注冊(cè)蛛枚,避免下一次切換又被回調(diào)。
- sendMoveAppForegroundMsg()脸哀,發(fā)送通知蹦浦,大家按自己項(xiàng)目封裝的來(lái)即可,由于我封裝得比較多撞蜂,不是本篇重點(diǎn)盲镶,所以只貼出通知被點(diǎn)擊時(shí)調(diào)用的moveAppToForeground()方法。
- navNotification谅摄,是提供給發(fā)送通知時(shí)使用的標(biāo)題和內(nèi)容徒河。
- 走到else分支,則代表是在前臺(tái)送漠,那么我們直接調(diào)用continueNavigation()顽照,正常跳轉(zhuǎn)即可。
/**
* ARouter跳轉(zhuǎn)Activity統(tǒng)一拓展
* @param requestCode startActivityForResult時(shí)使用的requestCode
* @param callback 跳轉(zhuǎn)回調(diào)
* @param source 跳轉(zhuǎn)來(lái)源類型,默認(rèn)為普通跳轉(zhuǎn)代兵,會(huì)進(jìn)行后臺(tái)尼酿、前臺(tái)判斷,如果為后臺(tái)則到下一次回到前臺(tái)時(shí)再跳轉(zhuǎn)
* @param navNotification 當(dāng)跳轉(zhuǎn)時(shí)不在前臺(tái)時(shí)植影,是否發(fā)送一條通知讓用戶跳轉(zhuǎn)回App裳擎,Pair的2個(gè)參數(shù)分別為title和content
* 這個(gè)主要是為了兼容AndroidQ的各大第三方廠商定制的不讓后臺(tái)時(shí)跳轉(zhuǎn)Activity的權(quán)限,一般用于像電腦登錄微信時(shí)彈出界面使用
*/
@JvmOverloads
fun Postcard.startNavigation(
activity: Activity,
requestCode: Int = -1,
callback: NavigationCallback? = null,
source: RouteSource = RouteSource.NORMAL,
navNotification: Pair<String, String>? = null
) {
//這里兼容AndroidQ的限制思币,App不在后臺(tái)進(jìn)行跳轉(zhuǎn)的情況
AppMonitor.get().run {
//正在發(fā)起跳轉(zhuǎn)的方法
fun continueNavigation() {
navigation(activity, requestCode, object : NavigationCallback {
override fun onFound(postcard: Postcard?) {
//路由目標(biāo)被發(fā)現(xiàn)時(shí)調(diào)用
callback?.onFound(postcard)
}
override fun onArrival(postcard: Postcard?) {
//路由到達(dá)時(shí)調(diào)用
callback?.onArrival(postcard)
}
override fun onLost(postcard: Postcard?) {
//路由被丟失時(shí)調(diào)用
callback?.onLost(postcard)
}
override fun onInterrupt(postcard: Postcard?) {
//路由被攔截時(shí)調(diào)用鹿响,統(tǒng)一攔截處理,這里我貼一下我寫的登錄統(tǒng)一攔截處理
//未登錄谷饿,攔截了惶我,由于登錄攔截器中,攔截時(shí)會(huì)給跳轉(zhuǎn)參數(shù)中加一個(gè)標(biāo)志位博投,如果判斷到有標(biāo)志位绸贡,就代表被攔截了,則跳轉(zhuǎn)到登錄頁(yè)面
postcard?.run {
if (extras.getBoolean(ARouterUrl.IS_LOGIN_INTERCEPTOR)) {
ARouter.getInstance()
.build(ARouterUrl.LOGIN_LOGIN)
.navigation(activity)
}
}
callback?.onInterrupt(postcard)
}
})
}
//不在前臺(tái)毅哗,訂閱一個(gè)切換回前臺(tái)的回調(diào)听怕,回到前臺(tái)時(shí),再繼續(xù)跳轉(zhuǎn)
if (isAppBackground && RouteSource.NORMAL == source) {
register(object : AppMonitor.CallbackAdapter() {
override fun onAppForeground() {
super.onAppForeground()
//回調(diào)一次后就取消注冊(cè)虑绵,否則會(huì)重復(fù)回調(diào)
unRegister(this)
//回到前臺(tái)再繼續(xù)跳轉(zhuǎn)
continueNavigation()
}
})
//發(fā)送一條通知提醒用戶點(diǎn)擊尿瞭,用戶點(diǎn)擊后再跳轉(zhuǎn)
if (navNotification != null) {
sendMoveAppForegroundMsg()
}
} else {
//在前臺(tái)或者通知欄跳轉(zhuǎn),直接跳轉(zhuǎn)
continueNavigation()
}
}
}
- 通知被點(diǎn)擊后蒸殿,執(zhí)行moveAppToForeground筷厘,將App從后臺(tái)拉回到前臺(tái)
/**
* 將棧頂activity移到前臺(tái)
*/
public void moveAppToForeground(Context context) {
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> tasks = activityManager.getRunningTasks(100);
for (ActivityManager.RunningTaskInfo task : tasks) {
if (task.topActivity.getPackageName().equals(context.getPackageName())) {
activityManager.moveTaskToFront(task.id, ActivityManager.MOVE_TASK_WITH_HOME);
}
}
}
沒(méi)有封裝統(tǒng)一跳轉(zhuǎn)鸣峭,無(wú)侵入式攔截
如果沒(méi)有封裝類似startNavigation()宏所,統(tǒng)一的跳轉(zhuǎn)方法,而使用了路由框架摊溶。例如ARouter爬骤,我們可以建立一個(gè)攔截器。在攔截器中進(jìn)行前莫换、后臺(tái)判斷。
- 在攔截器中判斷前、后臺(tái)情況蹲坷,后臺(tái)時(shí)浦夷,注冊(cè)前臺(tái)回調(diào),記得取消注冊(cè)喊暖,避免下一次切換又被回調(diào)惫企,發(fā)送通知。下次回到前臺(tái)時(shí)繼續(xù)跳轉(zhuǎn)。
- 在前臺(tái)狞尔,繼續(xù)跳轉(zhuǎn)丛版。
@Interceptor(priority = 1)
class AppNavgationInterceptor : IInterceptor {
override fun init(context: Context?) {
}
override fun process(postcard: Postcard?, callback: InterceptorCallback?) {
AppMonitor.get().run {
//在后臺(tái),攔截
if (isAppBackground) {
//獲取RouteSource
val routeSource = postcard?.extras?.getSerializable("route_source") as? RouteSource
//獲取要發(fā)送通知標(biāo)題偏序、內(nèi)容
val navNotificationPair = postcard?.extras?.getSerializable("nav_notification") as? Pair<String, String>
if(routeSource == RouteSource.NORMAL) {
register(object :AppMonitor.CallbackAdapter() {
override fun onAppForeground() {
super.onAppForeground()
unRegister(this)
//回到前臺(tái)后页畦,繼續(xù)跳轉(zhuǎn)
callback?.onContinue(postcard)
}
})
//發(fā)送一條通知提醒用戶點(diǎn)擊,用戶點(diǎn)擊后再跳轉(zhuǎn)
if (navNotificationPair != null) {
sendMoveAppForegroundMsg()
}
} else {
//不是普通跳轉(zhuǎn)類型研儒,不進(jìn)行攔截
callback?.onContinue(postcard)
}
} else {
//在前臺(tái)豫缨,放行,繼續(xù)跳轉(zhuǎn)
callback?.onContinue(postcard)
}
}
}
}
- startNavigation()方法端朵,則需要修改一下州胳,主要是將跳轉(zhuǎn)來(lái)源和通知標(biāo)題、內(nèi)容放到跳轉(zhuǎn)參數(shù)逸月,讓攔截器獲取栓撞。直接使用navigation()跳轉(zhuǎn)即可。
@JvmOverloads
fun Postcard.startNavigation(
activity: Activity,
requestCode: Int = -1,
callback: NavigationCallback? = null,
source: RouteSource = RouteSource.NORMAL,
navNotification: Pair<String, String>? = null
) {
//修改1:將跳轉(zhuǎn)來(lái)源和通知標(biāo)題碗硬、內(nèi)容放到跳轉(zhuǎn)參數(shù)瓤湘,讓攔截器獲取
withSerializable("route_source", source)
if (navNotification != null) {
withSerializable("nav_notification", navNotification)
}
navigation(activity, requestCode, object : NavigationCallback {
//...省略其他復(fù)寫方法
override fun onInterrupt(postcard: Postcard?) {
//省略登錄攔截處理
callback?.onInterrupt(postcard)
}
})
}