文章目录
在讲解 Lifecycle 和 LiveData 之前,有必要说明下 Jetpack,官方对 Jetpack 的描述如下:
Jetpack 是一个由多个库组成的套件,可帮助开发者遵循最佳做法、减少样板代码并编写可在各种 Android 版本和设备中一致运行的代码,让开发者可将精力集中于真正重要的编码工作。
简单理解 Jetpack,它是由多个库组成的、版本兼容的、让我们专注于业务代码的套件。
其中 Lifecycle 和 LiveData 是 Jetpack 中的两个组件,也是比较重要的两个库;LiveData 使用了 Lifecycle,所以我们会先从 Lifecycle 开始讲起,然后再讲解 LiveData,这样会更方便原理。
Lifecycle
Lifecycle 的使用
我们可以先思考一个问题:为什么需要 Lifecycle?
在没有 Lifecycle 之前,如果我们实现 MVP 架构,要在 Presenter 能知道 Activity 的生命周期,一般会这么写:
public interface ILifecycle {
void onCreate();
void onDestroy();
}
public class MyPresenter implements ILifecycle {
@Override
public void onCreate() {
}
@Override
public void onDestroy() {
}
}
public class MainActivity extends AppCompatActivity {
private Presenter presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCraete(savedInstanceState);
presenter = new MyPresenter();
presenter.onCreate();
}
@Override
protected void onDestroy() {
super.onDestroy();
presenter.onDestroy();
}
}
这种其实都是样板代码,虽然也能实现但却存在一些问题:
-
编码疏忽没有及时移除引用,容易产生内存泄漏
-
和 Activity 耦合侵入性强,只要有改动其他 Activity 都要修改,不好维护
所以 Google 为了我们能更专注的写业务代码,提供了 Lifecycle。
Lifecycle 是根据观察者模式设计的,既然是观察者模式,就有观察者和被观察者。其中 被观察者需要实现 LifecycleOwner 接口,观察者需要实现 LifecycleObserver 接口。
在 Android 已经默认将 Activity/Fragment 实现 LifecycleOwner 作为被观察者,当 Activity/Fragment 的生命周期变化时,就会通知到观察者。
public class ComponentActivity extends androidx.core.app.ComponentActivity implements
LifecycleOwner,
ViewModelStoreOwner,
SavedStateRegistryOwner,
OnBackPressedDispatcherOwner {
...
}
public class MyClass implements LifecycleObserver {
// 各个生命周期调用通知
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
void onCreate(LifecycleOwner owner) {
}
@OnLifecycleEvent(Lifecycle.Event.ON_START)
void onStart(LifecycleOwner owner) {
}
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
void onResume(LifecycleOwner owner) {
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
void onPause(LifecycleOwner owner) {
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
void onStop(LifecycleOwner owner) {
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
void onDestroy(LifecycleOwner owner) {
}
}
被观察者需要能通知到观察者,两者还要建立订阅关系。只需要在 Activity/Fragment 调用 getLifecycle().addObserver() 将观察者传入参数即可:
public class MyActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyClass myclass = new MyClass();
getLifecycle().addObserver(myClass);
}
}
Lifecycle 的使用非常简单,只需要建立订阅关系,观察者就能在生命周期变化时收到通知,而取消订阅 Lifecycle 已经帮我们做了处理,这能有效的帮助我们解决编码疏忽导致内存泄漏的隐患。
Lifecycle 的实现原理
Lifecycle 订阅观察者是使用 getLifecycle().addObserver(),具体看下它做了什么事情:
Lifecycle.java
public abstract class Lifecycle {
...
@MainThread
public abstract void addObserver(@NonNull LifecycleObserver observer);
}
LifecycleRegistry.java
@Override
public void addObserver(@NonNull LifecycleObserver observer) {
// 这里有一个 mState 的状态,我们后面讲
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
// 将我们传进来的 LifecycleObserver 包装成新的对象
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
// 将我们传进来的 LifecycleObserver 作为 key,包装对象为 value 存进 map
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
...
}
addObserver() 第一步是将我们传进来的 LifecycleObserver 包装成一个新对象,然后将包装对象又存进了 mObserverMap。mObserverMap 存放了订阅了 Activity 的所有观察者。
为什么要对观察者再包装一层呢?我们看下 ObserverWithState 做了什么事情:
LifecycleRegistry.java
static class ObserverWithState {
State mState;
LifecycleEventObserver mLifecycleObserver;
ObserverWithState(LifecycleObserver observer, State initialState) {
mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
mState = initialState;
}
...
}
Lifecycling.java
@NonNull
static LifecycleEventObserver lifecycleEventObserver(Object object) {
...
return new ReflectiveGenericLifecycleObserver(object);
}
ReflectiveGenericLifecycleObserver.java
class ReflectiveGenericLifecycleObserver implements LifecycleEventObserver {
private final Object mWrapped;
private final CallbackInfo mInfo;
ReflectiveGenericLifecycleObserver(Object wrapped) {
mWrapped = wrapped;
mInfo = ClassesInfoCache.sInstance.getInfo(mWrapped.getClass());
}
}
ClassInfoCache.java
CallbackInfo getInfo(Class klass) {
CallbackInfo existing = mCallbackMap.get(klass);
if (existing != null) {
return existing;
}
existing = createInfo(klass, null);
return existing;
}
private CallbackInfo createInfo(Class klass, @Nullable Method[] declaredMethods) {
Map<MethodReference, Lifecycle.Event> handlerToEvent = new HashMap<>();
...
// 获取到观察者对象的所有方法
Method[] methods = declaredMethods != null ? declaredMethods : getDeclaredMethods(klass);
boolean hasLifecycleMethods = false;
for (Method method : methods) {
// 找到所有添加了 @OnLifecycleEvent 注解的方法
OnLifecycleEvent annotation = method.getAnnotation(OnLifecycleEvent.class);
if (annotation == null) {
continue;
}
hasLifecycleMethods = true;
Class<?>[] params = method.getParameterTypes();
// CALL_TYPE_NO_ARG = 0
// CALL_TYPE_PROVIDER = 1
// CALL_TYPE_PROVIDER_WITH_EVENT = 2
int callType = CALL_TYPE_NO_ARG;
if (params.length > 0) {
callType = CALL_TYPE_PROVIDER;
...
}
Lifecycle.Event event = annotation.value();
if (params.length > 1) {
callType = CALL_TYPE_PROVIDER_WITH_EVENT;
...
}
...
// 将观察者所有带了 @OnLifecycleEvent 注解的方法存到 handlerToEvent 这个 map
MethodReference methodReference = new MethodReference(callType, method);
verifyAndPutHandler(handlerToEvent, methodReference, event, klass);
}
// 所以 CallbackInfo 持有了观察者所有添加了 @OnLifecycleEvent 的方法
CallbackInfo info = new CallbackInfo(handlerToEvent);
...
return info;
}
ObserverWithState 这个包装对象在创建时主要做了一件事情:将观察者对象 class 的所有带 @OnLifecycleEvent 注解的方法都找出来存到一个 map,将 map 包装为 CallbackInfo。
按照这种设计我们可以猜测,在 Activity/Fragment 生命周期改变的时候,就可以先找到 mObserverMap 拿到所有的观察者,然后找到 ObserverWithState 的 mInfo 反射调用添加了 @LifecycleEvent 注解的方法。这样就能完成生命周期变化时的通知:

现在只是完成观察者和被观察者建立订阅的操作,那么生命周期是怎么通知到观察者的?
ComponentActivity.java
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
ReportFragment.injectIfNeededIn(this);
...
}
ReportFragment.java
public static void injectIfNeededIn(Activity activity) {
// ProcessLifecycleOwner should always correctly work and some activities may not extend
// FragmentActivity from support lib, so we use framework fragments for activities
android.app.FragmentManager manager = activity.getFragmentManager();
if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
manager.beginTransaction

本文深入讲解了Jetpack组件Lifecycle和LiveData的使用与实现原理。Lifecycle通过观察者模式和状态机管理活动周期,确保准确地通知观察者。LiveData作为生命周期感知的数据持有类,能够保证UI与数据同步更新,同时分析了其粘性事件特性和递归调用的容错机制。
最低0.47元/天 解锁文章
1726

被折叠的 条评论
为什么被折叠?



