android – 如何在后台线程上执行LiveData转换?

前端之家收集整理的这篇文章主要介绍了android – 如何在后台线程上执行LiveData转换?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我需要将一个由LiveData对象返回的数据转换为后台线程上的另一种形式,以防止UI延迟.

在我的具体案例中,我有:@H_404_3@

> MyDBRow对象(由原始long和字符串组成的POJO);
> a Room DAO实例通过LiveData< List< MyDBRow>>发出这些实例;和
>一个UI期待更丰富的MyRichObject对象(PO​​JO与原语膨胀到例如date/time objects)@H_404_3@

所以我需要转换我的LiveData< List< MyDBRow>>到一个LiveData< List< MyRichObject>>,但不在UI线程上.@H_404_3@

Transformations.map(LiveData<X>,Function<X,Y>)方法执行此操作需要转换,但我不能使用它,因为它在主线程上执行转换:@H_404_3@

Applies the given function on the main thread to each value emitted by source LiveData and returns LiveData,which emits resulting values.@H_404_3@

The given function func will be executed on the main thread.@H_404_3@

什么是实现LiveData转换的简洁方法:@H_404_3@

>离主线程的某个地方,和
>仅在需要时(即仅在某些事物正在观察预期的转变时)?@H_404_3@

解决方法

>原始的“源” LiveData可以由新的 Observer实例监控.
>此Observer实例在发出源LiveData时,可以准备后台线程来执行所需的转换,然后通过新的“转换”LiveData发出它.
>转换后的LiveData可以在具有活动观察者时将上述观察者附加到源LiveData,并在没有活动观察者时将其分离,确保仅在必要时观察源LiveData.

该问题给出了一个示例源LiveData< List< MyDBRow>>并需要转换后的LiveData< List< MyRichObject>>.组合转换的LiveData和Observer看起来像这样:@H_404_3@

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);
            }
        });
    }
}

如果需要多个这样的转换,上面的逻辑可以像这样通用:@H_404_3@

abstract class TransformedLiveData<Source,Transformed>
        extends LiveData<Transformed>
{
    private Observer<Source> observer = new Observer<Source>() {
        @Override public void onChanged(@Nullable final Source source) {
            AsyncTask.execute(new Runnable() {
                @Override public void run() {
                    postValue(getTransformed(source));
                }
            });
        }
    };

    @Override protected void onActive()   { getSource().observeForever(observer); }
    @Override protected void onInactive() { getSource().removeObserver(observer); }

    protected abstract LiveData<Source> getSource();
    protected abstract Transformed getTransformed(Source source);
}

并且问题给出的示例的子类可能如下所示:@H_404_3@

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;
    }
}
原文链接:https://www.f2er.com/android/318237.html

猜你在找的Android相关文章