项目中有用到生命周期感知型组件 MutableLiveData
,它是 LiveData
的子类,这里主要介绍 MutableLiveData
在项目中的简单使用。
注意:当 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 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 对象
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
对象。
MutableLiveData
对象(数据源)的值可以使用 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:
*
* liveData.postValue("a");
* liveData.setValue("b");
*
* The value "b" would be set at first and later the main thread would override it with
* the value "a".
*
* 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.
*
* 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 对象
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();
}
});
}
}
推荐同学们也阅读一下,加深理解。
技术永不眠,我们下期见!