【Jetpack 更新之Activity】ContextAware 是个啥?
前言
最近 activity 1.2.0 正式版发布,除了全新的 Activity Result API (前面已有介绍),还引入了一个新的接口 ContextAware。

老规矩,我们沿着 git commit 查看该功能的引入过程。
引入原因
IssueTracker 上提了这样一个需求:

LifecycleOwner API 提供了达到 CREATED 状态时的回调,但有些场景这个 API 不满足我们的需求。
例如:
- 调用
setTheme来配置主题 - 调用
setLocalNightMode()
这些方法都需要在 super.onCreate() 和 inflate 布局前调用。
如果存在一个可组合的回调就好了(无需手动在 onCreate() 中加入代码)。
引入前
我们先来看看引入前的状态, LifecycleOwner API 提供的 Observer 只能在至少达到 CREATED 状态时回调。换言之,回调时 super.onCreate() 已经调用。

class MainActivity : AppCompatActivity(R.layout.activity_main) {
init {
lifecycle.addObserver(LifecycleEventObserver { _, event ->
Log.i(TAG, "LifecycleEventObserver: ${event.name} ${event.targetState}")
})
}
override fun onCreate(savedInstanceState: Bundle?) {
Log.d(TAG, "onCreate: before super")
super.onCreate(savedInstanceState)
Log.d(TAG, "onCreate: after super")
}
}

引入后
我们可以通过调用 addOnContextAvailableListener 设置监听:

class MainActivity : AppCompatActivity(R.layout.activity_main) {
init {
lifecycle.addObserver(LifecycleEventObserver { _, event ->
Log.i(TAG, "LifecycleEventObserver: ${event.name} ${event.targetState}")
})
++ addOnContextAvailableListener { context ->
++ Log.i(TAG, "ContextAvailableListener: $context")
++ // 需要在 super.onCreate() 前进行的操作
++ }
}
override fun onCreate(savedInstanceState: Bundle?) {
Log.d(TAG, "onCreate: before super")
super.onCreate(savedInstanceState)
Log.d(TAG, "onCreate: after super")
}
}
该方法会在调用 super.onCreate() 前回调,这意味着我们可以将一些需要在 super.onCreate() 前执行的逻辑放置在 OnContextAvailableListener#onContextAvailable() 方法中。

背后原理
Activity 的继承关系

如上图所示,Activity 的继承关系是:
android.app.Activity → androidx.core.app.ComponentActivity → androidx.activity.ComponentActivity → androidx.fragment.app.FragmentActivity → androidx.appcompat.app.AppCompatActivity → 自定义 Activity
-
android.app.Activity是固化在 ROM 中的 framework 层的 Activity(代码逻辑随着 Android 版本发布而固定),最基础的 Activity,拥有 Activity 最核心的逻辑 -
androidx.core.app.ComponentActivity是 androidx.core library (提供最新的平台功能并兼容旧设备)下的 Activity,其内部逻辑很少,主要作为兼容层存在 -
androidx.activity.ComponentActivity是 androidx.activity library 下的 Activity,其内部封装者 activity 库最新的 API,例如新的 Activity Result API。主要使用多接口的组合实现,例如实现了LifecycleOwner,ViewModelStoreOwner,ActivityResultRegistryOwner等接口 -
androidx.fragment.app.FragmentActivity是 androidx.fragment library 下的 Activity,用于支持 Fragment。其内部持有 FragmentController 以对 Fragment 进行操作。 -
androidx.appcompat.app.AppCompatActivity是 androidx.appcompat library 下的 Activity,主要用于为旧设备提供高版本的功能,如使用 Toolbar 操作标题栏,将 TextView 等控件映射成 AppcompatTextView 等控件。
引入的代码
为了引入 ContextAware 功能,官方在 androidx.activity library 下引入了相关的代码:

代码十分简单,两个接口和一个 Helper 类



核心逻辑
让 androidx.activity library 的 ComponentActivity 实现 ContextAware 接口,并在调用 super.onCreate() 方法前调用 dispatchOnContextAvailable() 方法,代码如下,删减无关代码。

一些细节
- FragmentActivity 内部使用该 API 来为 Fragment 与宿主 Activity 建立关联

- androidx.activity-ktx 提供了一个挂起函数来在 Context 可用时处理数据

总结
- ContextAware 提供了平台 Activity 执行 onCreate() 方法前的回调,可以在该回调做一些必须在 super.onCreate() 前执行的逻辑
- 为了灵活性与兼容性,Activity 有很多「中间层 Activity」
- activity 1.2.0 已发布正式版,可以在生产环境使用
- OnContextAvailableListener 对 library 开发或封装 library 的场景很有用
关于我
人总是喜欢做能够获得正反馈(成就感)的事情,如果感觉本文内容对你有帮助的话,麻烦点亮一下👍,这对我很重要哦~
我是 Flywith24,人只有通过和别人的讨论,才能知道我们自己的经验是否是真实的,加我微信交流,让我们共同进步。