android - 如何从 RecyclerView 清除数据监听器/订阅?

标签 android firebase firebase-realtime-database android-recyclerview android-lifecycle

<分区>

注意:请不要建议将 FirebaseUI 作为答案。

我正在尝试设计一个聊天列表用户界面。为此,我将数据填充到我的 recyclerview,它显示聊天组列表以及最后一条消息。我希望实时更新最后一条消息。因此,为了做到这一点,我在 onBindViewHolder 方法中设置了一些监听器/订阅,它们不断地监听新数据并更新 View 。

我面临的问题是,如果用户迁移到其他 Activity ,当数据库中的聊天列表数据发生变化时,应用程序会崩溃。这是因为监听器仍在后台运行并尝试更新已销毁 Activity 的 View 。

我正在寻找一种方法来在 recyclerview 被销毁时关闭我的听众/订阅。我试过使用 onViewDetachedFromWindow 但它只适用于回收器在屏幕上时回收的 View 。如果我只读取一次数据,我会在订阅完成后立即清理它们,但我的用例是持续监听数据的变化。

一些示例代码:

protected void onBindViewHolder(@NonNull ChatViewHolder holder,
                                int position, @NonNull FirebaseConversationRecord model) {
    final CardView cardView = (CardView) holder.itemView;
    ...
    final ValueEventListener listener = new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            Log.v("FIREBASEADAPTERLISTENER", dataSnapshot.getKey());
            FirebaseUserRecord data = dataSnapshot.getValue(FirebaseUserRecord.class);
            textViewName.setText(data.getName());

            GlideApp.with(cardView.getContext())
                    .load(data.getProfilePicURL())
                    .into(imageView);
        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {
            Log.v("FIREBASEADAPTERLISTENER", databaseError.getMessage());
        }
    };
    ...
 }

编辑 这个问题是关于 RecyclerView 的上下文以及如何在 onBindView 期间附加监听器。它与从 Activity 中添加/删除单个监听器不同,后者可以非常直接地实现。

最佳答案

使用以下方法从 DatabaseReference onDestroy 中删除 ValueEvenetListener

DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("");
    ValueEventListener valueEventListener = new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            //here you gets the data
        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {
            //if some error occurs
        }
    };

    //add value event listener
    databaseReference.addValueEventListener(valueEventListener);

    //remove enet listener
    databaseReference.removeEventListener(valueEventListener);

这只是一个提示

确定这样做:

//here you require the instance of activity
//in your onDataCahnge method 
if(activity.getApplicationContext() != null){
   //implement all the ui change here
}else{
  //here you remove the ValueEventListener
  databaseReference.removeEventListener(valueEventListener);
}

关于android - 如何从 RecyclerView 清除数据监听器/订阅?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53421087/

相关文章:

android - 为什么 9-patch 是水平缩放的

java - 解决SecurityException : Permission Denial: starting Intent. 我需要什么权限?

java.lang.RuntimeException : Found conflicting getters for name isImportantForAccessibility on class androidx. appcompat.widget.AppCompatImageView

javascript - Promise.all 不等待 firestore 查询循环

java - Firebase:检查是否有任何元素具有特定的属性值

android - 没有缩放级别的 Android MapView

android - 使用 gradle DSL 声明多模块项目中的 flavor 依赖性

cordova - PhoneGap 移动应用中的 Firebase URL 安全性

swift - 自动生成的 ID 标签的 Firebase 分组

android - 在使用电子邮件和密码身份验证的 firebase 中,我想使用推送来附加用户数据