前言
Android12 有很多令人惊喜的变化,比如基于 Material You 的全新 UI,基于 SplashScreen 的应用启动画面以及更安全的隐私设置等等,此外也有一些需要开发者注意的行为变化,比如这里介绍的 Activity 的 Lifecycle 上的变化
点击返回键 Activity 不在 onDestroy
Android 12 以前,当我们处于 Root Activity 时,点击返回键时,应用返回桌面, Activity 执行 onDestroy,程序结束。 Android 12 起同样场景下 Activity 只会 onStop,不再执行 onDestroy。
通过下面代码进行验证:
class LifecycleLogObserver : LifecycleEventObserver {
override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
Log.d(source::class.java.simpleName, event.name)
}
}
class SampleActivity: AppCompatActivity() {
init {
lifecycle.addObserver(LifecycleLogObserver())
}
}
启动 Activity,按下返回键后,重新打开 App。首先 Android12 之前的设备,Log 如下:
// 初次启动
D/SampleActivity: ON_CREATE
D/SampleActivity: ON_START
D/SampleActivity: ON_RESUME
// 返回桌面
D/SampleActivity: ON_PAUSE
D/SampleActivity: ON_STOP
D/SampleActivity: ON_DESTROY
// 再次启动
D/SampleActivity: ON_CREATE
D/SampleActivity: ON_START
D/SampleActivity: ON_RESUME
再开 Android12 之后的设备:
// 初次启动
D/SampleActivity: ON_CREATE
D/SampleActivity: ON_START
D/SampleActivity: ON_RESUME
// 返回桌面
D/SampleActivity: ON_PAUSE
D/SampleActivity: ON_STOP
// 再次启动
D/SampleActivity: ON_START
D/SampleActivity: ON_RESUME
我们知道 ViewModel 的销毁在 onDestroy 中,这样改动后 ViewModel 中的状态可以保存,再次启动后可以直接使用。对于使用者来说直接感受就是冷启动变为了热启动,启动速度更快。
注意:所谓 Root Activity 就是我们在 AndroidManifest 中配置了 IntentFilter 为 ACTION_MAIN 和 CATEGORY_LAUNCHER 的入口 Activity,其他 Activity 点击返回键后行为不变,依然会 onDestroy
重新 onBackPressed 时的注意点
如果你的应用在 Android12 中没有上述变化,那很有可能是你重写了 onBackPressed 并手动调用了 finish(),为了在行为上符合 Android12 的预期,需要修改如下:
class SampleActivity : AppCompatActivity() {
private var flag = true
override fun onBackPressed() {
if (flag) {
flag = false
TODO("do sth business")
return
}
//Don't call finish()
super.onBackPressed()
}
}
当然,官方已不再推荐重写 onBackPressed 了,更好的做法使用 AndroidX 的 OnBackPressedCallback 重写你的实现,它会自动适配 Android12 的变化。
class SampleActivity : AppCompatActivity() {
private val onBackPressedCallback: OnBackPressedCallback =
object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
TODO("do sth business")
//处理自定义业务后,后续返回键交回系统处理
onBackPressedCallback.isEnabled = false
}
}
}
总结
随着手机内存的增大,相比起资源的及时释放,用户体验变得更加重要,这也会为什么 Android12 会引入这次的变化。这次变化也让 onStop 的重要性得以提升,我们要更加区分 onStop 与 onDestroy 在使用场景上的不同:onDestroy 负责必要的资源释放,而其余类似活跃状态的切换应该放在 onStart/onStop 中进行,这符合 androidx-lifecycle 的基本思想。