適配AndroidQ,不能后臺(tái)啟動(dòng)Activity限制

在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)限。

Vivo攔截應(yīng)用后臺(tái)啟動(dòng)Activity通知.png
Vivo后臺(tái)彈出界面權(quán)限開(kāi)關(guān).png
MIUI10后臺(tái)彈出界面權(quán)限開(kāi)關(guān).png

而默認(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)蕴轨。

    1. 對(duì)于Timer,我們可以在啟動(dòng)頁(yè)的onPause()中骇吭,將Timer停止橙弱,計(jì)算剩余時(shí)間,并在下一次的onResume()中重新啟動(dòng)一個(gè)Timer繼續(xù)計(jì)時(shí)燥狰。
    2. 對(duì)于Handler棘脐,和上面Timer的處理方式一樣,onPause()中removeCallbacksAndMessages(null)來(lái)去掉跳轉(zhuǎn)的Message()或Runnable龙致,再在下一次的onResume()中繼續(xù)sendMessage()或postDelayed()繼續(xù)計(jì)時(shí)蛀缝。
    3. 之前有小伙伴提出過(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)景:

    1. 如果用戶手滑,劃走了通知排截,跳轉(zhuǎn)確定需要再次在電腦端申請(qǐng)嫌蚤,再?gòu)椧淮巍?/li>
    2. 用戶沒(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)撇簿。

  1. 如果需要考慮到上面QQ考慮到的情況,發(fā)送通知差购,讓用戶點(diǎn)擊通知將應(yīng)用拉回前臺(tái)四瘫,棧頂Activity跳轉(zhuǎn)一個(gè)Fragment。

但是上面這種方式也有缺點(diǎn):

  1. 跳轉(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順帶被銷毀了抬闯。

  2. 一般的路由框架井辆,例如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就不能使用該功能了。

  3. 如果是新模塊這么寫固然可以檀头,但是如果是舊模塊轰异,已經(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)步驟

  1. 統(tǒng)一在跳轉(zhuǎn)前判斷前喜鼓、后臺(tái)情況副砍。
  2. 在前臺(tái)直接跳轉(zhuǎn)衔肢,再后臺(tái)則注冊(cè)一個(gè)回到前臺(tái)時(shí)的監(jiān)聽(tīng)回調(diào),回調(diào)時(shí)再進(jìn)行跳轉(zhuǎn)豁翎。
  3. 發(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)源

    1. NORMAL驳癌,普通跳轉(zhuǎn)滑燃,正常的Activity應(yīng)用內(nèi)跳轉(zhuǎn),會(huì)進(jìn)行前颓鲜、后臺(tái)判斷表窘。
    2. NOTIFICATION典予,點(diǎn)擊通知進(jìn)行的跳轉(zhuǎn),不會(huì)判斷前乐严、后臺(tái)判斷熙参。(不然,在后臺(tái)時(shí)發(fā)送給用戶的通知被點(diǎn)擊了麦备,又會(huì)因?yàn)樵诤笈_(tái)被攔截掉)
    3. 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()拓展方法。

    1. 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)一處理攔截的情況升薯。
    2. 我使用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)。
    3. sendMoveAppForegroundMsg()脸哀,發(fā)送通知蹦浦,大家按自己項(xiàng)目封裝的來(lái)即可,由于我封裝得比較多撞蜂,不是本篇重點(diǎn)盲镶,所以只貼出通知被點(diǎn)擊時(shí)調(diào)用的moveAppToForeground()方法。
    4. navNotification谅摄,是提供給發(fā)送通知時(shí)使用的標(biāo)題和內(nèi)容徒河。
    5. 走到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)判斷。

  1. 在攔截器中判斷前、后臺(tái)情況蹲坷,后臺(tái)時(shí)浦夷,注冊(cè)前臺(tái)回調(diào),記得取消注冊(cè)喊暖,避免下一次切換又被回調(diào)惫企,發(fā)送通知。下次回到前臺(tái)時(shí)繼續(xù)跳轉(zhuǎn)。
  2. 在前臺(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)
            }
        }
    }
}
  1. 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)
            }
        })
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市恩尾,隨后出現(xiàn)的幾起案子弛说,更是在濱河造成了極大的恐慌,老刑警劉巖翰意,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件木人,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡冀偶,警方通過(guò)查閱死者的電腦和手機(jī)醒第,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)进鸠,“玉大人稠曼,你說(shuō)我怎么就攤上這事】湍辏” “怎么了霞幅?”我有些...
    開(kāi)封第一講書人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)量瓜。 經(jīng)常有香客問(wèn)我司恳,道長(zhǎng),這世上最難降的妖魔是什么绍傲? 我笑而不...
    開(kāi)封第一講書人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任扔傅,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘铅鲤。我一直安慰自己划提,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布邢享。 她就那樣靜靜地躺著鹏往,像睡著了一般。 火紅的嫁衣襯著肌膚如雪骇塘。 梳的紋絲不亂的頭發(fā)上伊履,一...
    開(kāi)封第一講書人閱讀 49,036評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音款违,去河邊找鬼唐瀑。 笑死,一個(gè)胖子當(dāng)著我的面吹牛插爹,可吹牛的內(nèi)容都是我干的哄辣。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼赠尾,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼力穗!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起气嫁,我...
    開(kāi)封第一講書人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤当窗,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后寸宵,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體崖面,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年梯影,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了巫员。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡光酣,死狀恐怖疏遏,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情救军,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布倘零,位于F島的核電站唱遭,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏呈驶。R本人自食惡果不足惜拷泽,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧司致,春花似錦拆吆、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至庭再,卻和暖如春捞奕,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背拄轻。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工颅围, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人恨搓。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓院促,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親斧抱。 傳聞我的和親對(duì)象是個(gè)殘疾皇子一疯,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345