Thracian..
8
首先,map()和switchMap()方法都在主线程上调用。它们与用于快速或慢速任务无关。但是,如果您在这些方法(而不是工作线程)中执行复杂的计算或耗时任务,例如解析或转换较长和/或复杂的json响应,则可能会导致UI滞后,因为它们是在UI线程上执行的。
地图()
map()方法的代码是
@MainThread
public static LiveData map(@NonNull LiveData source,
@NonNull final Function func) {
final MediatorLiveData result = new MediatorLiveData<>();
result.addSource(source, new Observer() {
@Override
public void onChanged(@Nullable X x) {
result.setValue(func.apply(x));
}
});
return result;
}
它的作用是,它使用源LiveData,我是输入类型,并在LiveData上调用setValue(O),其中O是输出类型。
为了清楚起见,让我举一个例子。您希望在用户更改时将用户名和姓氏写入textView。
/**
* Changes on this user LiveData triggers function that sets mUserNameLiveData String value
*/
private MutableLiveData mUserLiveData = new MutableLiveData<>();
/**
* This LiveData contains the data(String for this example) to be observed.
*/
public final LiveData mUserNameLiveData;
现在让我们在mUserLiveData更改时触发mUserNameLiveData的String的更改。
/*
* map() method emits a value in type of destination data(String in this example) when the source LiveData is changed. In this example
* when a new User value is set to LiveData it trigger this function that returns a String type
*
* Input, Output
* new Function
*
* public String apply(User input) { return output;}
*/
// Result Source Input, Output
mUserNameLiveData = Transformations.map(mUserLiveData, new Function() {
@Override
public String apply(User input) {
// Output
return input.getFirstName() + ", " + input.getLastName();
}
});
让我们做同样的事情 MediatorLiveData
/**
* MediatorLiveData is what {@link Transformations#map(LiveData, Function)} does behind the scenes
*/
public MediatorLiveData mediatorLiveData = new MediatorLiveData<>();
/*
* map() function is actually does this
*/
mediatorLiveData.addSource(mUserLiveData, new Observer() {
@Override
public void onChanged(@Nullable User user) {
mediatorLiveData.setValue(user.getFirstName() + ", " + user.getLastName());
}
});
而且,如果您在Activity或Fragment上观察MediatorLiveData,则得到的结果与观察到的结果相同 LiveData mUserNameLiveData
userViewModel.mediatorLiveData.observe(this, new Observer() {
@Override
public void onChanged(@Nullable String s) {
TextView textView = findViewById(R.id.textView2);
textView.setText("User: " + s);
Toast.makeText(MainActivity.this, "User: " + s, Toast.LENGTH_SHORT).show();
}
});
switchMap()
每当SourceLiveData更改时,switchMap()都会返回相同的MediatorLiveData而不是新的 LiveData。
它的源代码是
@MainThread
public static LiveData switchMap(@NonNull LiveData trigger,
@NonNull final Function> func) {
final MediatorLiveData result = new MediatorLiveData<>();
result.addSource(trigger, new Observer() {
LiveData mSource;
@Override
public void onChanged(@Nullable X x) {
LiveData newLiveData = func.apply(x);
if (mSource == newLiveData) {
return;
}
if (mSource != null) {
result.removeSource(mSource);
}
mSource = newLiveData;
if (mSource != null) {
result.addSource(mSource, new Observer() {
@Override
public void onChanged(@Nullable Y y) {
result.setValue(y);
}
});
}
}
});
return result;
}
基本上,它会创建一个最终的MediatorLiveData并将其设置为Result,例如map dos(),但这一次函数返回LiveData
public static LiveData map(@NonNull LiveData source,
@NonNull final Function func) {
final MediatorLiveData result = new MediatorLiveData<>();
result.addSource(source, new Observer() {
@Override
public void onChanged(@Nullable X x) {
result.setValue(func.apply(x));
}
});
return result;
}
@MainThread
public static LiveData switchMap(@NonNull LiveData trigger,
@NonNull final Function**> func) {
final MediatorLiveData result = new MediatorLiveData<>();
result.addSource(trigger, new Observer() {
LiveData mSource;
@Override
public void onChanged(@Nullable X x) {
LiveData newLiveData = func.apply(x);
if (mSource == newLiveData) {
return;
}
if (mSource != null) {
result.removeSource(mSource);
}
mSource = newLiveData;
if (mSource != null) {
result.addSource(mSource, new Observer() {
@Override
public void onChanged(@Nullable Y y) {
result.setValue(y);
}
});
}
}
});
return result;
}
因此,map()需要LiveData把它转换成一个String,如果User对象更改为实例名称领域的变化。
switchMap()接受一个String并开始LiveData使用它。使用字符串从Web或db查询用户,并得到LiveData一个结果。