安卓

Android APP在后台被杀问题修复

2021-12-18  本文已影响0人  小强开学前

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


之前的设计逻辑

Activity

不做任何事情

ViewModel

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

Splash

Home

调用 SDK 实现相关功能。

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

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

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

很明显,被杀后与 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 不依赖网络等其他因素,默认情况下因为所有调用都在主线程,那么 就不用做监听。

上一篇下一篇

猜你喜欢

热点阅读