(四)Android Jetpack 组件之LiveData

本文深入解析LiveData的概念,探讨其在给定生命周期内的数据观察机制,以及如何与ViewModel结合使用,实现数据状态保存与恢复,避免内存泄漏,适用于Android开发场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、LiveData到底是个啥?

LiveData是可以在给定生命周期内观察到的数据持有者类。
它是一个类,这个类可以干嘛呢?
可以在给定的生命周期内观察数据变化。
给定的生命周期是什么意思?
指的是AppCompatActivity的onStart() 和 onResume()方法。
为什么要是AppCompatActivity 这个类而不是单纯的Activity类呢?
很简单当我们查看AppCompatActivity类的源码时发现它实现了LifecycleOwner 这个接口。
LifecycleOwner 这个接口有什么用?
为了实现数据变化的感知,需要实现观察者模式。

所以单靠区区一个类LiveData类还不能实现观察者模式,需要结合LifecycleOwner 接口实现类。为啥我们不需要直接去实现它,因为AppCompatActivity 的这个【ComponentActivity】父类已经实现了LifecycleOwner 这个接口,所以我们可以直接使用LiveData进行数据变更,就会有对应的生命周期响应。

接下来我们看看应该怎么样在实际案例中使用它。
使用之前我们需要在app的build.gradle文件中配置:

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

2、具体案例

布局activity_live_data.xml:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>

        <variable
            name="dataBean"
            type="com.hb.mvvm.livedata.DataBeanViewModel" />
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TextView
            android:id="@+id/tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@={dataBean.data}" />
    </LinearLayout>
</layout>

实体类DataBeanViewModel.class:

import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;

/**
 * Created by Administrator
 * on 2020/3/31
 */
public class DataBeanViewModel extends ViewModel {
    //<String> 可以换成对应的实体类型 eg:<User>
    MutableLiveData<String> dbLiveData = new MutableLiveData<>();

    //获取LiveData对象实例
    public MutableLiveData<String> getData() {
        return dbLiveData;
    }
}

类LiveDataActivity.class :


import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;

import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import androidx.lifecycle.ViewModelProvider;

import com.hb.mvvm.R;
import com.hb.mvvm.databinding.ActivityLiveDataBinding;

import org.w3c.dom.Text;

public class LiveDataActivity extends AppCompatActivity {
    ActivityLiveDataBinding liveDataBinding;
    final String TAG = LiveDataActivity.class.getSimpleName();
    DataBeanViewModel dbViewModel;

    @Override
        protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        liveDataBinding = DataBindingUtil.setContentView(this, R.layout.activity_live_data);

        //设置观察
        liveDataBinding.setLifecycleOwner(this);
        //创建DataBeanViewModel 的实例
        dbViewModel = new ViewModelProvider(this).get(DataBeanViewModel.class);
        //使用实例
        liveDataBinding.setDataBean(dbViewModel);

        liveDataBinding.tv.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                Log.i(TAG, "观察TextView数据变化: " + s);
            }
        });
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.i(TAG, "onStart()");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.i(TAG, "onResume()");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.i(TAG, "onPause()");
        //为了查看数据是否能够恢复,切换到后台的时候将数据置空
        liveDataBinding.tv.setText("");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.i(TAG, "onStop()");
        //停止的时候设置数据,看看在OnResume之后能否在显示出数据
        dbViewModel.getData().postValue("ViewModel配合LiveData使用");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i(TAG, "onDestroy()");
    }
}

输出:

onStart()
onResume()
onPause()
观察TextView数据变化: 
onStop()
onStart()
onResume()
观察TextView数据变化: ViewModel配合LiveData使用
onPause()
观察TextView数据变化: 
onStop()
onStart()
onResume()
观察TextView数据变化: ViewModel配合LiveData使用
onPause()
观察TextView数据变化: 
onStop()
onStart()
onResume()
观察TextView数据变化: ViewModel配合LiveData使用
onPause()
观察TextView数据变化: 
onStop()
onDestroy()
onStart()
onResume()
onPause()
观察TextView数据变化: 
onStop()
onDestroy()

输出中可以看到TextView数据恢复时都是在onResume()之后,但是onStart() 貌似没有体现出来。
当我们没调用onDestroy()方法时,每次切换显示界面都会恢复之前设置的数据,否则数据将会不在恢复。
这个过程保证了数据能完整的伴随生命周期的过程,相对而言数据恢复这块比之前的方式savedInstanceState更加方便。
同时通过查阅资料,当生命周期处于onDestory时,观察者会自动删除,防止内存溢出。

3、总结

LiveData 会自己管理自己的生命周期,防止内存溢出。
LiveData 能更好的帮助我们数据恢复,贯穿到整个Activity生命周期。
案例中发现当在onResume的时候看到才会恢复数据。而onStart()的时候没有做具体的实验,希望留给后面进行尝试。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值