Jetpack:Lifecycle 和 LiveData

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

在讲解 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
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值