Android Jetpack 之 LiveData – 1

这是我参与更文挑战的第20天,活动详情查看: 更文挑战

LiveData 概述

简介

LiveData是一个可观察的数据持有者类,与常规observable不同,LiveData是生命周期感知的,这意味着它尊重其他应用程序组件的生命周期,例如ActivityFragmentService。此感知确保LiveData仅更新处于活动生命周期状态的应用程序组件观察者。

注意:欲将 LiveData 组件导入您的 Android 项目,请参阅向您的项目中添加 Android 架构组件

实例

基本使用

class LiveDataDemoActivity : AppCompatActivity() {

    private lateinit var livedata: MutableLiveData<String>

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_liva_data_demo)
        val observerForever = Observer<String> { println("LiveData observeForever changed : $it") }
        val observer = Observer<String> { println("LiveData observe changed : $it") }
        livedata = MutableLiveData()
        livedata.observeForever(observerForever)
        livedata.observe(this, observer)
    }

    override fun onResume() {
        super.onResume()
        livedata.value = "onResume"
    }

    override fun onPause() {
        super.onPause()
        livedata.value = "onPause"
    }

    override fun onStop() {
        super.onStop()
        livedata.value = "onStop"
    }

    override fun onDestroy() {
        super.onDestroy()
        livedata.value = "onDestroy"
    }
}

复制代码

打开这个Activity时日志如下

com.lingdage.androiddemo I/System.out: LiveData observeForever changed : onResume
com.lingdage.androiddemo I/System.out: LiveData observe changed : onResume

按home键之后

com.lingdage.androiddemo I/System.out: LiveData observeForever changed : onPause
com.lingdage.androiddemo I/System.out: LiveData observe changed : onPause
com.lingdage.androiddemo I/System.out: LiveData observeForever changed : onStop

重新打开应用

com.lingdage.androiddemo I/System.out: LiveData observe changed : onStop
com.lingdage.androiddemo I/System.out: LiveData observeForever changed : onResume
com.lingdage.androiddemo I/System.out: LiveData observe changed : onResume

按返回键

com.lingdage.androiddemo I/System.out: LiveData observeForever changed : onPause
com.lingdage.androiddemo I/System.out: LiveData observe changed : onPause
com.lingdage.androiddemo I/System.out: LiveData observeForever changed : onStop
com.lingdage.androiddemo I/System.out: LiveData observeForever changed : onDestroy

**注意:若使用了observeForever**会监听了所有生命周期方法,所以你会看到onDestroy()等生命周期函数的打印。

LiveData 是一个抽象类,我们不能直接使用。幸运的是,Google 提供了一些其简单实现,让我们来使用。

这里使用了MutableLiveData类来保存数据,它继承了LiveData,暴露了setValuepostValue方法。

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

创建 LiveData 对象

官方建议我们LiveData通常和Jetpack架构下的另一个组件ViewModel配合使用,ViewModel是一个负责为Activity或者Fragment准备和管理数据的类,同时处理和应用剩余部分的通信,注意ViewModel仅仅负责管理UI上的数据,其他都无权干涉,它和组件生命周期绑定,只有Activity结束了,它才会被销毁。

public class NameViewModel extends ViewModel {

    // 创建一个存储 String 的 LiveData 对象
    private MutableLiveData<String> mCurrentName;

    public MutableLiveData<String> getCurrentName() {
        if (mCurrentName == null) {
            mCurrentName = new MutableLiveData<String>();
        }
        return mCurrentName;
    }

// ViewModel 的其余部分……
}
复制代码

在初始状态,LiveData 对象中的数据是没有被赋值的。

注意:请务必将更新 UI 的 LiveData 对象存储在 ViewModel 对象中,而不是 activity 或 fragment。原因如下:

  • 避免过于臃肿的 activity 和 fragment。现在这些 UI 控制器负责展示数据,而非存储数据的状态。
  • LiveData 实例从特定的 activity 或 fragment 中解耦出来,并允许 LiveData 存活过配置变更。

观测 LiveData 对象

在大多数情况下,您应当在某个应用组件的 onCreate()方法中开始对 LiveData 对象的观测,原因如下:

  • onCreate是activity创建时的第一个回调,onResume和onStart在activity生命周期内会回调多次,造成调用监听多次形成冗余。
  • 确保activity和fragment在变成活跃状态进入started时可以尽快获得数据更新,所以要尽早开始监听。

一般而言,LiveData 只在数据变化的情况下才会将更新通知给活动状态的观测者。然而这有一个例外:观测者在从非活动状态进入活动状态的时候,也能收到更新。更进一步讲,如果观测者又一次从非活动状态进入活动状态,那么只有当数据在这期间又发生了变化,观测者才会收到更新。

如下的示例代码展示了如何开始观测一个 LiveData 对象:

public class NameActivity extends AppCompatActivity {

    private NameViewModel mModel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 其他设置 activity 的代码……
        // 获取 ViewModel
        mModel = ViewModelProviders.of(this).get(NameViewModel.class);

        // 创建用于更新 UI 的观测者
        final Observer<String> nameObserver = new Observer<String>() {
            @Override
            public void onChanged(@Nullable final String newName) {
                mNameTextView.setText(newName);
            }
        };

        // 将这个 activity 作为 LifecycleOwner 参数,和观测者一并传入,开始观测该 LiveData
        mModel.getCurrentName().observe(this, nameObserver);
    }
}
复制代码

在 [observe()](developer.android.google.cn/reference/a…,
android.arch.lifecycle.Observer)) 被传入 nameObserver 参数并调用后,onChanged() 立即被触发,用于提供 mCurrentName 所存储的数据的最新的值。如果 LiveData 对象还没有为 mCurrentName 设置一个值,那么 onChanged() 就不会被调用。

更新 LiveData 对象

LiveData更改数据的方法不是public类型的,只在内部自己调用,所有这里才会使用MutableLiveData,他暴露了修改数据的公共方法。

当您已经设置好观测者的关系后,就可以更新 LiveData 对象中的数据了。如下面的例所示,用户点击按钮时所有观测者都被通知:

mButton.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        String anotherName = "Naco Siren";
        mModel.getCurrentName().setValue(anotherName);
    }
});
复制代码

在该例中调用 setValue(T) 会导致观测者使用新的值 Naco Siren 去调用其 onChanged 方法。该例展示的是用户点击按钮的情况,但还有更多使用 setValue()postValue() 的情形,比如对网络请求或者数据库完成加载做出反应:无论是哪种情况,setValue()postValue() 的调用都会通知观测者去更新 UI。

注意:在主线程中,您必须调用 setValue(T) 来更新 LiveData 对象。如果代码是在工作线程中执行的,那么您可以使用 postValue(T) 来更新它。

参考

官方文档:LiveData 概览

Jetpack源码解析—LiveData的使用及工作原理

Android livedata 源码解剖

Android源码解析-LiveData

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享