我试图在非UI线程上更新数据库,但是在主线程上注册的changeListener(同时)有时不会被调用 . 每个Activity在调用onStart方法时添加该侦听器,并在onStop上取消注册 .
这是简单的应用程序流程:
Activity1包含已创建项目的列表 . 当用户想要添加新项目时,将启动Activity2 . 用户填写所有必填字段,然后按添加btn - >将创建的项目添加到具有临时ID的本地数据库中,并将作业添加到队列以在远程上创建该项目 . 在这两个操作之后,Activit2关闭(调用 finish()
),用户返回Activity1,其中包含所有已创建项目(包括新项目)的列表 . 同时,完成了在远程创建新项目的工作,并且在其 onRun()
方法中,创建的对象的tmpID被替换为从服务器检索的新对象 . 但是, at this point Activity1 do not get notified 关于数据库的更改 .
活动注册监听器如下:
public Activity extends AppCompatActivity {
private Realm mRealm;
private RealmChangeListener listener = element -> Log.d("Called");
@Override
protected void onStart() {
super.onStart();
mRealm = Realm.getDefaultInstance();
mRealm.addChangeListener(realmChangeListener);
}
@Override
protected void onStop() {
super.onStop();
mRealm.removeChangeListener(realmChangeListener);
mRealm.close();
}
}
这是作业方法,在工作线程上运行
@WorkerThread
public void onRun() {
Response<ItemResponse> response = mAPI.createItem(text).execute();
if(response.isSuccessful){
Realm realm = Realm.getDefaultInstance();
realm.executeTransaction(r ->{
Item i = r.where(Item.class).equalTo("id", tmpID).findFirst();
if(i != null){
i.id = response.body().id;
}
});
realm.close();
// At this point onChange() method of realmChangeListener should be fired
}
}
另一方面,如果我将继续使用Activity2(在将项目添加到本地数据库后不调用 finish()
)并等到作业完成,则正确调用 onChange()
RealmChangeListener方法...
两个线程都在同一进程上运行 .
我很感激任何建议
EDIT
Activity1附加了一个片段,该片段包含项目列表 . 片段然后根据onStart和onStop回调中的最佳实践Controlling the lifecycle of Realm instances为侦听器注册 .
@Override
public void onStart() {
super.onStart();
mRealm = Realm.getDefaultInstance();
mRealm.addChangeListener(realmChangeListener);
}
@Override
public void onStop() {
super.onStop();
mRealm.removeChangeListener(realmChangeListener);
mRealm.close();
}
片段的生命周期,当Activity2为:
Launched
- onPause
Closed using back button or by calling finish()
-
onStart
-
onResume
出于某种原因,当手动关闭Activity2时,使用后退按钮调用 realmChangeListener
. 但是,如果我使用finish()关闭它,没有任何反应......
1 回答
最后,几个小时后我发现了问题所在......
Activity1有一个与项目列表相连的Fragment,该片段侦听realm数据库上的更改以更新UI . 当用户想要添加新项目时,Activity2已经启动,并且还有一个演示者,它正在从本地数据库中加载一些东西 . 那位主持人还在听Realm DB .
And here is the problem: 当用户添加新项目且Activity2即将完成时,会在演示者上调用
close()
方法以清除资源 . 在close()
方法中调用的命令之一是mRealm.removeAllChangeListeners()
. 这不会是一个问题,因为来自Activity1的片段在onStart()
回调中再次注册其侦听器,但是在片段上,在演示者上的close()
方法被称为 AFTERonStart()
. 所以,基本上它从片段中删除了新注册的监听器 .再次,谢谢你们的意愿! @beeender,@ EpicPandaForce