美文网首页安卓
Android APP在后台被杀问题修复

Android APP在后台被杀问题修复

作者: 小强开学前 | 来源:发表于2021-12-18 19:37 被阅读0次

    目前项目采用单 Activity 模式,页面采用 Jetpack Navigation 导航
    布局如下:Splash -> Home -> Detail


    之前的设计逻辑

    Activity

    不做任何事情

    ViewModel

    持有 LiveData 类型变量 hasSDKInit,根据SDK初始化成功与否设置 true 或者 false

    Splash

    • 通过 parentActivity 实例化一个 ViewModel,并在 ViewModel 的构造函数中 初始化 SDK
    • 监听 hasSDKInit, true ==》 跳转 Home,false ==》显示错误信息

    Home

    调用 SDK 实现相关功能。

    发现有异常情况后调查生命周期

    模拟APP被强杀可以去开发者选项打开不保留活动

    • 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 进入后台,相关生命周期:

      Home onPause
      Activity onPause
      Home onStop
      Activity onStop
      Home onSaveInstanceState
      Activity onSaveInstanceState
      
    • APP 在后台被杀

      Home onDestroy
      Home onDetach
      Activity onDestroy
      
    • APP在后台被杀后再次进入前台

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

    错误原因分析及生命周期理解

    很明显,被杀后与 Activity 生命周期关联的 ViewModel 也结束了,与新打开 APP 的区别是,这时候是没有通过 Splash 去 初始化 SDK 的, Home 直接调用一个没有初始化的SDK 实例当然就报错了。

    解决办法

    预备知识
    ViewModel 是与初始化它的 ViewLifeCycleOwner 唯一绑定的,全局唯一,不会重复实例化
    ViewModel 是生命周期感知的,但是在 onDestroy 中做了判断,如果是因为类似横竖屏、黑暗模式、语言等ConfigChanged 导致的销毁,ViewModel 是不会被销毁的。

    另外很重要的一点
    无论在什么情况下,Activity 的 onCreate 一定在 Fragment 的 onCreateView 之前。

    这样我们把 SDK 的初始化挪到 Activity::onCreate就行了。
    Fragment 中通过``ViewModelProvider(requireActivity()).get(GlobalViewModel::class.java)`获取。

    把 init SDK 放到 ViewModel 的构造函数中,并将 initSDK 方法私有化,不允许从外部调用

    context 通过新建ViewModelFactory类传入。
    Google 官方不推荐 ViewModel 持有任何形式的 Context,如果确实要用,可以考虑单例或者 AndroidViewModel

    Splash 页面监听 hasSDKInit 逻辑不变。
    Home 页面原有逻辑不变,必要时加上对 hasSDKInit 的监听,true 才可进行后续操作。
    而,如果SDK 的 init 不依赖网络等其他因素,默认情况下因为所有调用都在主线程,那么 就不用做监听。

    相关文章

      网友评论

        本文标题:Android APP在后台被杀问题修复

        本文链接:https://www.haomeiwen.com/subject/nzbwfrtx.html