Android Jetpack—LiveData和数据倒灌

1.LiveData

LiveData是Jetpack包提供的一种可观察的数据存储器类,它可以通过添加观察者被其他组件观察其变更。不同于普通的观察者,LiveData最重要的特征是它具有生命周期感知能力,它遵循其他应用组件(如Activity、Fragment或Service)的生命周期。这种感知能力可确保LiveData仅更新处于活跃生命周期状态的应用组件观察者。如在Activity中如果数据更新了但Activity已经处于destroy状态,则LiveData就不会通知Activity(observer)了。

回想一下,在项目中是不是经常会碰到这样的问题:当网络请求结果回来的时候,经常需要判断Activity或者Fragment是否已经Destroy, 如果不是destroy才更新UI。而如果使用Livedata的话,因为它是在Activity处于onStart或者onResume的状态时,它才会进行相应的回调,因而可以很好得处理这个问题,不必写一大堆的 activity.isDestroyed()。

注意:当Activity不是处于激活状态的时候,如果想Livedata调用setValue之后立即回调obsever的onChange方法,而不是等到Activity处于激活状态的时候才回调obsever的onChange方法,可以使用observeForever方法,但是必须在onDestroy的时候调用removeObserver()方法来停止对LiveData的观察,否则LiveData会一直处于激活状态,Activity就永远不会被系统自动回收,会造成内存泄露。

LiveData有两个子类:MutableLiveData和MediatorLiveData。MutableLiveData针对单个需要观察的数据进行了封装,而MediatorLiveData则可以观察其它的LiveData。开发过程中通常使用LiveData的子类,而不是去继承LiveData。

LiveData通常会配合ViewModel一起使用,ViewModel负责触发数据的更新,更新会通知到LiveData,然后LiveData再通知活跃状态的观察者。当然,LiveData也可以单独使用,分为三步:

①创建对应数据类型的LiveData

②添加观察者与Lifecycle建立联系

③发送对应的数据进行更新

比如MutableLiveData的使用方法:

private void liveDataTest(){

    MutableLiveData<String> mutableLiveData = new MutableLiveData<>();

    mutableLiveData.observe(this, new Observer<String>() {

        @Override

        public void onChanged(String value) {

           //如果数据有变化的话,这里会接收到通知,可以在这里可以做一些反应,比如更新界面

        }

     });

    mutableLiveData.setValue("我的值变化了");

}

 

2.LiveData使用

①引入依赖

implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'

②布局文件

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout >

    <TextView

        android:id="@+id/tv_text"

        android:layout_width="match_parent"

        android:layout_height="50dp"/>

    <LinearLayout

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:orientation="horizontal">

        <ImageButton

            android:id="@+id/img_button_add"

            android:layout_width="70dp"

            android:layout_height="70dp"/>

        <ImageButton

           android:id="@+id/img_button_subtract"

            android:layout_width="70dp"

            android:layout_height="70dp"   />

    </LinearLayout>

</LinearLayout>

③创建ViewModelWithLiveData类继承于ViewModel,在这个类里面声明LiveData变量

public class ViewModelWithLiveData extends ViewModel {

    private MutableLiveData<Integer> LikedNumber;  

    public MutableLiveData<Integer> getLikedNumber() {

        if (LikedNumber == null) {

            //LikedNumber是对象类型,不是基本数据类型,所以要保证变量不是空的

            LikedNumber = new MutableLiveData<>();       

            LikedNumber.setValue(0);  //初始化为0

        }

        return LikedNumber;

    }

    public void addLikedNumber(int n) {

        LikedNumber.setValue( LikedNumber.getValue() + n);

    }

}

④给viewModelWithLiveData里面的LiveData变量添加一个观察,点击按钮实现+1、-1操作

public class LiveDataTestActivity extends AppCompatActivity {

    private ViewModelWithLiveData viewModelWithLiveData;

    private TextView tv_text;

    private ImageButton button_add;

    private ImageButton button_subtract;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView( R.layout.activity_live);

        viewModelWithLiveData = new ViewModelProvider(this).get(ViewModelWithLiveData.class);

        //给viewModelWithLiveData里面的LiveData变量添加一个观察,如果它发生变化则会回调下面的onChange函数。observe()的第一个参数要求是具有LifeCycle管理功能的一些对象,比如Activity

        viewModelWithLiveData.getLikedNumb er().observe(this, new Observer<Integer>() {

          @Override

          public void onChanged(Integer integer) { //当LiveData数据发生改变时回调这个函数

              tv_text.setText( String.valueOf(integer));

            }

        });

        button_add.setOnClickListener(new View.OnClickListener() {

            @Override

            public void onClick(View view) {

                viewModelWithLiveData.addLikedN umber(1);

            }

        });

        button_subtract.setOnClickListener( new View.OnClickListener() {

            @Override

            public void onClick(View view) {

                viewModelWithLiveData.addLikedN umber(-1);

            }

        });

    }

}

ac6e22946cbb422a94eec0ed51489137.gif

由于ViewModel的存在,当旋转屏幕、切换系统语言等配置时,数据不会丢失。

 

LiveData的好处:

①监听与其绑定的界面的生命周期。因此,使用LiveData就不需要手动管理它的生命周期了。

②组件能及时响应LiveData的数据变化,组件总能拿到LiveData的最新数据。当然被绑定的组件响应LiveData是有一定的前提的,那就是LiveData数据发生变化,且组件处于活跃状态。也就是说,LiveData数据即使发生了变化,也不一定会响应onChanged函数,因为它必须要求LiveData数据所在的界面处于活跃状态,才会响应onChanged函数。

③生命周期自动解绑,它能够在组件销毁的时候自动解绑,大大降低了产生内存泄露的概率。

注:LiveData确实能解决内存泄漏问题,但是如果使用不当,还是会出现内存泄漏的。例如,有一个Activity,Activity包含了一个Fragment,Fragment中有一个LiveData,因此Fragment引用了LiveData。然后LiveData通过observe方法把Activity当作owner进行了绑定,那么这时候,LiveData的生命周期将和Activity一样。如果这时Fragment被销毁了,那LiveData将不会被销毁,因为它被Activity引用着。LiveData本该回收却无法被回收,那么LiveData就发生内存泄漏了。

 

3.LiveData源码

①observe方法

LiveData使用observe()方法监听与其绑定的界面的生命周期。

LiveData.java:

@MainThread

public void observe(LifecycleOwner owner, Observer<? super T> observer) {

    assertMainThread("observe"); //只能在主线程调用这个方法

    if (owner.getLifecycle().getCurrentState() == DESTROYED) {

        return; //如果owner的生命周期已经是DESTROYED状态,则不再往下执行

    }

    //将外部传进的observer对象封装成一个LifecycleBoundObserver对象

    LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);

    //将observer和wrapper分别作为key和value存放到map中

    ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);

    if (existing != n

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值