Android APP在后臺(tái)被殺問題修復(fù)

目前項(xiàng)目采用單 Activity 模式,頁(yè)面采用 Jetpack Navigation 導(dǎo)航
布局如下:Splash -> Home -> Detail


之前的設(shè)計(jì)邏輯

Activity

不做任何事情

ViewModel

持有 LiveData 類型變量 hasSDKInit,根據(jù)SDK初始化成功與否設(shè)置 true 或者 false

Splash

  • 通過 parentActivity 實(shí)例化一個(gè) ViewModel,并在 ViewModel 的構(gòu)造函數(shù)中 初始化 SDK
  • 監(jiān)聽 hasSDKInit, true ==》 跳轉(zhuǎn) Home,false ==》顯示錯(cuò)誤信息

Home

調(diào)用 SDK 實(shí)現(xiàn)相關(guān)功能。

發(fā)現(xiàn)有異常情況后調(diào)查生命周期

模擬APP被強(qiáng)殺可以去開發(fā)者選項(xiàng)打開不保留活動(dòng)

  • APP 打開

    Splash onAttach
    Splash onCreate
    Activity onCreate
    Splash onCreateView
    Splash onViewStateRestored
    Splash onStart
    Activity onStart
    Activity onResume
    Splash onResume
    Splash onPause
    Splash onStop
    Home onAttach
    Home onCreate
    Home onCreateView
    Home onViewStateRestored
    Home onStart
    Splash onDestroy
    Splash onDetach
    Home onResume
    
  • APP 進(jìn)入后臺(tái),相關(guān)生命周期:

    Home onPause
    Activity onPause
    Home onStop
    Activity onStop
    Home onSaveInstanceState
    Activity onSaveInstanceState
    
  • APP 在后臺(tái)被殺

    Home onDestroy
    Home onDetach
    Activity onDestroy
    
  • APP在后臺(tái)被殺后再次進(jìn)入前臺(tái)

    Home onAttach
    Home onCreate
    Activity onCreate
    Home onCreateView
    Home onViewStateRestored
    Home onStart
    Activity onStart
    Activity onResume
    Home onResume
    

錯(cuò)誤原因分析及生命周期理解

很明顯,被殺后與 Activity 生命周期關(guān)聯(lián)的 ViewModel 也結(jié)束了,與新打開 APP 的區(qū)別是,這時(shí)候是沒有通過 Splash 去 初始化 SDK 的, Home 直接調(diào)用一個(gè)沒有初始化的SDK 實(shí)例當(dāng)然就報(bào)錯(cuò)了。

解決辦法

預(yù)備知識(shí)
ViewModel 是與初始化它的 ViewLifeCycleOwner 唯一綁定的,全局唯一,不會(huì)重復(fù)實(shí)例化
ViewModel 是生命周期感知的,但是在 onDestroy 中做了判斷,如果是因?yàn)轭愃茩M豎屏、黑暗模式、語(yǔ)言等ConfigChanged 導(dǎo)致的銷毀,ViewModel 是不會(huì)被銷毀的。

另外很重要的一點(diǎn)
無論在什么情況下,Activity 的 onCreate 一定在 Fragment 的 onCreateView 之前。

這樣我們把 SDK 的初始化挪到 Activity::onCreate就行了。
Fragment 中通過``ViewModelProvider(requireActivity()).get(GlobalViewModel::class.java)`獲取。

把 init SDK 放到 ViewModel 的構(gòu)造函數(shù)中,并將 initSDK 方法私有化,不允許從外部調(diào)用

context 通過新建ViewModelFactory類傳入。
Google 官方不推薦 ViewModel 持有任何形式的 Context,如果確實(shí)要用,可以考慮單例或者 AndroidViewModel

Splash 頁(yè)面監(jiān)聽 hasSDKInit 邏輯不變。
Home 頁(yè)面原有邏輯不變,必要時(shí)加上對(duì) hasSDKInit 的監(jiān)聽,true 才可進(jìn)行后續(xù)操作。
而,如果SDK 的 init 不依賴網(wǎng)絡(luò)等其他因素,默認(rèn)情況下因?yàn)樗姓{(diào)用都在主線程,那么 就不用做監(jiān)聽。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容