Android 什么';处理多线程和领域的正确方法是什么?

Android 什么';处理多线程和领域的正确方法是什么?,android,multithreading,realm,Android,Multithreading,Realm,在我的Android应用程序中,我有一个数据访问层,其中每个数据存储类都有以下属性 Realm realm = Realm.getDefaultInstance(); 我的问题是当我试图从不同的线程调用任何数据存储方法时。然后我得到 领域对象只能在创建它们的线程上访问 我已经读到我应该在新线程上创建一个新的领域实例。问题是,数据访问层并没有线程意识,它不知道是从main调用的还是从separated调用的,在我看来,它会嗅到添加逻辑来检查这一点的味道 我在这里检查了不同的问题,并在github

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

Realm realm = Realm.getDefaultInstance();
我的问题是当我试图从不同的线程调用任何数据存储方法时。然后我得到

领域对象只能在创建它们的线程上访问

我已经读到我应该在新线程上创建一个新的领域实例。问题是,数据访问层并没有线程意识,它不知道是从main调用的还是从separated调用的,在我看来,它会嗅到添加逻辑来检查这一点的味道

我在这里检查了不同的问题,并在github上填写了问题,但我不清楚政府如何处理这种情况。我不认为我在处理一个奇怪的场景

编辑

我的ArquitArchitecture是一个包含Presenter的片段,其中包含一个数据存储

我检测到一个运行时间很长的进程,所以我将其移动到presenter上这样一个单独的线程

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() {
        ....
    }
});
final RealmResults results=query.findalsync();
results.addChangeListener(新的RealmChangeListener(){
@凌驾
更改后的公共无效(){
....
}
});
查询2

final RealmResults<T> result = realm.where(type).findAllAsync();
result.addChangeListener(new RealmChangeListener() {
    @Override
    public void onChange() {
        ...
    }
});
final RealmResults result=realm.where(type.findalsync();
result.addChangeListener(新的RealmChangeListener(){
@凌驾
更改后的公共无效(){
...
}
});
查询3

final RealmResults<PresentationSpeaker> results = query.findAllAsync();
results.addChangeListener(new RealmChangeListener() {
    @Override
    public void onChange() {
        ...
    }
});
final RealmResults results=query.findalsync();
results.addChangeListener(新的RealmChangeListener(){
@凌驾
更改后的公共无效(){
...
}
});

通常,自定义数据存储是异步的,以避免您现在遇到的问题:操作需要很长时间,您必须创建自定义线程并使用
postrunable
。这应该是数据存储关注的问题,而不是应该在UI线程上运行的演示者和UI。一种解决方案是让您的数据存储是异步的,或者自己实现一些观察者模式,或者使用RxJava。然后,您可以使用Realms async API()执行以下操作:

// 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);
    }
})
//数据存储
公共类数据存储{
私人最终领域;
公共数据存储(){
realm=realm.getDefaultInstance();//在UI线程上调用
}
public void getEvents(EventsLoadListener侦听器){
RealmResults results=realm.where(Events.class).findalsync();
results.addChangeListener(新的RealmChangeListener(){
更改后的公共无效(){
if(侦听器!=null){
listener.eventsLoaded(结果);
}
}
});
}
公共接口事件LadedListener{
公开作废事件(列出事件);
}
}
//用户界面代码
datastore.getEvents(新的datastore.EventsLoadedListener(){
已删除的公共无效事件(列出事件){
查看。showEvents(事件);
}
})

上面的代码可以使用RxJava进行大规模简化,因此我非常鼓励您对此进行研究。Realm本身也支持RxJava:

您能否对您的体系结构和使用的库多加评论。没有这些,你的问题真的很广泛。还有,在什么情况下你会切换线程?@ChristianMelchior:我不确定你的意思,我使用了哪些库,我使用了很多,但除了领域之外,没有一个与这个问题相关。如果我遗漏了什么,请告诉我。恐怕这个解决方案出了问题。我删除了线程创建逻辑,现在一行中有3个异步查询。在随机基础上,
onChange
未在
RealmChangeListener
上调用侦听器。我确信我正确地附加了侦听器,因为有时候它会命中它(这似乎取决于执行的查询有多重)。我确信它不会返回,因为不会花很长时间。添加了代码来附加这些查询的侦听器。有时,
onChange
会运行,有时不会运行。对于相同的查询参数,它的行为总是相同的:它运行或不运行。我100%确信,在所有情况下,它都会到达
findalsync
line当它行为错误时,只有第一个查询返回,而另外两个永远不会到达
onChange
发布的代码看起来是正确的,但没有说明调用它的上下文。我非常感谢您的帮助,但在这里粘贴1500行代码并不容易,我正在尝试粘贴相关代码,但如果您想在中看到任何内容,请告诉我:)关于如何调用包含这些查询的方法,没有有趣的逻辑,只在主线程中一行接一行,没有任何花哨的内容。我在github上看到过类似的问题,也许我只需要从0.84升级到最新版本。谢谢