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