概述
背景
项目中有用到生命周期感知型组件 MutableLiveData
,它是 LiveData
的子类,这里主要介绍 MutableLiveData
在项目中的简单使用。
一些优点
- 不用担心发生内存泄漏
- 可以做到在组件处于激活状态的时候才会回调相应的方法,从而刷新相应的 UI
- 不需要手动取处理数据的储存和恢复。它已经帮我们封装好了
注意:当 Actiivty 不是处于激活状态的时候,如果你想 livedata setValue 之后立即回调 obsever 的
onChange 方法,而不是等到 Activity 处于激活状态的时候才回调 obsever 的 onChange 方法,你可以使用
observeForever 方法,但是你必须在 onDestroy 的时候 removeObserver
生命周期感知型组件的用例
生命周期感知型组件可使您在各种情况下更轻松地管理生命周期。下面列举几个例子:
- 在粗粒度和细粒度位置更新之间切换。使用生命周期感知型组件可在位置应用可见时启用细粒度位置更新,并在应用位于后台时切换到粗粒度更新。借助生命周期感知型组件
LiveData
,应用可以在用户使用位置发生变化时自动更新界面。 - 停止和开始视频缓冲。使用生命周期感知型组件可尽快开始视频缓冲,但会推迟播放,直到应用完全启动。此外,应用销毁后,您还可以使用生命周期感知型组件终止缓冲。
- 开始和停止网络连接。借助生命周期感知型组件,可在应用位于前台时启用网络数据的实时更新(流式传输),并在应用进入后台时自动暂停。
- 暂停和恢复动画可绘制资源。借助生命周期感知型组件,可在应用位于后台时暂停动画可绘制资源,并在应用位于前台后恢复可绘制资源。
添加依赖
现在 Lifecycle
稳定的版本是 2.2.0
,可以通过开发者库说明中查找,如下图示:
在app
模块下的build.gradle
文件中添加如下:
代码块为:
dependencies {
def lifecycle_version = "2.2.0"
implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version"
...
}
可以通过 androidx.lifecycle 2.2.0 来了解 2.2.0
版本的一些变化调整。
MutableLiveData
源码
如下:
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.lifecycle;
/**
* {@link LiveData} which publicly exposes {@link #setValue(T)} and {@link #postValue(T)} method.
*
* @param <T> The type of data hold by this instance
*/
@SuppressWarnings("WeakerAccess")
public class MutableLiveData<T> extends LiveData<T> {
/**
* 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);
}
}
可以看到 MutableLiveData
是 LiveData
的子类,并且 MutableLiveData
中的数据类型为 T
,很方便我们在 ViewModel
中实例化 MutableLiveData
,并在泛型中表明数据的类型即可(比如可以是一个实体类),所以这里使用 MutableLiveData
来作一个简单说明。
创建一个 ViewModel
的子类
package com.imxiaoqi.mutablelivedatademo.view_model;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
/**
* 创建 DataViewModel 继承 ViewModel
*/
public class DataViewModel extends ViewModel {
// 声明一个 MutableLiveData 类型的变量,数据类型为 String
private MutableLiveData<String> myStr = new MutableLiveData<>();
// 生成 get 和 set 方法
public MutableLiveData<String> getMyStr() {
return myStr;
}
public void setMyStr(MutableLiveData<String> myStr) {
this.myStr = myStr;
}
}
ViewModel
和 Activity
绑定
DataViewModel dataViewModel = null;
if (dataViewModel == null){
// 创建 DataViewModel 对象,让 DataViewModel 和 Activity 进行绑定
dataViewModel = new ViewModelProvider(this).get(DataViewModel.class);
}
获取被观察对象并添加到观察者列表中
// 获取被观察对象 - 这里为 MutableLiveData<String> 对象
mutableLiveData = dataViewModel.getMyStr();
// 将 mutableLiveData 添加到观察者列表中
mutableLiveData.observe(this, new Observer<String>() {
@Override
public void onChanged(String s) {
// 当被观察者对象 mutableLiveData 值发生改变时,会调用该方法,从而刷新相应 UI
Toast.makeText(MainActivity.this, "onChange = " + s, Toast.LENGTH_SHORT)
.show();
}
});
这里被观察这对象为 MutableLiveData<String>
对象。
改变 MutableLiveData<String>
对象(数据源)的值
可以使用 setValue()
或 postValue()
方法,这里使用 setValue()
,如下:
// 按钮单击事件
findViewById(R.id.btn_change).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// 改变被观察对象 - mutableLiveData 的值,使用 setValue方法改变数据源
mutableLiveData.setValue("改变,现在时间为:" +
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
.format(new Date(System.currentTimeMillis())));
}
});
两者区别:
setValue
方法必须在主线程调用postValue
方法将任务发送到主线程以设置给定的值
大家看方法对应源码说明可知,不细说了:
/**
* Posts a task to a main thread to set the given value. So if you have a following code
* executed in the main thread:
* <pre class="prettyprint">
* liveData.postValue("a");
* liveData.setValue("b");
* </pre>
* The value "b" would be set at first and later the main thread would override it with
* the value "a".
* <p>
* If you called this method multiple times before a main thread executed a posted task, only
* the last value would be dispatched.
*
* @param value The new value
*/
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
/**
* Sets the value. If there are active observers, the value will be dispatched to them.
* <p>
* This method must be called from the main thread. If you need set a value from a background
* thread, you can use {@link #postValue(Object)}
*
* @param value The new value
*/
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
完整代码
package com.imxiaoqi.mutablelivedatademo;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import com.imxiaoqi.mutablelivedatademo.view_model.DataViewModel;
import java.text.SimpleDateFormat;
import java.util.Date;
public class MainActivity extends AppCompatActivity {
DataViewModel dataViewModel = null;
MutableLiveData<String> mutableLiveData = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
observeData();
// 按钮单击事件
findViewById(R.id.btn_change).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// 改变被观察对象 - mutableLiveData 的值,使用 setValue方法改变数据源
mutableLiveData.setValue("改变,现在时间为:" +
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
.format(new Date(System.currentTimeMillis())));
}
});
}
/**
* 观察数据
*/
private void observeData() {
if (dataViewModel == null){
// 创建 DataViewModel 对象,让 DataViewModel 和 Activity 进行绑定
dataViewModel = new ViewModelProvider(this).get(DataViewModel.class);
}
// 获取被观察对象 - 这里为 MutableLiveData<String> 对象
mutableLiveData = dataViewModel.getMyStr();
// 将 mutableLiveData 添加到观察者列表中
mutableLiveData.observe(this, new Observer<String>() {
@Override
public void onChanged(String s) {
// 当被观察者对象 mutableLiveData 值发生改变时,会调用该方法,从而刷新相应 UI
Toast.makeText(MainActivity.this, "onChange = " + s, Toast.LENGTH_SHORT)
.show();
}
});
}
}
演示
参考
- Android开发 LiveData与MutableLiveData详解
- Android LiveData 使用详解
推荐同学们也阅读一下,加深理解。
技术永不眠,我们下期见!
最后
以上就是清爽曲奇为你收集整理的Android开发 MutableLiveData 简单使用说明背景一些优点生命周期感知型组件的用例添加依赖MutableLiveData 源码创建一个 ViewModel 的子类ViewModel 和 Activity 绑定获取被观察对象并添加到观察者列表中改变 MutableLiveData
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复