我正在开发一个显示项目列表的应用程序,并允许用户添加更多项目并检查项目的详细信息。
假设我将数据库引用保留在活动中,添加ChildEventListener
个侦听器onResume()
并在onPause()
上删除它们:
public void onResume() {
super.onResume();
mItemChildEventListener = mDatabaseReference.child('items').addChildEventListener(new ChildEventListener() {
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
mAdapter.addItem(dataSnapshot.getValue(Item.class));
}
...
};
}
public void onPause() {
super.onPause();
if (mItemChildEventListener != null) {
mDatabaseReference.removeEventListener(mItemChildEventListener);
}
}
在这些ChildEventListener
中,我将逐项添加到项目列表中,并在适配器中调用notifyItemInserted(itemArray.size() - 1)
。
public void addItem(Item item) {
if (mItems == null) {
mItems = new ArrayList<>();
}
mItems.add(item);
notifyItemInserted(mItems.size() - 1);
}
另外,为了使应用程序保持平稳运行,我将项目列表保留在Reteiner Fragment中,保存此值onSaveInstanceState()
并在onCreate()
上恢复它们。
protected void onCreate(@Nullable Bundle savedInstanceState) {
if (savedInstanceState != null) {
mItems = getState(STATE_ITEMS);
} else {
mItems = new ArrayList<>();
}
mAdapter = new ItemAdapter(mItems);
}
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
saveState(STATE_ITEMS, mItems);
}
public <T> T getState(String key) {
//noinspection unchecked
return (T) mRetainedFragment.map.get(key);
}
public void saveState(String key, Object value) {
mRetainedFragment.map.put(key, value);
}
public static class RetainedFragment extends Fragment {
HashMap<String, Object> map = new HashMap<>();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// retain this fragment
setRetainInstance(true);
}
}
但是,如果我再次取消注册并注册侦听器,例如,通过任何方向更改或离开并重新注册到活动,将按预期调用onResume()
,并添加ChildEventListener
再次,检索相同的数据,如果未与项目列表mItems
中已包含的数据进行比较,则会复制该数据。
此外,如果我不保留项目列表mItems
,并且每次调用onResume()
时检索数据,列表将丢失其滚动位置并闪烁,因为它需要一些时间检索数据。
问题
如何在不再次检索项目的情况下保留检索项目列表,但是继续监听已检索项目的更改以及添加的新项目?有没有比将已检索的项目与新项目进行比较更好的解决方案,例如,通过密钥?
我已尝试查看文档和其他问题,但我找不到与此情况相关的任何信息。此外,我尝试在mDatabaseReference
中保留对onSaveInstanceState()
的引用,就像我对项目列表mItems
所做的那样,但它也没有用。
答案 0 :(得分:2)
答案 1 :(得分:2)
如果您在Firebase实时数据库SDK中enable persistence,则有助于防止对已经收到的数据进行不必要的提取。 SDK将在本地缓存获取数据,并且在可用时首先使用该数据:
FirebaseDatabase.getInstance().setPersistenceEnabled(true);
请务必read the documentation了解其工作原理。
另外请记住,在onStart和onStop期间启动和停止监听器是传统的。如果应用程序暂时失去焦点(例如,它弹出一个对话框,或者其他一些透明活动出现在顶部),这将避免更多的重新获取。