添加相关依赖java
LiveData 有两种使用方式,结合 ViewModel 使用以及直接继承 LiveData 类。android
结合 ViewModel 使用git
如下代码场景:点击按钮提示一个名字。github
class MyViewModel : ViewModel() {
// 建立一个 String 类型的 LiveData
// MutableLiveData 是抽象类 LiveData 的子类,咱们通常使用的是 MutableLiveData
private lateinit var name: MutableLiveData<String>
fun getName(): MutableLiveData<String> {
if (!::name.isInitialized) {
name = MutableLiveData()
}
return name
}
}
复制代码
class LiveDataActivity : AppCompatActivity() {
private lateinit var myViewModel: MyViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_live_data)
// 建立并注册观察者
myViewModel = ViewModelProviders.of(this).get(MyViewModel::class.java)
myViewModel.getName().observe(this, Observer {
// LiveData 数据更新回调,it 表明被观察对象的数据,此处为 name
Toast.makeText(baseContext, it, Toast.LENGTH_SHORT).show()
})
btnSetName.setOnClickListener {
// 使用 setValue 的方式更新 LiveData 数据
myViewModel.getName().value = "张三"
}
}
}
复制代码
让数据(name)和组件(LiveDataActivity)分离,当 Activity 重建时,数据(name)不会丢失。架构
直接继承 LiveData 类app
如下代码场景:在 Activity 中监听 Wifi 信号强度。ide
class WifiLiveData private constructor(context: Context) : LiveData<Int>() {
private var mContext: WeakReference<Context> = WeakReference(context)
companion object {
private var instance: WifiLiveData? = null
fun getInstance(context: Context): WifiLiveData {
if (instance == null) {
instance = WifiLiveData(context)
}
return instance!!
}
}
override fun onActive() {
super.onActive()
registerReceiver()
}
override fun onInactive() {
super.onInactive()
unregisterReceiver()
}
/** * 注册广播,监听 Wifi 信号强度 */
private fun registerReceiver() {
val intentFilter = IntentFilter()
intentFilter.addAction(WifiManager.RSSI_CHANGED_ACTION)
mContext.get()!!.registerReceiver(mReceiver, intentFilter)
}
/** * 注销广播 */
private fun unregisterReceiver() {
mContext.get()!!.unregisterReceiver(mReceiver)
}
private val mReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent) {
when (intent.action) {
WifiManager.RSSI_CHANGED_ACTION -> getWifiLevel()
}
}
}
private fun getWifiLevel() {
val wifiManager = mContext.get()!!.applicationContext.getSystemService(android.content.Context.WIFI_SERVICE) as WifiManager
val wifiInfo = wifiManager.connectionInfo
val level = wifiInfo.rssi
instance!!.value = level // 发送 Wifi 的信号强度给观察者
}
}
复制代码
class LiveDataActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_live_data)
withExtendsLiveDataTest()
}
/** * 直接继承 LiveData 类 */
private fun withExtendsLiveDataTest() {
WifiLiveData.getInstance(this).observe(this, Observer {
Log.e("LiveDataActivity", it.toString()) // 观察者收到数据更新的通知,打印 Wifi 信号强度
})
}
}
复制代码
当组件(Activity)处于激活状态(onActive)时注册广播,处于非激活状态(onInactive)时注销广播。post
LiveData 经过 observe() 方法将被观察者 LifecycleOwner (Activity / Fragment) 和观察者 Observer 关联起来。ui
LiveData.observe(LifecycleOwner owner , Observer<T> observer)
复制代码
进入 LiveData 的 observe() 方法中this
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// 若 LifecycleOwner 处于 DESTROYED 状态,则返回
return;
}
// LifecycleBoundObserver 把 LifecycleOwner 对象和 Observer 对象包装在一块儿
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
// mObservers(相似 Map 的容器)的 putIfAbsent() 方法用于判断容器中的 observer(key)
// 是否已有 wrapper(value)与之关联
// 若已关联则直接返回关联值,不然关联后再返回 wrapper
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;
}
// 因为 LifecycleBoundObserver 实现了 GenericLifecycleObserver 接口,而 GenericLifecycleObserver 又
// 继承了 LifecycleObserver,因此 LifecycleBoundObserver 本质是一个 LifecycleObserver
// 此处属于注册过程, Lifecycle 添加观察者 LifecycleObserver
owner.getLifecycle().addObserver(wrapper);
}
复制代码
从上面的代码可知,observe() 方法最终是会调用 LifecycleOwner.getLifecycle().addObserver(LifecycleObserver) ,所以 LiveData 是可以感知观察者的生命周期变化的。
经过以上的分析,咱们知道 LifecycleBoundObserver(LiveData 的内部类)是观察者,如下具体分析 LifecycleBoundObserver 的实现过程。
class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
@NonNull final LifecycleOwner mOwner;
LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<T> observer) {
super(observer); // 保存 Observer
mOwner = owner; // 保存 LifecycleOwner
}
@Override
boolean shouldBeActive() {
// 判断是否处于激活状态
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
// 若 Lifecycle 处于 DESTROYED 状态,则移除 Observer 对象
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
// 移除观察者,在这个方法中会移除生命周期监听而且回调 activeStateChanged() 方法
removeObserver(mObserver);
return;
}
// 若处于激活状态,则调用 activeStateChanged() 方法
activeStateChanged(shouldBeActive());
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
复制代码
当组件(Activity / Fragment)的生命周期发生改变时,onStateChanged() 方法将会被调用。若当前处于 DESTROYED 状态,则会移除观察者;若当前处于激活状态,则会调用 activeStateChanged() 方法。activeStateChanged() 方法位于父类 ObserverWrapper 中。
void activeStateChanged(boolean newActive) {
// 若新旧状态一致,则返回
if (newActive == mActive) {
return;
}
// immediately set active state, so we'd never dispatch anything to inactive owner
mActive = newActive;
boolean wasInactive = LiveData.this.mActiveCount == 0;
LiveData.this.mActiveCount += mActive ? 1 : -1;
if (wasInactive && mActive) { // 激活状态的 observer 个数从 0 到 1
onActive(); // 空实现,通常让子类去重写
}
if (LiveData.this.mActiveCount == 0 && !mActive) { // 激活状态的 observer 个数从 1 到 0
onInactive(); // 空实现,通常让子类去重写
}
if (mActive) { // 激活状态,向观察者发送 LiveData 的值
dispatchingValue(this);
}
}
复制代码
再看看最终调用的 dispatchingValue() 方法。
private void dispatchingValue(@Nullable ObserverWrapper initiator) {
// ...
do {
mDispatchInvalidated = false;
if (initiator != null) {
considerNotify(initiator);
initiator = null;
} else {
// 循环遍历 mObservers 这个 map , 向每个观察者都发送新的数据
for (Iterator<Map.Entry<Observer<T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
// ...
}
复制代码
能够看到 dispatchingValue() 方法里面再经过 considerNotify() 方法将消息通知下去。
private void considerNotify(ObserverWrapper observer) {
// ...
observer.mObserver.onChanged((T) mData);
}
复制代码
上面的 mObserver 正是咱们调用 observe() 方法时传入的观察者。
总结上面的分析就是:调用 LiveData.observe(LifecycleOwner owner , Observer observer) 进行注册后,当 LiveData 数据发生变化后,最终就会调用 Observer 对象的 onChanged() 方法,并把变化的数据做为参数回传。
LiveData 为咱们提供了两种改变数据后,通知观察者更新数据的方式,一个是 setValue() 方法(必须在主线程调用),另外一个是 postValue() 方法(必须在子线程调用)。
setValue() 方法
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
复制代码
dispatchingValue() 方法会跑咱们上面分析的流程,最终把改变的数据 value(对应上面的 mData)做为 onChanged() 方法的参数传给观察者。
postValue() 方法
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
private final Runnable mPostValueRunnable = new Runnable() {
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
//noinspection unchecked
setValue((T) newValue);
}
};
复制代码
能够看出 postValue() 方法最终也会在主线程中调用 setValue() 方法。
参考资料: