I am trying to update database on non UI thread, however changeListener registered on main thread (at the same time) sometimes not get called. Each Activity adds that listener when onStart method is called, and unregister on onStop.
Here is the simple application flow:
Activity1 contains a list of already create items. When user wants to add new item, Activity2 is launched. User fills all required fields and press add btn -> created item is added into local database with temporary ID, and job is added to queue to create that item on remote. After these two operations, Activit2 is closed (calling finish()
) and user is back on Activity1 with list of all already created items (including the new one). Meanwhile, job for creating new item on remote is finished, and within its onRun()
method, tmpID of created object is replaced with new one that was retrieved from server. However, at this point Activity1 do not get notified about change in database.
Activities register listener like this:
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();
}
}
This is method of job, that is run on worker thread
@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
}
}
On the other side, if I would stay on Activity2(not calling finish()
after item is added into local DB) and wait until job get finished, onChange()
method of RealmChangeListener is called properly...
Both of threads runs on the same process.
I am thankful for any suggestions
EDIT
Activity1 has a fragment attached to it, an that fragment contains list of items. Fragment then registers for listeners according to Best practises - Controlling the lifecycle of Realm instances within onStart and onStop callbacks.
@Override
public void onStart() {
super.onStart();
mRealm = Realm.getDefaultInstance();
mRealm.addChangeListener(realmChangeListener);
}
@Override
public void onStop() {
super.onStop();
mRealm.removeChangeListener(realmChangeListener);
mRealm.close();
}
Lifecycle of Fragment, when Activity2 is:
Launched
Closed using back button or by calling finish()
For some reason, when Activity2 is closed manually, using back button, realmChangeListener
is called. However, if I close it using finish(), nothing happens ...
答案 0 :(得分:1)
最后,几个小时后我发现了问题所在......
Activity1附加了一个带有项目列表的Fragment,该片段侦听realm数据库上的更改以更新UI。当用户想要添加新项目时,Activity2已经启动,并且还有一个演示者,它正在从本地数据库中加载一些东西。那位主持人还在听Realm DB。
以下是问题:
当用户添加新项目并且Activity2即将完成时,会在演示者上调用close()
方法来清除资源。在close()
方法中调用的命令之一是mRealm.removeAllChangeListeners()
。这不会是一个问题,因为Activity1中的片段会在onStart()
回调中再次注册其侦听器,但片段上的{{1>}方法在片段上被称为 AFTER close()
。所以,基本上它从片段中删除了新注册的监听器。
再次,谢谢你们的意愿! @beeender,@ EpicPandaForce