LiveData 是一个持有数据的类,它持有的数据是可以被观察者订阅的,当数据被修改时就会通知观察者。观察者可以是 Activity、Fragment、Service 等。 首先看它的使用,一种方式我们已经用过了,即与ViewModel一起使用,这里就不在赘述,另一种方式是直接继承LiveData。比如实现wifi信号值的监听
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 的信号强度给观察者
}
}
因为LiveData 能够感知观察者的生命周期,只有当观察者处于激活状态(STARTED、RESUMED)才会接收到数据更新的通知,在未激活时会自动解注册观察者,以减少内存泄漏。所以继承LiveData时需要实现onActive及onInactive方法。那么上面最重要的就是这两个方法了,那么又是如何将值通知给观察者的呢,这里就看最后一行代码其实调用的是LiveData中的setValue方法,这与之前的ViewModel中的使用(postValue)其实是一样的。之前在viewModel中使用的MutableLiveData其实也是继承了LiveData,他的实现如下
public class MutableLiveData<T> extends LiveData<T> {
@Override
public void postValue(T value) {
super.postValue(value);
}
@Override
public void setValue(T value) {
super.setValue(value);
}
}
使用时还利用上节中的ViewModel所使用的activity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// 获取factory
val factory: ViewModelProvider.Factory = ViewModelProvider.AndroidViewModelFactory.getInstance(application)
// 获取provider
val provider = ViewModelProvider(this, factory)
// 获取viewModel
val mViewModel=provider.get(UserViewModel::class.java)
// 观察viewModel的变化来更新UI
mViewModel.getUsers().observe(this, Observer {
Log.e(javaClass.simpleName,it.toString())
})
withExtendsLiveDataTest()
}
private fun withExtendsLiveDataTest() {
WifiLiveData.getInstance(this).observe(this, Observer {
Log.e("MainActivity", it.toString()) // 观察者收到数据更新的通知,打印 Wifi 信号强度
})
}
}
可以看到无论是使用MutableLiveData还是自己继承LiveData,最终都是要调用LiveData的observe方法。那么我们就从observe方法开始。
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
//必须在主线程观察
assertMainThread("observe");
//如果当前的activity或者fragment已经destroy了,那么就停止观察
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
//将observer和lifecycleOwner封装到一起
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
//判断observer是否有与之关联的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;
}
//这就跟之前的监听lifecycle一样了
owner.getLifecycle().addObserver(wrapper);
}
}
这里需要重点看一下这个wrapper,它是LiveData的内部类
class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
@NonNull
final LifecycleOwner mOwner;
LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
super(observer);
mOwner = owner;
}
@Override
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
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;
}
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
void dispatchingValue(@Nullable ObserverWrapper initiator) {
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
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;
}
可以看到这里有两层判断,如果ObserverWapper不为空则直接notify,如果为空的话就遍历map,notify每一个观察者,那么最终的通知方法即为considerNotify,在这里面最终调用 observer.mObserver.onChanged((T) mData); 这就是我们在activity或者fragment中得到的数据。上面的整个流程是从activity生命周期变化的过程来执行的顺序。当然之前举例的两种方式使用时,与ViewModel一起使用时用到了postValue,而wifi强度监听时则采用了setValue的方式来通知观察者。它们的实现如下
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
setValue必须在主线程调用,这里看到dispatchingValue中的ObserverWrapper为null,所以这里他就会去通知所有的观察者。而Post则是将子线程的数据推送到主线程
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
也就是说将这个Runnable发到主线程,post的具体实现为
@Override
public void postToMainThread(Runnable runnable) {
if (mMainHandler == null) {
synchronized (mLock) {
if (mMainHandler == null) {
mMainHandler = new Handler(Looper.getMainLooper());
}
}
}
//noinspection ConstantConditions
mMainHandler.post(runnable);
}
上面的postRunnable实现也很简单
private final Runnable mPostValueRunnable = new Runnable() {
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
//noinspection unchecked
setValue((T) newValue);
}
};
其实就是在主线程调用setValue方法