@OnLifecycleEvent 被废弃,替代方案是?
BATcoder技术群,让一部分人先进大厂
大家好,我是刘望舒,腾讯TVP,著有三本业内知名畅销书,连续四年蝉联电子工业出版社年度优秀作者,百度百科收录的资深技术专家。
前华为架构师,现独角兽技术负责人
想要加入 BATcoder技术群,公号回复BAT
即可。
近期 androidx.lifecycle 发布了 2.4.0 版本,此次更新中 @OnLifecycleEvent
注解被废弃,官方建议使用 LifecycleEventObserver
或者 DefaultLifecycleObserver
替代
现代的 Android 应用中都少不了 Lifecycle 的身影,正是各种 lifecycle-aware 组件的存在保证了程序的健壮性。
Lifecycle 本质是一个观察者模式的最佳实践,通过实现 LifecycleObserver
接口,开发者可以自自定 lifecycle-aware 组件,感知 Activity 或 Fragment 等 LifecycleOwner
的生命周期回调。
趁新版本发布之际,我们再回顾一下 Lifecycle 注解的使用以及废弃后的替代方案
Lifecycle Events & States
Lifecyce 使用两组枚举分别定义了 Event
和 State
。
Events
ON_CREATE ON_START ON_RESUME ON_PAUSE ON_STOP ON_DESTROY ON_ANY States
INITIALIZED CREATED STARTED RESUMED DESTROYED
Events 对应了 Activity 等原生系统组件的生命后期回调, 每当 Event 发生时意味着这些 LifecycleOwner 进入到一个新的 State。
作为 观察者的 LifecycleObserver 可以感知到 被观察者的 LifecycleOwner 其生命周期 State 变化时的 Event。定义 LifecycleObserver
有三种方式:
实现 LifecycleEventObserver
接口使用 @OnLifecycleEvent
注解
实现 LifecycleEventObserver
public interface LifecycleEventObserver extends LifecycleObserver {
void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event);
}
LifecycleEventObserver
是一个单方法接口,在 Kotlin 中可转为写法更简洁的 Lambda
进行声明
val myEventObserver = LifecycleEventObserver { source, event ->
when(event) {
Lifecycle.Event.ON_CREATE -> TODO()
Lifecycle.Event.ON_START -> TODO()
else -> TODO()
}
}
LifecycleEventObserver
本身就是 LifecycleObserver
的派生,使用时直接 addObserver
到 LivecycleOwner 的 Lifecycle 即可。
需要在 onStateChanged
中写 swich / case
自己分发事件。相对于习惯重写 Activity 或者 Fragment 的 onCreate
, onResume
等方法,稍显啰嗦。
因此 Lifecycle 给我们准备了 @OnLifecycleEvent
注解
使用 @OnLifecycleEvent 注解
使用方法很简单,继承 LifecycleObserver
接口,然后在成员方法上添加注解即可
val myEventObserver = object : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
fun onStart() {
TODO()
}
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
fun onCreat() {
TODO()
}
}
添加注册后,到 LifecycleOwner 的 Event 分发时,会自动回调注解匹配的成员方法,由于省去了手动 switch/case
的过程,深受开发者喜欢
注解解析过程
Event 分发时,怎么就会回到到注解对应的方法的?
通过 addObserver
添加的 LifecycleObserver ,都会转为一个 LifecycleEventObserver
,LifecycleOwner 通过调用其 onStateChanged
分发 Event
在 Lifecycling#lifecycleEventObserver
中处理转换
public class Lifecycling {
@NonNull
static LifecycleEventObserver lifecycleEventObserver(Object object) {
boolean isLifecycleEventObserver = object instanceof LifecycleEventObserver;
boolean isFullLifecycleObserver = object instanceof FullLifecycleObserver;
// 观察者是 FullLifecycleObserver
if (isLifecycleEventObserver && isFullLifecycleObserver) {
return new FullLifecycleObserverAdapter((FullLifecycleObserver) object,
(LifecycleEventObserver) object);
}
// 观察者是 LifecycleEventObserver
if (isFullLifecycleObserver) {
return new FullLifecycleObserverAdapter((FullLifecycleObserver) object, null);
}
if (isLifecycleEventObserver) {
return (LifecycleEventObserver) object;
}
final Class> klass = object.getClass();
int type = getObserverConstructorType(klass);
// 观察者是通过 apt 产生的类
if (type == GENERATED_CALLBACK) {
List> constructors =
sClassToAdapters.get(klass);
if (constructors.size() == 1) {
GeneratedAdapter generatedAdapter = createGeneratedAdapter(
constructors.get(0), object);
return new SingleGeneratedAdapterObserver(generatedAdapter);
}
GeneratedAdapter[] adapters = new GeneratedAdapter[constructors.size()];
for (int i = 0; i < constructors.size(); i++) {
adapters[i] = createGeneratedAdapter(constructors.get(i), object);
}
return new CompositeGeneratedAdaptersObserver(adapters);
}
// 观察者需要通过反射生成一个 wrapper
return new ReflectiveGenericLifecycleObserver(object);
}
...
public static String getAdapterName(String className) {
return className.replace(".", "_") + "_LifecycleAdapter";
}
}
逻辑很清晰,根据 LifecycleObserver 类型不用转成不同的 LifecycleEventObserver,
用一段伪代码梳理如下:
if (lifecycleObserver is FullLifecycleObserver) {
return FullLifecycleObserverAdapter // 后文介绍
} else if (lifecycleObserver is LifecycleEventObserver) {
return this
} else if (type == GENERATED_CALLBACK) {
return GeneratedAdaptersObserver
} else {// type == REFLECTIVE_CALLBACK
return ReflectiveGenericLifecycleObserver
}
注解有两种使用用途。
场景一:runtime 时期使用反射生成 wrapper
class ReflectiveGenericLifecycleObserver implements LifecycleEventObserver {
private final Object mWrapped;
private final CallbackInfo mInfo;
ReflectiveGenericLifecycleObserver(Object wrapped) {
mWrapped = wrapped;
mInfo = ClassesInfoCache.sInstance.getInfo(mWrapped.getClass());
}
@Override
public void onStateChanged(LifecycleOwner source, Event event) {
mInfo.invokeCallbacks(source, event, mWrapped);
}
}
CallbackInfo
是关键,通过反射收集当前 LifecycleObserver 的回调信息。onStateChanged
中通过反射调用时,不会因为因为缺少 method
报错。
场景二:编译时使用 apt 生成 className + _LifecycleAdapter
除了利用反射, Lifecycle 还提供了 apt 方式处理注解。
添加 gradle 依赖:
dependencies {
// java 写法
annotationProcessor "androidx.lifecycle:lifecycle-compiler:2.3.1"
// kotlin 写法
kapt "androidx.lifecycle:lifecycle-compiler:2.3.1"
}
这样在编译器就会根据 LifecyceObserver 类名生成一个添加 _LifecycleAdapter
后缀的类。比如我们加了 onCreat
和 onStart
的注解,生成的代码如下:
public class MyEventObserver_LifecycleAdapter implements GeneratedAdapter {
final MyEventObserver mReceiver;
MyEventObserver_LifecycleAdapter(MyEventObserver receiver) {
this.mReceiver = receiver;
}
@Override
public void callMethods(LifecycleOwner owner, Lifecycle.Event event, boolean onAny,
MethodCallsLogger logger) {
boolean hasLogger = logger != null;
if (onAny) {
return;
}
if (event == Lifecycle.Event.ON_CREATE) {
if (!hasLogger || logger.approveCall("onCreate", 1)) {
mReceiver.onCreate();
}
return;
}
if (event == Lifecycle.Event.ON_START) {
if (!hasLogger || logger.approveCall("onStart", 1)) {
mReceiver.onStart();
}
return;
}
}
}
apt 减少了反射的调用,性能更好,当然会牺牲一些编译速度。
为什么要使用注解
生命周期的 Event 种类很多,我们往往不需要全部实现,如过不使用注解,可能需要实现所有方法,产生额外的无用代码
上面代码中的 FullLifecycleObserver
就是一个全部方法的接口
interface FullLifecycleObserver extends LifecycleObserver {
void onCreate(LifecycleOwner owner);
void onStart(LifecycleOwner owner);
void onResume(LifecycleOwner owner);
void onPause(LifecycleOwner owner);
void onStop(LifecycleOwner owner);
void onDestroy(LifecycleOwner owner);
}
从接口不是 public
的( java 代码 ) 可以看出,官方也无意让我们使用这样的接口,增加开发者负担。
遭废弃的原因
既然注解这么好,为什么又要废弃呢?
This annotation required the usage of code generation or reflection, which should be avoided.
从官方文档的注释可以看到,注解要么依赖反射降低运行时性能,要么依靠 APT 降低编译速度,不是完美的方案。
我们之所引入注解,无非是不想多实现几个空方法。早期 Android 工程不支持 Java8 编译,接口没有 default 方法, 现如今 Java8 已经是默认配置,可以为接口添加 default 方法,此时注解已经失去了存在的意义。
如今官方推荐使用 DefaultLifecycleObserver
接口来定义你的 LifecycleObserver
public interface DefaultLifecycleObserver extends FullLifecycleObserver {
@Override
default void onCreate(@NonNull LifecycleOwner owner) {
}
@Override
default void onStart(@NonNull LifecycleOwner owner) {
}
@Override
default void onResume(@NonNull LifecycleOwner owner) {
}
@Override
default void onPause(@NonNull LifecycleOwner owner) {
}
@Override
default void onStop(@NonNull LifecycleOwner owner) {
}
@Override
default void onDestroy(@NonNull LifecycleOwner owner) {
}
}
FullLifecycleObserverAdapter
, 无脑回调 FullLifecycleObserver
即可
class FullLifecycleObserverAdapter implements GenericLifecycleObserver {
private final FullLifecycleObserver mObserver;
FullLifecycleObserverAdapter(FullLifecycleObserver observer) {
mObserver = observer;
}
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
switch (event) {
case ON_CREATE:
mObserver.onCreate(source);
break;
case ON_START:
mObserver.onStart(source);
break;
case ON_RESUME:
mObserver.onResume(source);
break;
case ON_PAUSE:
mObserver.onPause(source);
break;
case ON_STOP:
mObserver.onStop(source);
break;
case ON_DESTROY:
mObserver.onDestroy(source);
break;
case ON_ANY:
throw new IllegalArgumentException("ON_ANY must not been send by anybody");
}
}
}
需要注意 DefaultLifecycleObserver
在 2.4.0 之前也是可以使用的, 存在于 androidx.lifecycle.lifecycle-common-java8
这个库中, 2.4.0 开始 统一移动到 androidx.lifecycle.lifecycle-common
了 ,已经没有 java8 单独的扩展库了。
• 耗时2年,Android进阶三部曲第三部《Android进阶指北》出版!
为了防止失联,欢迎关注我的小号
微信改了推送机制,真爱请星标本公号👇