这是我参与更文挑战的第20天,活动详情查看: 更文挑战
LiveData 概述
简介
LiveData
是一个可观察的数据持有者类,与常规observable
不同,LiveData
是生命周期感知的,这意味着它尊重其他应用程序组件的生命周期,例如Activity
,Fragment
或Service
。此感知确保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,暴露了setValue
、postValue
方法。
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)
来更新它。