LiveData的使用及原理

举报
yd_221104950 发表于 2020/12/20 00:32:01 2020/12/20
【摘要】 LiveData的使用及原理 1.LiveData的使用2.原理3.自定义LiveData LiveData是一个 可观察的数据持有类,它与常见的可观察对象不同的是它有生命周期意识,即它能够感知组件,如activities, fragments, services等的生命周期变化。以前我们可会用EventBus来做事件传递,现在用LiveData也是不错...


可观察的数据持有类

1.LiveData的使用

  • 使用添加依赖项grale.build(:app)
dependencies { ... def lifecycle_version = "2.2.0" implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version" implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 在Activity中使用
...
LiveData<String> liveData
@Override
protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.activity_main);
	LiveData<String> liveData = new LiveData<String>;
	liveData.postValue("Hello");// 发消息
	liveData.setValue("world");// 发消息
	button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { liveData.observe(MainActivity.this, new Observer<String>() { @Override public void onChanged(String s) { Log.i("接收到数据",s+""); if (id == binding.button.getId()) { binding.button.setText(s); } if (id == binding.button2.getId()) { binding.button2.setText(s); } } });
	}
  });
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

2.原理

LiveData发送数据使用setValuepostValue,它们的区别是setValue直接在主线程中进行,postValue则是在子线程进行的。所以当你的数据要在子线程发出来的,应该选用postValue,否则使用setValue

liveData.observe(LifecycleOwner, Observer<? super T> )这个方法是用来注册观察者的。注册的过程是这样的:
在这里插入图片描述

@MainThread public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) { assertMainThread("observe"); if (owner.getLifecycle().getCurrentState() == DESTROYED) { // ignore return; } LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer); 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; } owner.getLifecycle().addObserver(wrapper); }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  1. 首先,注册所在的控件的生命状态是不是已销毁了,如是就不再注册,否则继续注册。
  2. LifecycleBoundObserver wrapper将我们的观察者进行打包,打包成一个LifecycleEventObserver观察者,这个观察者专门用于组件生命周期的观察的。
  3. 最后,将观察者注册到组件的生命周期的可观察对象上。
    也就是说,android本身是有这个生命周期观察机制的,这就给我们LiveData感知组件生命周期创造了条件,我们只是在这个机制上添加了一些我们的东西而已。

LifecycleBoundObserver的UML图:
在这里插入图片描述

LifecycleEventObserver接口中有一个方法onStateChanged,当组件的生命周期发生改变时,就会被调用:

public interface LifecycleEventObserver extends LifecycleObserver { /** * Called when a state transition event happens. * * @param source The source of the event * @param event The event */ void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event);
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

LiveData对这个方法的实现是这样的:

@Override
public void onStateChanged(@NonNull LifecycleOwner source,@NonNull Lifecycle.Event event) { if (mOwner.getLifecycle().getCurrentState() == DESTROYED) { removeObserver(mObserver); return; } activeStateChanged(shouldBeActive());
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

也就是说,LiveData它会在这个方法里观察所在组件的生命状态,如果是已销毁的,那么它就将观察者移除,否则,它就会调用activeStateChanged方法,将数据分发出去:

void activeStateChanged(boolean newActive) {
...
	if (mActive) { dispatchingValue(this); }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

具体分发数据是由dispatchingValue来实现的

void dispatchingValue(@Nullable ObserverWrapper initiator) {
... 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; } } }
...
}
private void considerNotify(ObserverWrapper observer) { ... if (observer.mLastVersion >= mVersion) { return; } observer.mLastVersion = mVersion; observer.mObserver.onChanged((T) mData); }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

dispatchingValue分派事件是这样来进行的,传入的观察者initiator不为空,则执行该观察者的事件,否则就遍历所有观察者,并执行它的事件。我们刚刚是注册观察者,因此,会执行该观察者的事件onChanged,事件会把之前的数据拿过来,这就是所谓的粘性事件。postValuesetValue事件就会遍历所有的观察者,进行数据分发。

postValuesetValue事件都会直接去分派事件,postValue最后还是调回了setValue

private final Runnable mPostValueRunnable = new Runnable() { @SuppressWarnings("unchecked") @Override public void run() { Object newValue; synchronized (mDataLock) { newValue = mPendingData; mPendingData = NOT_SET; } setValue((T) newValue); } };
protected void postValue(T value) { boolean postTask; synchronized (mDataLock) { postTask = mPendingData == NOT_SET; mPendingData = value; } if (!postTask) { return; } ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable); } protected void setValue(T value) { assertMainThread("setValue"); mVersion++; mData = value; dispatchingValue(null); }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

正如上面所见的,postValuesetValue都会修改mData的值,mData是持有需要传递的数据的变量。因此:

liveData.postValue("Hello");// 发消息
liveData.setValue("world");// 发消息

  
 
  • 1
  • 2

结果是mData = “world”

3.自定义LiveData

我们自己实现一个WnLiveData:

package com.wong.livedatademo;

import android.annotation.SuppressLint;

import androidx.annotation.NonNull;
import androidx.arch.core.executor.ArchTaskExecutor;
import androidx.arch.core.internal.SafeIterableMap;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleEventObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;

import static androidx.lifecycle.Lifecycle.State.DESTROYED;
import static androidx.lifecycle.Lifecycle.State.STARTED;

public class WnLiveData<T> { private Object NOT_SET = new Object(); // 存入的数据 private T mData; // 生命周期 private LifecycleOwner owner; // 存放观察者对象 private Map<Observer<? super T>, WnLifecycleObserver> mObservers = new HashMap<>(); private int mVersion; volatile Object mPendingData = new Object(); final Object mDataLock = new Object(); private final Runnable mPostValueRunnable = new Runnable() { @SuppressWarnings("unchecked") @Override public void run() { Object newValue; synchronized (mDataLock) { newValue = mPendingData; mPendingData = NOT_SET; } setValue((T) newValue); } }; // 非主线程中使用 @SuppressLint("RestrictedApi") public void postValue(T value) { synchronized (mDataLock) { mPendingData = value; } ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable); } public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) { if (owner.getLifecycle().getCurrentState() == DESTROYED) { return; } WnLifecycleObserver wrapper = new WnLifecycleObserver(owner, observer); mObservers.put(observer,wrapper); owner.getLifecycle().addObserver(wrapper); } // 在主线程中使用 public void setValue(T value) { mVersion++; mData = value; dispatchingValue(null); } private class WnLifecycleObserver implements LifecycleEventObserver { final Observer<? super T> mObserver; boolean mActive; int mLastVersion = -1; @NonNull final LifecycleOwner mOwner; private WnLifecycleObserver(@NonNull LifecycleOwner mOwner,Observer<? super T> mObserver) { this.mObserver = mObserver; this.mOwner = mOwner; } @Override public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) { if (mOwner.getLifecycle().getCurrentState() == DESTROYED) { WnLifecycleObserver removed = mObservers.remove(mObserver); return; } boolean newActive = mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED); if (newActive == mActive) { return; } mActive = newActive; if (mActive) { dispatchingValue(this); } } } private void dispatchingValue(WnLifecycleObserver observer) { if (observer != null) { notify(observer); } else { for (Map.Entry<Observer<? super T>, WnLifecycleObserver> observerWnLifecycleObserverEntry : mObservers.entrySet()) { notify(observerWnLifecycleObserverEntry.getValue()); } } } private void notify(WnLifecycleObserver observer) { if (!observer.mActive) { return; } if (observer.mLastVersion >= mVersion) { return; } observer.mLastVersion = mVersion; observer.mObserver.onChanged((T) mData); }
}


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127

Demo

文章来源: blog.csdn.net,作者:WongKyunban,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/weixin_40763897/article/details/111396864

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。