更新时间:2023-02-09 18:57:48
LiveData
可以由新的 Observer
监视> 实例. LiveData
时,此 Observer
实例可以准备后台线程以执行所需的转换,然后通过新的已转换"的 LiveData
. LiveData
可以在活动的 Observer
时将上述 Observer
附加到源 LiveData
上,并在不需要时分离它们,以确保仅在必要时才观察源 LiveData
.LiveData
can be monitored by a new Observer
instance.Observer
instance, when source LiveData
is emitted, can prepare a background thread to perform the needed transformation and then emit it via a new, "transformed" LiveData
.LiveData
can attach the aforementioned Observer
to the source LiveData
when it has active Observer
s, and detach them when it doesn't, ensuring that the source LiveData
is only being observed when necessary.该问题给出了示例源 LiveData< List< MyDBRow>>
,并且需要转换后的 LiveData< List< MyRichObject>>
.组合后的转换后的 LiveData
和 Observer
可能看起来像这样:
The question gives an example source LiveData<List<MyDBRow>>
and needs a transformed LiveData<List<MyRichObject>>
. A combined transformed LiveData
and Observer
could look something like this:
class MyRichObjectLiveData
extends LiveData<List<MyRichObject>>
implements Observer<List<MyDBRow>>
{
@NonNull private LiveData<List<MyDBRow>> sourceLiveData;
MyRichObjectLiveData(@NonNull LiveData<List<MyDBRow>> sourceLiveData) {
this.sourceLiveData = sourceLiveData;
}
// only watch the source LiveData when something is observing this
// transformed LiveData
@Override protected void onActive() { sourceLiveData.observeForever(this); }
@Override protected void onInactive() { sourceLiveData.removeObserver(this); }
// receive source LiveData emission
@Override public void onChanged(@Nullable List<MyDBRow> dbRows) {
// set up a background thread to complete the transformation
AsyncTask.execute(new Runnable() {
@Override public void run() {
assert dbRows != null;
List<MyRichObject> myRichObjects = new LinkedList<>();
for (MyDBRow myDBRow : myDBRows) {
myRichObjects.add(MyRichObjectBuilder.from(myDBRow).build());
}
// use LiveData method postValue (rather than setValue) on
// background threads
postValue(myRichObjects);
}
});
}
}
如果需要多次这样的转换,可以使上述逻辑通用,如下所示:
If multiple such transformations are needed, the above logic could be made generic like this:
abstract class TransformedLiveData<Source, Transformed>
extends LiveData<Transformed>
implements Observer<Source>
{
@Override protected void onActive() { getSource().observeForever(this); }
@Override protected void onInactive() { getSource().removeObserver(this); }
@Override public void onChanged(@Nullable Source source) {
AsyncTask.execute(new Runnable() {
@Override public void run() {
postValue(getTransformed(source));
}
});
}
protected abstract LiveData<Source> getSource();
protected abstract Transformed getTransformed(Source source);
}
以及该问题给出的示例的子类可能看起来像这样:
and the subclass for the example given by the question could look something like this:
class MyRichObjectLiveData
extends TransformedLiveData<List<MyDBRow>, List<MyRichObject>>
{
@NonNull private LiveData<List<MyDBRow>> sourceLiveData;
MyRichObjectLiveData(@NonNull LiveData<List<MyDBRow>> sourceLiveData) {
this.sourceLiveData = sourceLiveData;
}
@Override protected LiveData<List<MyDBRow>> getSource() {
return sourceLiveData;
}
@Override protected List<MyRichObject> getTransformed(List<MyDBRow> myDBRows) {
List<MyRichObject> myRichObjects = new LinkedList<>();
for (MyDBRow myDBRow : myDBRows) {
myRichObjects.add(MyRichObjectBuilder.from(myDBRow).build());
}
return myRichObjects;
}
}