当前位置: 代码迷 >> 综合 >> Android开发 MutableLiveData 简单使用说明
  详细解决方案

Android开发 MutableLiveData 简单使用说明

热度:32   发布时间:2024-01-30 05:11:22.0

背景

项目中有用到生命周期感知型组件 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();}@Overridepublic void postValue(T value) {super.postValue(value);}@Overridepublic void setValue(T value) {super.setValue(value);}
}

可以看到 MutableLiveDataLiveData 的子类,并且 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 类型的变量,数据类型为 Stringprivate MutableLiveData<String> myStr = new MutableLiveData<>();// 生成 get 和 set 方法public MutableLiveData<String> getMyStr() {return myStr;}public void setMyStr(MutableLiveData<String> myStr) {this.myStr = myStr;}
}

ViewModelActivity 绑定

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>() {@Overridepublic void onChanged(String s) {// 当被观察者对象 mutableLiveData 值发生改变时,会调用该方法,从而刷新相应 UIToast.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() {@Overridepublic 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*/@MainThreadprotected 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;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);observeData();// 按钮单击事件findViewById(R.id.btn_change).setOnClickListener(new View.OnClickListener() {@Overridepublic 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>() {@Overridepublic void onChanged(String s) {// 当被观察者对象 mutableLiveData 值发生改变时,会调用该方法,从而刷新相应 UIToast.makeText(MainActivity.this, "onChange = " + s, Toast.LENGTH_SHORT).show();}});}
}

演示

在这里插入图片描述


参考

  • Android开发 LiveData与MutableLiveData详解
  • Android LiveData 使用详解

推荐同学们也阅读一下,加深理解。


技术永不眠,我们下期见!

  相关解决方案