1.为什么要用LiveData
首先LiveData是Google原生API不需要额外依赖第三方库,易于版本维护;其次相较于其他通讯方式,LiveData可以感知窗体生命周期,可以随生命周期销毁而销毁,更易于操作。
2.如何使用LiveData
首先创建LiveData对象(PS:这里不要直接撞见LiveData的对象而是创建其子类MutableLiveData)。
MutableLiveData<String> liveData = new MutableLiveData<>();//规范泛型为String
然后设置数据
liveData.postValue("11111");
在MutableLiveData中有两个方法设置数据:postValue和setValue。其中postValue可以在任意线程中使用,而setValue只能在主线程中使用。而我们之所以使用MutableLiveData就是为了得到postValue这个方法。
最后这是观察者进行监听
liveData.observe(MainActivity.this, new Observer<String>() {@Overridepublic void onChanged(String s) {Log.e("chy",s);}});
这样就可以在observer中监听liveData数据的变化了,当我们执行postValue是onChanged方法会进行回调。但是在使用时我们会发现一个问题----->LiveData的具有不可控的粘性事件,但是我们在查看LiveData的源码是发现我们是可以在LiveData的considerNotify方法中进行拦截。
实际操作代码如下:
public class BusMutableLiveData<T> extends MutableLiveData<T> {//false; 需要粘性事件 true 不需要粘性事件private boolean isViscosity = false;public void observe(@NonNull LifecycleOwner owner, boolean isViscosity, @NonNull Observer<T> observer) {this.isViscosity = isViscosity;observe(owner, observer);}@Overridepublic void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {super.observe(owner, observer);try {if(isViscosity){//通过反射 获取到mVersion 获取到mLastVersion 将mVersion 的值给mLastVersionhook(observer);}} catch (Exception e) {e.printStackTrace();}}/*** hook技术的实现方法 拦截onChange方法的执行* @param observer*/private void hook(Observer<? super T> observer) throws Exception {//获取到LiveData的类对象Class<LiveData> liveDataClass = LiveData.class;//根据类对象获取到mVersion的反射对象Field mVersionField = liveDataClass.getDeclaredField("mVersion");//打开权限mVersionField.setAccessible(true);//获取到mObservers的反射对象Field mObserversField = liveDataClass.getDeclaredField("mObservers");//打开权限mObserversField.setAccessible(true);//从当前的LiveData对象中获取mObservers这个成员变量在当前对象中的值Object mObservers = mObserversField.get(this);//获取到mObservers这个map的get方法Method get = mObservers.getClass().getDeclaredMethod("get", Object.class);//打开权限get.setAccessible(true);// 执行get方法Object invokeEntry = get.invoke(mObservers, observer);//定义一个空对象 LifecycleBoundObserverObject observerWrapper = null;if(invokeEntry !=null && invokeEntry instanceof Map.Entry){observerWrapper = ((Map.Entry)invokeEntry).getValue();}if(observerWrapper == null){throw new NullPointerException("ObserverWrapper不能为空");}//得到observerWrapper的类对象Class<?> aClass = observerWrapper.getClass().getSuperclass();//获取mLastVersion的发射对象Field mLastVersionField = aClass.getDeclaredField("mLastVersion");//打开权限mLastVersionField.setAccessible(true);//获取到mVersion的值Object o = mVersionField.get(this);//把它的值赋值给mLastVersionmLastVersionField.set(observerWrapper,o);}}
这样我们就可以使用我们自定义的LiveData来控制是否添加粘性事件了O(∩_∩)O~