在build.gradle(app)中添加依赖
dependencies {
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0-rc01"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.0-rc01"
}
自定义viewModel,持有LiveData
class MessageViewModel:ViewModel() {
val message : MutableLiveData<String> by lazy {
MutableLiveData<String>()
}
}
MainActivity中代码如下
class MainActivity : AppCompatActivity() {
private lateinit var binding:ActivityMainBinding
companion object{
@JvmField
var viewModel = MessageViewModel()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
initView()
}
private fun initView(){
with(binding){
//观察者
var count = 0
val observer = Observer<String>{
Log.d("debug", it)
tvMessage.text = it
}
//添加观察者
viewModel.message.observe(this@MainActivity,observer)
//在主线程中更新内容
sendMessageInMainThread.setOnClickListener {
viewModel.message.value = "在主线程中更新内容---$count"
}
//在子线程中更新内容
sendMessageInSonThread.setOnClickListener {
Thread{
viewModel.message.postValue("在子线程中更新内容---$count")
count++
}.run()
}
}
}
}
先找到添加观察者的入口
viewModel.message.observe(this@MainActivity,observer)
点击进入LiveData的observe()中
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
//检查是否在主线程中调用observe(),如果不是抛出异常
assertMainThread("observe");
//检查Activity/Fragment的状态,如果已经DESTROYED,则直接退出,不用继续往下走
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
//这里创建一个带生命周期的观察者对象
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
//将这个观察者放入Map中,根据返回值,判断这个带生命周期的观察者是否和多个被观察者绑定,
//如果和多个被观察者绑定则抛出异常
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
if (existing != null && !existing.isAttachedTo(owner)) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
//这里获取Lifecycle的唯一实现类LifecycleRegistry的实例,将这个带生命周期的观察者添加进去
owner.getLifecycle().addObserver(wrapper);
}
点击addObserver(),进入LifecycleRegistry的方法中
@Override
public void addObserver(@NonNull LifecycleObserver observer) {
enforceMainThreadIfNeeded("addObserver");
//初始化刚加入的LifecycleBoundObserver对象的状态,默认为INITIALIZED
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
//同时使用带生命周期的observer和初始化状态生成一个带状态和生命周期的observer,
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
//检查这个observer是否存在
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
if (previous != null) {
return;
}
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
//检查宿主是否被销毁了
if (lifecycleOwner == null) {
// it is null we should be destroyed. Fallback quickly
return;
}
//重入标志,
boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
//计算observer要到达的状态,这里使用状态机
State targetState = calculateTargetState(observer);
mAddingObserverCounter++;
//进行状态同步,和targetState进行比较
while ((statefulObserver.mState.compareTo(targetState) < 0
&& mObserverMap.contains(observer))) {
//将当前这个statefulObserver的状态压入栈中,
//private ArrayList mParentStates = new ArrayList<>();
//这是个ArrayList线程不安全
pushParentState(statefulObserver.mState);
final Event event = Event.upFrom(statefulObserver.mState);
if (event == null) {
throw new IllegalStateException("no event up from " + statefulObserver.mState);
}
//进行事件分发
statefulObserver.dispatchEvent(lifecycleOwner, event);
//
popParentState();
// mState / subling may have been changed recalculate
//更新targetState
targetState = calculateTargetState(observer);
}
if (!isReentrance) {
// we do sync only on the top level.
sync();
}
mAddingObserverCounter--;
}
进入同步
// happens only on the top of stack (never in reentrance),
// so it doesn't have to take in account parents
private void sync() {
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
throw new IllegalStateException("LifecycleOwner of this LifecycleRegistry is already"
+ "garbage collected. It is too late to change lifecycle state.");
}
while (!isSynced()) {
//这里和moveToState()的mNewEventOccurred 一致
mNewEventOccurred = false;
// no need to check eldest for nullability, because isSynced does it for us.
//无须检查 eldest的是否为空,isSynced()中已经帮我们做了
//LifecycleRegister的状态和当前栈中最底层的observer的状态比较
if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
//调整LifecycleOwner的state,降级
backwardPass(lifecycleOwner);
}
//LifecycleRegister的状态和当前栈中最顶层的observer的状态比较
Map.Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
if (!mNewEventOccurred && newest != null
&& mState.compareTo(newest.getValue().mState) > 0) {
//将lifecycleOwner的状态升级
forwardPass(lifecycleOwner);
}
}
mNewEventOccurred = false;
}
关于这个状态的升级和降级和Activity的生命周期相关,下面代码是Lifecycle中的具体实现
@NonNull
public State getTargetState() {
switch (this) {
case ON_CREATE:
case ON_STOP:
return State.CREATED;
case ON_START:
case ON_PAUSE:
return State.STARTED;
case ON_RESUME:
return State.RESUMED;
case ON_DESTROY:
return State.DESTROYED;
case ON_ANY:
break;
}
throw new IllegalArgumentException(this + " has no target state");
}
private boolean isSynced() {
if (mObserverMap.size() == 0) {
return true;
}
State eldestObserverState = mObserverMap.eldest().getValue().mState;
State newestObserverState = mObserverMap.newest().getValue().mState;
return eldestObserverState == newestObserverState && mState == newestObserverState;
}
viewModel.message.value = "在主线程中更新内容---$count"
从setValue这里进入,发现使用了父类LiveData的方法
@Override
public void setValue(T value) {
super.setValue(value);
}
进入LiveData中setValue(T value)
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
//将版本+1,初始值为 0
mVersion++;
mData = value;
//如果有活跃的观察者,则分配值给他们
dispatchingValue(null);
}
继续跟踪进入 dispatchingValue()
@SuppressWarnings("WeakerAccess") /* synthetic access */
void dispatchingValue(@Nullable ObserverWrapper initiator) {
//其中mSispatchingValue ,表示是否正在分发值
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
//这里做了个循环,mDispatchInvalidated 表示是否同时有其他线程调用分发
mDispatchInvalidated = false;
if (initiator != null) {
considerNotify(initiator);
initiator = null;
} else {
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
//如果有其他线程也在分发数据,立即停止分发,跳出循环
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
进入到considerNotify()
@SuppressWarnings("unchecked")
private void considerNotify(ObserverWrapper observer) {
if (!observer.mActive) {
return;
}
// Check latest state b4 dispatch. Maybe it changed state but we didn't get the event yet.
//
// we still first check observer.active to keep it as the entrance for events. So even if
// the observer moved to an active state, if we've not received that event, we better not
// notify for a more predictable notification order.
//观察者是否存活
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
if (observer.mLastVersion >= mVersion) {
return;
}
//更新版本号
observer.mLastVersion = mVersion;
//回调匿名内部类,观察者接收到信息,更新内容流程结束
observer.mObserver.onChanged((T) mData);
}
这里Google官方用了一个比较奇妙的方法,因为Fragment的生命周期会跟随Activity的生命周期发生变化,
所以Google使用了一个无界面ReportFragment来感知生命周期的变化,当生命周期发生变化时,分发事件
在ComponentActivity的onCreate()方法中
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
// Restore the Saved State first so that it is available to
// OnContextAvailableListener instances
mSavedStateRegistryController.performRestore(savedInstanceState);
mContextAwareHelper.dispatchOnContextAvailable(this);
super.onCreate(savedInstanceState);
mActivityResultRegistry.onRestoreInstanceState(savedInstanceState);
//这里进行注入
ReportFragment.injectIfNeededIn(this);
if (mContentLayoutId != 0) {
setContentView(mContentLayoutId);
}
}
进入ReportFragment的injectIfNeededIn()中
public static void injectIfNeededIn(Activity activity) {
if (Build.VERSION.SDK_INT >= 29) {
// 在 API 29+ 上,我们可以直接注册正确的生命周期回调
LifecycleCallbacks.registerIn(activity);
}
/**
在 API 29 之前并保持与旧版本的 ProcessLifecycleOwner 的兼容性
(更新生命周期运行时可能不会更新,并且需要支持不从支持 lib 扩展的 FragmentActivity 的活动)
,使用框架片段来获得正确的生命周期事件的时间安排
*/
android.app.FragmentManager manager = activity.getFragmentManager();
if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
// Hopefully, we are the first to make a transaction.
manager.executePendingTransactions();
}
}
最终调用的是dispatch()
@SuppressWarnings("deprecation")
static void dispatch(@NonNull Activity activity, @NonNull Lifecycle.Event event) {
if (activity instanceof LifecycleRegistryOwner) {
((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);
return;
}
if (activity instanceof LifecycleOwner) {
Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
if (lifecycle instanceof LifecycleRegistry) {
((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
}
}
}
handleLifecycleEvent是属于LifecycleRegistry,那么终于都连起来了,
进入到handleLifeCycleEvent中
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
enforceMainThreadIfNeeded("handleLifecycleEvent");
moveToState(event.getTargetState());
}
//进行状态转移
private void moveToState(State next) {
if (mState == next) {
return;
}
mState = next;
if (mHandlingEvent || mAddingObserverCounter != 0) {
mNewEventOccurred = true;
// we will figure out what to do on upper level.
return;
}
mHandlingEvent = true;
//同步所有观察者,并进行事件分发
sync();
mHandlingEvent = false;
}
粘性事件的定义是什么?
即发射的事件如果早于注册,那么注册之后依然可以接收到的事件称为粘性事件,举个栗子,比如我在2022年订阅了一份广州日报,但是你还给我推送2019年的报纸,那就不厚道了,参考了博主我星空的文章:http://t.csdn.cn/w35CO看下源码,主要的原因是
@SuppressWarnings("unchecked")
private void considerNotify(ObserverWrapper observer) {
//1
if (!observer.mActive) {
return;
}
// Check latest state b4 dispatch. Maybe it changed state but we didn't get the event yet.
//
// we still first check observer.active to keep it as the entrance for events. So even if
// the observer moved to an active state, if we've not received that event, we better not
// notify for a more predictable notification order.
//2
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
//一般事件流程 :new Observe(mVersion=-1)-> 注册观察者(mLastVersion=-1)-> setValue(mVersion++)
//粘性事件的流程 :new Observe(mVersion=-1)-> setValue(mVersion++) ->注册观察者(mLastVersion=-1)
//此时 mLastVersion=-1 , mVersion=0 ,未触发拦截导致首次注册时会触发接口回调造成粘性事件
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
observer.mObserver.onChanged((T) mData);
}
解决方法是第一次进行拦截,不让livedate进行事件分发,注释1 和注释2 处的代码涉及到Framework层的代码,不好动,只能在第mLaseVersion 和mVersion上动手脚,在注册观察者时,通过反射修改mLastVersion的值,使得mLastVersion 和mVersion的值相等,那么就可以直接返回,不进行事件分发
class NonStickyMutableLiveData<T> : MutableLiveData<T>() {
private var stickFlag = true
override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {
super.observe(owner, observer)
if (stickFlag) {
hook(observer)
}
}
private fun hook(observer: Observer<in T>) {
try {
val liveDataClass = LiveData::class.java
val mObserversField = liveDataClass.getDeclaredField("mObservers")
mObserversField.isAccessible = true
val mObserversObject = mObserversField[this]
//得到map对应的class对象
val mObserversClass: Class<*> = mObserversObject.javaClass
//获取到mObserversClass对象的get()
val get = mObserversClass.getDeclaredMethod("get", Any::class.java)
get.isAccessible = true
//执行get方法
val invokeEntry = get.invoke(mObserversObject, observer)
//定义一个空对象
var observerWrapper: Any? = null
if (invokeEntry != null && invokeEntry is Map.Entry<*, *>) {
observerWrapper = invokeEntry.value
}
if (observerWrapper == null) {
throw NullPointerException("observerWrapper is null")
}
//得到ObserverWrapper的类对象,编译擦除问题会引起多态冲突所以用getSuperClass
val superClass: Class<*> = observerWrapper.javaClass.superclass
val mLastVersion = superClass.getDeclaredField("mLastVersion")
mLastVersion.isAccessible = true
//得到mversion
val mVersion = liveDataClass.getDeclaredField("mVersion")
mVersion.isAccessible = true
//将mVersion的值填入到mLastVersion
val mVersionValue = mVersion[this]
mLastVersion[observerWrapper] = mVersionValue
stickFlag = false
} catch (e: Exception) {
e.printStackTrace()
}
}
}