gpt4 book ai didi

android - 处理多线程和 Realm 的正确方法是什么?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:21:31 28 4
gpt4 key购买 nike

在我的 Android 应用程序中,我有一个数据访问层,其中每个数据存储类都有以下属性

Realm realm = Realm.getDefaultInstance();

我的问题是当我尝试从不同的线程调用任何数据存储方法时。然后我得到

Realm objects can only be accessed on the thread they were created.

我读到我应该在新线程上创建一个新的 Realm 实例。问题是数据访问层没有线程感知,它不知道它是从 main 调用还是分离调用,在我看来它会闻到添加逻辑来检查这一点的味道。

我正在检查这里的不同问题和 github 上填写的问题,但我不清楚处理这种情况的官方方法是什么。我不认为我正在处理一个奇怪的场景......

编辑

我的架构是包含 Presenter 的 Fragment,而 Presenter 又包含 DataStore。

我检测到一个运行时间很长的进程,所以我将它移到演示者上这样一个单独的线程

Thread thread = new Thread(new Runnable() {
@Override
public void run() {
// Events is a collection of DTOs, they are not Realm objects (converted from Realm object to DTO inside dataStore)
events = dataStore.getEvents(filterTerm);

view.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
if (events.size() > 0) {
view.showEvents(events);
}
}
});
}
});

thread.start();

编辑

添加连续执行的 3 个查询。它们是从 3 种不同的方法调用的

查询 1

final RealmResults<Event> results = query.findAllAsync();
results.addChangeListener(new RealmChangeListener() {
@Override
public void onChange() {
....
}
});

查询 2

final RealmResults<T> result = realm.where(type).findAllAsync();
result.addChangeListener(new RealmChangeListener() {
@Override
public void onChange() {
...
}
});

查询 3

final RealmResults<PresentationSpeaker> results = query.findAllAsync();
results.addChangeListener(new RealmChangeListener() {
@Override
public void onChange() {
...
}
});

最佳答案

通常习惯让您的 DataStore 是异步的,以避免您现在遇到的问题:操作花费很长时间,您必须创建自定义线程并使用 postRunnable。这应该是 DataStore 关心的事情,而不是应该在 UI 线程上运行的 Presenter 和 UI。一种解决方案是让您的数据存储改为异步,方法是您自己实现一些观察者模式或使用 RxJava。然后您可以使用 Realms 异步 API ( https://realm.io/docs/java/latest/#asynchronous-queries ) 执行以下操作:

// DataStore
public class DataStore {

private final Realm realm;

public DataStore() {
realm = Realm.getDefaultInstance(); // Called on the UI thread
}

public void getEvents(EventsLoadedListener listener) {
RealmResults<Event> results = realm.where(Events.class).findAllAsync();
results.addChangeListener(new RealmChangeListener() {
public void onChange() {
if (listener != null) {
listener.eventsLoaded(results);
}
}
});
}

public interface EventsLoadedListener {
public void eventsLoaded(List<Event> events);
}

}

// UI code
datastore.getEvents(new DataStore.EventsLoadedListener() {
public void eventsLoaded(List<Event> events) {
view.showEvents(events);
}
})

使用 RxJava 可以大大简化上面的代码,所以我真的鼓励你研究一下。 Realm 还原生支持 RxJava:https://realm.io/docs/java/latest/#rxjava

关于android - 处理多线程和 Realm 的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34856801/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com