创建聊天应用程序时出现ConcurrentModificationException

时间:2019-01-07 17:08:13

标签: android firebase arraylist firebase-realtime-database

在应用程序中显示最近的聊天片段时,我正在从firebase中获取我的聊天记录,并在聊天对象中通过它们的receiveID和senderID过滤掉了聊天记录,以显示最近的聊天记录。

问题表明ArrayList中的ConcurrentModificationException,并且由于在数组中搜索ID的复杂性,我需要一种解决方案来最大程度地减少这种聊天过滤的复杂性。

  //私有列表 stringList;声明顶部
    stringList = new ArrayList <>();
    firebaseUser = FirebaseAuth.getInstance()。getCurrentUser();

    databaseReference = FirebaseDatabase.getInstance()。getReference(“ BaatCheet / Chats /”);
    databaseReference.addValueEventListener(new ValueEventListener(){
        @Override
        公共无效onDataChange(@NonNull DataSnapshot dataSnapshot){
            //userModelList.clear();
            对于(DataSnapshot dataSnapshot1:dataSnapshot.getChildren()){
                MessageModel messageModel = dataSnapshot1.getValue(MessageModel.class);

                如果(messageModel.getSender()。equals(firebaseUser.getUid())){
                  stringList.add(messageModel.getReceiver());
                }
                如果(messageModel.getReceiver()。equals(firebaseUser.getUid())){
                    stringList.add(messageModel.getSender());
                }
            }
            readChat();
        }
        @Override
        公共无效onCancelled(@NonNull DatabaseError databaseError){
        }
    });
 

阅读聊天功能

  private void readChat(){

    userModelList = new ArrayList <>();
    databaseReference = FirebaseDatabase.getInstance()。getReference(“ BaatCheet / Users /”);

    databaseReference.addValueEventListener(new ValueEventListener(){
        @Override
        公共无效onDataChange(@NonNull DataSnapshot dataSnapshot){
            userModelList.clear();
            对于(DataSnapshot dataSnapshot1:dataSnapshot.getChildren()){
                UserModel userModel = dataSnapshot1.getValue(UserModel.class);

                对于(String id:stringList){
                    如果(userModel.getId()。equals(id)){
                        如果(userModelList.size()!= 0){
                            对于(UserModel userModel1:userModelList){
                                如果(!userModel.getId()。equals(userModel1.getId())){
                                    userModelList.add(userModel);
                                    Log.d(“ DataAdded”,userModel.getId());
                                } //如果现有列表的发件人和收件人没有相同的值
                            } //内部userModel的结尾
                        }其他{
                            userModelList.add(userModel);
                            Log.d(“ DataAdded”,userModel.getId());
                        } //其他结尾
                    } // userModel id的结尾等于字符串id
                } // String的结尾是循环
            } // DataSnapshot循环的结尾

            usersAdapter =新的UsersAdapter(userModelList);
            recyclerView.setAdapter(usersAdapter);


        } // onDataChange的结尾

        @Override
        公共无效onCancelled(@NonNull DatabaseError databaseError){
        }
    });
} // readChat()的结尾
 

结果将是包含聊天的最近聊天的recyclerView,该聊天包含发件人或收件人相互发送的消息。

2 个答案:

答案 0 :(得分:1)

在以下代码段中:

for (UserModel userModel1 : userModelList){
   if (!userModel.getId().equals(userModel1.getId())){
        userModelList.add(userModel);
        Log.d("DataAdded",userModel.getId());
    } // If the existing list don't have same value for sender and reciever
} //

您正在遍历userModelList的同时修改userModelList。这是不允许的,并且是ConcurrentModificationException的原因。

简化逻辑的方法很少,最简单(尽管不是最好)的方法是将这个foreach循环转换为简单的for i循环。

for (int i = 0; i< userModelList.size(); i++) {
    UserModel userModel1 = userModelList.get(i);
    if (!userModel.getId().equals(userModel1.getId())){
       userModelList.add(userModel);
       Log.d("DataAdded",userModel.getId());
    } // If the existing list don't have same value for sender and reciever
} //

答案 1 :(得分:0)

基本上是为了处理这种复杂性,我现在仅使用单独的节点来存储chatList,因此现在无需阅读聊天记录即可过滤最近的聊天记录。

以下代码用于在用户每次发送消息时创建一个新节点,如果recieverID不同,它将更新该节点。

dbrefChatList = FirebaseDatabase.getInstance().
                getReference("BaatCheet/ChatList/")
                .child(senderuserID)
                .child(receiveruserID);

        dbrefChatList.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                if (!dataSnapshot.exists()){
                    dbrefChatList.child("id").setValue(receiveruserID);
                }
            }
            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
            }
        });

这样的ChatList是一个Model类,其中包含一个名为“ id”的字符串,该id将用于在节点中搜索。

下面的代码是针对ChatFragment的,该片段从firebase中获取chatList并将数据设置为回收者视图。

      // private List<ChatList> chatList; Declaration at top
    chatListList = new ArrayList<>();
    firebaseUser = FirebaseAuth.getInstance().getCurrentUser();

    databaseReference = FirebaseDatabase
            .getInstance()
            .getReference("BaatCheet/ChatList")
            .child(firebaseUser.getUid());

    databaseReference.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

            chatListList.clear();
                for (DataSnapshot snapshot : dataSnapshot.getChildren()){
                    ChatList chatList = snapshot.getValue(ChatList.class);
                    chatListList.add(chatList);
                }
                myChatList();
        }
        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {
        }
    });

问题声明中的函数myChatList充当readChat的功能。

 private void myChatList() {

    userModelList = new ArrayList<>();
    databaseReference = FirebaseDatabase.getInstance().getReference("BaatCheet/Users/");
    databaseReference.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            userModelList.clear();
            for (DataSnapshot snapshot : dataSnapshot.getChildren()){
                UserModel userModel = snapshot.getValue(UserModel.class);
                for (ChatList chatList : chatListList){
                    if (userModel.getId().equals(chatList.getId())){
                        userModelList.add(userModel);
                    }
                }
            }
            usersAdapter = new UsersAdapter(userModelList);
            recyclerView.setAdapter(usersAdapter);
        }
        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {
        }
    });

}