Java 如何在RecyclerView项的populateViewHolder中设置addSnapshotListener和删除?
我已经用FirebaseUI Android库实现了Java 如何在RecyclerView项的populateViewHolder中设置addSnapshotListener和删除?,java,android,firebase,google-cloud-firestore,firebaseui,Java,Android,Firebase,Google Cloud Firestore,Firebaseui,我已经用FirebaseUI Android库实现了RecyclerView 我的RecyclerView实时数据在使用该FirebaseRecyclerAdapter 在集合中,该数据文档的字段类型为 我想使用该引用在populateViewHolder中使用addSnapshotListener获取数据 救救我!这是我的密码: FirebaseRecyclerAdapter<Conv, ConvViewHolder> firebaseConvAdapter =
RecyclerView
我的RecyclerView
实时数据在使用该FirebaseRecyclerAdapter
在集合中,该数据文档的字段类型为
我想使用该引用在populateViewHolder
中使用addSnapshotListener
获取数据
救救我!这是我的密码:
FirebaseRecyclerAdapter<Conv, ConvViewHolder> firebaseConvAdapter = new FirebaseRecyclerAdapter<Conv, ConvViewHolder>(
Conv.class,
R.layout.users_single_layout,
ConvViewHolder.class,
conversationQuery
) {
@Override
protected void populateViewHolder(final ConvViewHolder convViewHolder, final Conv conv, int i) {
final String list_user_id = getRef(i).getKey();
final DocumentReference docRef = db.collection("cities").document(list_user_id);
docRef.addSnapshotListener(new EventListener<DocumentSnapshot>() {
@Override
public void onEvent(@Nullable DocumentSnapshot snapshot,
@Nullable FirebaseFirestoreException e) {
if (e != null) {
Log.w(TAG, "Listen failed.", e);
return;
}
if (snapshot != null && snapshot.exists()) {
Log.d(TAG, "Current data: " + snapshot.getData());
} else {
Log.d(TAG, "Current data: null");
}
}
});
}
};
mConvList.setAdapter(firebaseConvAdapter);
FirebaseRecyclerAdapter firebaseConvAdapter=新的FirebaseRecyclerAdapter(
会议室,
R.layout.users\u single\u布局,
ConvViewHolder.class,
会话查询
) {
@凌驾
受保护的void populateViewHolder(最终ConvViewHolder,最终Conv Conv,int i){
最终字符串列表_user_id=getRef(i).getKey();
最终文件参考docRef=db.集合(“城市”).文件(列表用户id);
docRef.addSnapshotListener(新的EventListener(){
@凌驾
public void onEvent(@Nullable DocumentSnapshot快照,
@可为空的FireBaseFireStore异常(e){
如果(e!=null){
Log.w(标记“侦听失败”,e);
返回;
}
if(snapshot!=null&&snapshot.exists()){
Log.d(标记“当前数据:”+snapshot.getData());
}否则{
Log.d(标记“当前数据:null”);
}
}
});
}
};
mConvList.setAdapter(firebaseConvAdapter);
Firebase说,如果您添加addSnapshotListener,则必须在不需要时将其删除
当您对侦听数据不再感兴趣时,必须分离侦听器,以便停止调用事件回调。这允许客户端停止使用带宽来接收更新。您可以使用onSnapshot()
上的unsubscribe函数停止收听更新
要实现这一点,您需要像这样使用
EventListener
:
EventListener<DocumentSnapshot> eventListener = new EventListener<DocumentSnapshot>() {
@Override
public void onEvent(DocumentSnapshot snapshot, FirebaseFirestoreException e) {
if (snapshot != null && snapshot.exists()) {
//Do what you need to do
}
}
};
if (listenerRegistration == null ) {
listenerRegistration = yourRef.addSnapshotListener(eventListener);
}
要删除侦听器,只需在onStop()
方法中使用以下代码行:
@Override
protected void onStop() {
if (listenerRegistration != null) {
listenerRegistration.remove();
}
}
另外,调用onStart()
方法后,不要忘记再次添加它
@Override
protected void onStart() {
super.onStart();
listenerRegistration = yourRef.addSnapshotListener(eventListener);
}
当您为调用addSnapshotListener
时,这意味着您附加了一个侦听器,该侦听器会为数据库中发生的每个更改而被调用。因此,当你的应用程序关闭时,也会发生这种情况,这就是为什么在活动被破坏之前必须关闭
如果在你的应用程序中,你不需要实时获取数据,那么你可以直接调用引用,只需读取文档一次。因为它只读取一次,所以没有要删除的侦听器。这是Firebase实时数据库中使用的addListenerForSingleValueEvent()
的对应项
还有一种更优雅的删除侦听器的方法,即将活动作为方法中的第一个参数传递,这样Firestore可以在活动停止时自动清理侦听器
ListenerRegistration lg = yourDocumentRef
.addSnapshotListener(YourActivity.this, eventListener);
还有一种更优雅的删除侦听器的方法,即在addSnapshotListener()方法中将活动作为第一个参数传递,这样Firestore可以在活动停止时自动清理侦听器。
大宗报价
这非常重要。我并没有寻找“优雅的方式”,但这暗示了为什么我的听众有时会停下来。我删除了“活动”字段,现在监听器在活动状态发生变化的情况下,在没有直接指令的情况下不会停止 我想在回收器适配器项目中使用。在使用侦听器的适配器中使用大量数据的同时,大量使用firebase的带宽。如果您删除侦听器,将不再有问题。你试过我的代码吗?是的,我已经试过了,但这是不是最好的方法?因为谷歌说大量使用监听器会导致大量数据使用带宽。是的,这绝对是最好的方式!是的,这是正确的,丢失侦听器可能会导致带宽的大量使用,但前提是您不删除它们。因此,使用我的答案中的代码,将解决您的问题。你认为我的回答对你有帮助吗?是的。我只担心带宽,所以这就是为什么提出这个问题。谢谢你的大力帮助。:)