我的ViewPager
包含三个不同的Fragments
,每个片段都有自己的API调用。让我们说第一个片段是从API请求某些东西。返回回调,然后我将其保存到本地Realm
数据库,之后我将EventBus
发送给Fragment。问题是我得到No subscribers registered for event class
错误并且没有任何反应。
过了一段时间,我设法用这种方式解决了这个问题:
final GetInfoResponse response = new GetInfoResponse(databaseService.getInfo());
new Handler().post(new Runnable() {
public void run() {
EventBus.getDefault().post(response);
}
});
如果我将EventBus放入Handler中,则Event
会正确传递给Fragment。
我在想,在从数据库获取数据时,Realm
可能正在切换线程。但我不确定。另一方面,如果我没有进行本地保存并直接从REST回调发送EventBus
,那么一切正常。
编辑:
GetInfo
方法
public List<Information> getInfo() {
List<Information> informationList;
Realm realm = Realm.getInstance(getConfig(context));
realm.beginTransaction();
RealmResults<Information> realmList = realm.where(Information.class).findAll();
informationList = new ArrayList<>(realmList);
realm.commitTransaction();
return informationList;
}
为什么会这样,我怎样才能做得更好?
编辑2:
经过@EpicPandaForce提出的变更。
这是我的代码结构和调用API的路径。
我有碎片。我们称之为InfoFragment
。在onCreateView
我这样做:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.info, container, false);
realm = Realm.getInstance(DatabaseConfiguration.getConfig(getActivity()));
DataManager dataManager = new DataManager(realm, getActivity());
dataManager.getInfo();
return view;
}
public void onEvent(GetFaqCategoriesResponse response) {
...
}
@Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
@Override
public void onStop() {
EventBus.getDefault().unregister(this);
super.onStop();
}
现在,我的DataManager
看起来像这样:
public DataManager(Realm realm, Context context) {
this.context = context;
databaseService = new DatabaseService(realm);
}
public void getInfo() {
if (ConnectionUtils.isNetworkAvailable(context)) {
ServerService.getInfo(this);
} else {
final GetInfoResponse response
= new GetInfoResponse(databaseService.getInfo());
new Handler().post(new Runnable() {
public void run() {
EventBus.getDefault().post(response);
}
});
}
}
我的DatabaseService
:
private Realm realm;
public SupportDatabaseService(Realm realm) {
this.realm = realm;
}
public List<Info> getInfo() {
RealmResults<Info> realmList = realm.where(Info.class).findAll();
return new ArrayList<>(realmList);
}
我正在使用Realm
realm.close()
onDestroyView
中的InfoFragment
关闭{{1}}个实例。
答案 0 :(得分:1)
要自动更新所有looper线程上的Realms,Realm sends a message to the main thread looper's handler在提交事务时开始更新。因此,除非您订阅了RealmListener
中的Realm的更改(我不推荐,因为它每次修改领域都会更新!),您只会在下一个处理程序循环运行时收到有关它的通知。如果您使用onEvent()
,那么就像default threading mode所指定的那样,您的事件将立即传递,而不是通过处理程序(在下一次迭代时发送runnable在另一个looper线程上执行)。
基本上,如果您不通过处理程序发送它,那么在接收事件时,其他线程的Realm将不会更新。如果要将这些Realm对象从主线程发送到主线程,则可以使用onEventMainThread()
而不是onEvent()
自动将其通过处理程序传递给主线程。
顺便说一句,你正在错误地使用Realm,你打开的Realm实例也应该被关闭,但是只能在同一个线程上访问与给定Realm相关联的Realm对象,并且只能从一个开放的领域。您无需打开新领域来执行查询,您可以使用在findAll()
中打开的Realm实例在主线程上使用onCreateView()
,同时在onDestroyView()
中关闭它},findAll()
作为惰性查询执行,因此不会占用大量内存。即使你实际上没有做任何写作,你也开始并进行交易......? :P