使用领域和LiveData.转换LiveData< RealmResults< CustomModelObject>>到LiveData< List< CustomModelObject>>. [英] Using Realm and LiveData. Converting LiveData<RealmResults<CustomModelObject>> to LiveData<List<CustomModelObject>>

查看:71
本文介绍了使用领域和LiveData.转换LiveData< RealmResults< CustomModelObject>>到LiveData< List< CustomModelObject>>.的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将Realm与包括LiveData在内的Android体系结构组件一起使用.

I am trying out Realm along with Android architecture components including LiveData.

我一直在关注Google的《应用程序体系结构指南》:

I have been following Google's Guide to Application Architecture:

https://developer.android.com/topic/libraries/architecture/guide.html

...用领域代替Room.

...substituting Room with Realm.

我正在使用的所有工具都可以使用:

I have everything working using:

LiveData<RealmResults<CustomModelObject>>

从我的存储库层

一直到ViewModel到View.

from my repository layer right through ViewModel to View.

我认为只从存储库中返回更多泛型类型可能更好,所以LiveData<List<CustomModelObject>>而不是LiveData<RealmResults<CustomModelObject>>.

I am thinking it might be nicer to only have more generic types coming back from repository so LiveData<List<CustomModelObject>> rather than LiveData<RealmResults<CustomModelObject>>.

这是我遇到问题的代码段:

Here is a code snippet of where I have got stuck:

@NonNull
@Override
protected LiveData<List<CustomModelObject>> loadFromDb() {
    return Transformations.switchMap(customModelObjectsDao.getCustomModelObjects(),
        new Function<RealmResults<CustomModelObject>, LiveData<List<CustomModelObject>>>() {
        @Override
        public LiveData<List<CustomModelObject>> apply(RealmResults<CustomModelObject> data) {
            if (data == null) {
                return AbsentLiveData.create();
            } else {
                return customModelObjectsDao.getCustomModelObjects();
            }
        }
    });
}

customModelObjectsDao.getCustomModelObjects()当前返回LiveData<RealmResults<Inspiration>>.

我想将其转换为LiveData<List<Inspiration>>.

我尝试过各种Transformations.mapTransformations.switchMap等都没有成功,我想我已经盯着它太久了:)

I have tried various Transformations.map and Transformations.switchMap etc with no success and I think I have been staring at it too long now :)

我是在正确的道路上还是我错过了明显的东西?

Am I on the right path or am I missing something obvious?

非常感谢您的帮助.

谢谢, 保罗.

更新

DAO:

public RealmLiveData<CustomModelObject> getCustomModelObjects() {
    return asLiveData(realm.where(CustomModelObject.class).findAllAsync());
}

asLiveData Impl:

asLiveData Impl:

fun <T: RealmModel> RealmResults<T>.asLiveData() = RealmLiveData<T>(this)
fun Realm.CustomModelObjectsDao(): CustomModelObjectsDao = CustomModelObjectsDao(this)

更新2

public class RealmLiveData<T> extends LiveData<RealmResults<T>> {

private RealmResults<T> results;

private final RealmChangeListener<RealmResults<T>> listener = new RealmChangeListener<RealmResults<T>>() {
    @Override
    public void onChange(RealmResults<T> results) {
        setValue(results);
    }
};

public RealmLiveData(RealmResults<T> realmResults) {
    results = realmResults;
}

@Override
protected void onActive() {
    results.addChangeListener(listener);
}

@Override
protected void onInactive() {
    results.removeChangeListener(listener);
}
}

推荐答案

在您的情况下,用LiveData<List<T>>替换LiveData<RealmResults<T>就足以解决您的问题.

In your case, replacing LiveData<RealmResults<T> with LiveData<List<T>> would be enough to solve your problem.

但是,我建议尝试使用RealmLiveResults类/java/io/realm/examples/arch/livemodel/LiveRealmResults.java"rel =" noreferrer>官方示例:

However, I'd advise trying out the RealmLiveResults class that is available in the official example:

/**
 * This class represents a RealmResults wrapped inside a LiveData.
 *
 * Realm will always keep the RealmResults up-to-date whenever a change occurs on any thread,
 * and when that happens, the observer will be notified.
 *
 * The RealmResults will be observed until it is invalidated - meaning all local Realm instances on this thread are closed.
 *
 * @param <T> the type of the RealmModel
 */
public class LiveRealmResults<T extends RealmModel> extends LiveData<List<T>> {
    private final RealmResults<T> results;

    // The listener will notify the observers whenever a change occurs.
    // The results are modified in change. This could be expanded to also return the change set in a pair.
    private OrderedRealmCollectionChangeListener<RealmResults<T>> listener = new OrderedRealmCollectionChangeListener<RealmResults<T>>() {
        @Override
        public void onChange(@NonNull RealmResults<T> results, @Nullable OrderedCollectionChangeSet changeSet) {
            LiveRealmResults.this.setValue(results);
        }
    };

    @MainThread
    public LiveRealmResults(@NonNull RealmResults<T> results) {
        //noinspection ConstantConditions
        if (results == null) {
            throw new IllegalArgumentException("Results cannot be null!");
        }
        if (!results.isValid()) {
            throw new IllegalArgumentException("The provided RealmResults is no longer valid, the Realm instance it belongs to is closed. It can no longer be observed for changes.");
        }
        this.results = results;
        if (results.isLoaded()) {
            // we should not notify observers when results aren't ready yet (async query).
            // however, synchronous query should be set explicitly.
            setValue(results);
        }
    }

    // We should start observing and stop observing, depending on whether we have observers.

    /**
     * Starts observing the RealmResults, if it is still valid.
     */
    @Override
    protected void onActive() {
        super.onActive();
        if (results.isValid()) { // invalidated results can no longer be observed.
            results.addChangeListener(listener);
        }
    }

    /**
     * Stops observing the RealmResults.
     */
    @Override
    protected void onInactive() {
        super.onInactive();
        if (results.isValid()) {
            results.removeChangeListener(listener);
        }
    }
}

这样,您的dao可以公开LiveData<List<T>>,而您的Transformations.map()应该可以工作.

This way your dao can expose LiveData<List<T>>, and your Transformations.map() should work.

这篇关于使用领域和LiveData.转换LiveData&lt; RealmResults&lt; CustomModelObject&gt;&gt;到LiveData&lt; List&lt; CustomModelObject&gt;&gt;.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆