Android--Jetpack--LiveData

穷则独善其身,达则兼善天下

一,定义

LiveData 组件是 Jetpack 新推出的基于观察者的消息订阅/分发组件,具有宿主(Activity/Fragment)生命周期感知能力。这种感知能力可确保 LiveData 仅分发消息给与活跃状态的观察者,即只有处于活跃状态的观察者才能收到消息。

LiveData 的消息分发机制,是以往 Handler,EventBus,RxjavaBus 无法比拟的,它们不会顾及当前页面是否可见,一股脑的有消息就转发。导致即便应用在后台,页面不可见,还在做一些无用的绘制,计算(微信的消息列表是在可见状态下才会更新列表最新信息的)将有限的资源让给可见的页面使用。

基于生命周期,其实就是在当前宿主 LifecycleOnwer 注册一个 Observer,那么宿主每次生命周期的变化,都会回调给观察者的 onStateChange() 方法,即便是刚刚注册的观察者宿主也会回调 onStateChange() 方法,会有一个状态同步的过程,LiveData 也是利用这个能力,巧妙实现了当宿主销毁的时候,自动移除注册进来的 Observer,从而避免了手动移除的麻烦。更不会造成内存泄漏,这个也是它的核心思想。

二,特点

使用 LiveData 具有以下几点优势:

1,确保界面符合数据状态:LiveData 遵循观察者模式。当底层数据发生变化时,LiveData 会通知 Observer 对象。

2,不会发生内存泄漏:观察者会绑定到 Lifecycle 对象,并在其关联的生命周期遭到销毁后进行自我清理。

3,不会因 Activity 停止而导致崩溃:如果观察者的生命周期处于非活跃状态(如返回堆栈中的 Activity),它便不会接收任何 LiveData 事件。

4,不再需要手动处理生命周期:界面组件只是观察相关数据,不会停止或恢复观察。LiveData 将自动管理所有这些操作,因为它在观察时可以感知相关的生命周期状态变化。

5,数据始终保持最新状态:如果生命周期变为非活跃状态,它会在再次变为活跃状态时接收最新的数据。

6,适当的配置更改:如果由于配置更改(如设备旋转)而重新创建了 Activity 或 Fragment,它会立即接收最新的可用数据。

7,共享资源:您可以使用单例模式扩展 LiveData 对象以封装系统服务,以便在应用中共享它们。LiveData 对象连接到系统服务一次,然后需要相应资源的任何观察者只需观察 LiveData 对象。

LiveData不足之处:

 粘性事件不支持取消(后面注册的观察者也能接收数据,无法反注册,但有办法解决)。

三,核心方法

方法名 作用
observe(LifecycleOwner owner, Observer observer) 注册和宿主生命周期关联的观察者, owner当前生命周期的宿主,当宿主销毁了observer能自动解除注册
observeForever(Observer observer) 注册观察者,不会反注册,需自行维护,没有owner无法管理宿主生命周期
setValue(T value) 发送数据,没有活跃的观察者时不分发,只能在主线程
postValue(T value) setValue一样,但是不受线程限制,内部也是通过handelr.post到主线程,最后还是通过setValue来分发的
onActive() 当且仅当有一个活跃的观察者时会触发
onInactive() 不存在活跃的观察者时会触发

四,基本使用

1,在app的build.gradle中添加:

implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.5.1"
implementation "androidx.lifecycle:lifecycle-common:2.5.1"

 2,自定义ViewModel:

public class MyViewModel extends ViewModel {

    private MutableLiveData count;

    public MutableLiveData getCount(){
        if(count ==null){
            count =new MutableLiveData<>();
        }
        return count;
    }
}

3,在宿主 LifecycleOnwer中创建观察者Observer:

Observer observer =new Observer() {
    @Override
    public void onChanged(String o) {
        System.out.println("yz---"+o);
        txt.setText(o);
    }
};

4,在宿主 LifecycleOnwer中获取自定义的viewmodel:

//获取viewmodule
model =new ViewModelProvider(this).get(MyViewModel.class);

5,在宿主 LifecycleOnwer中注册和宿主生命周期关联的观察者:

model.getCount().observe(this,observer);

6,在需要修改数据的地方修改数据,发送数据:

void startTimer() {
    final int[] i = {0};
   new Timer().schedule(new TimerTask() {
       @Override
       public void run() {
           model.getCount().postValue("yuanzhen"+ i[0]);
           i[0]++;
       }
}, 1000, 1000);
}

这里模拟每隔1s修改一次数据

3,4,5,6完整代码如下:

public class SecondActivity extends AppCompatActivity {

    private MyViewModel model;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        TextView txt = findViewById(R.id.txt);

        Observer observer =new Observer() {
            @Override
            public void onChanged(String o) {
                System.out.println("yz---"+o);
                txt.setText(o);
            }
        };

        //获取viewmodule
        model =new ViewModelProvider(this).get(MyViewModel.class);
        model.getCount().observe(this,observer);
        startTimer();

    }

    void startTimer() {
        final int[] i = {0};
       new Timer().schedule(new TimerTask() {
           @Override
           public void run() {
               model.getCount().postValue("yuanzhen"+ i[0]);
               i[0]++;
           }
    }, 1000, 1000);
    }
}

最终输出如下:

Android--Jetpack--LiveData_第1张图片

五,升级用法 

1,定义一个LiveDataBus 用来管理MutableLiveData:

public class LiveDataBus {

    private Map> bus;

    private LiveDataBus(){
        bus =new HashMap<>();
    }

    public static LiveDataBus getInstance(){
        return SingletonHolder.liveDataBus;
    }

    private static class SingletonHolder{
        private static final LiveDataBus liveDataBus =new LiveDataBus();
    }

    public  synchronized   MutableLiveData getLiveData(String key,Class type){
        if(!bus.containsKey(key)){
            bus.put(key,new MutableLiveData<>());
        }
        return (MutableLiveData) bus.get(key);
    }
}

2,发送数据:

void startTimer() {
    final int[] i = {0};
   new Timer().schedule(new TimerTask() {
       @Override
       public void run() {
           LiveDataBus.getInstance().getLiveData("yuanzhen",String.class).postValue("yuanzhen"+i[0]);
           i[0]++;
       }
}, 1000, 1000);
}

3,注册观察者接收数据:

LiveDataBus.getInstance().getLiveData("yuanzhen",String.class).observe(this, new Observer() {
    @Override
    public void onChanged(String s) {
        System.out.println("yz---"+s);
        txt.setText(s);
    }
});

六,基本原理解析

首先说一下我们为什么要用MutableLiveData呢,来看看LiveData的源码:

public abstract class LiveData {

    。。。。

    protected void postValue(T value) {
        boolean postTask;
        synchronized (mDataLock) {
        postTask = mPendingData == NOT_SET;
        mPendingData = value;
        }
        if (!postTask) {
            return;
        }
        ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
    }

    @MainThread
    protected void setValue(T value) {
        assertMainThread("setValue");
        mVersion++;
        mData = value;
        dispatchingValue(null);
    }
}

setValue 和postValue 都是protected方法,外面拿不到

同时,这里的setValue使用了注解@MainThread 说明只能在主线程发送数据

再来看看MutableLiveData的源码:

public class MutableLiveData extends LiveData {

    /**
     * Creates a MutableLiveData initialized with the given {@code value}.
     *
     * @param value initial value
     */
    public MutableLiveData(T value) {
        super(value);
    }

    /**
     * Creates a MutableLiveData with no value assigned to it.
     */
    public MutableLiveData() {
        super();
    }

    @Override
    public void postValue(T value) {
        super.postValue(value);
    }

    @Override
    public void setValue(T value) {
        super.setValue(value);
    }
}

这是它的全部代码,只是把postValue和setValue这两个方法公开了。其余的都是继承LiveData。

这就是我们为什么使用MutableLiveData的原因。

剩下的源码明晚分析,今晚熬不住了

你可能感兴趣的:(android-jetpack,android)