【问题标题】:Android chat app crashes due to java.util.ConcurrentModificationException由于 java.util.ConcurrentModificationException,Android 聊天应用程序崩溃
【发布时间】:2021-01-15 15:10:38
【问题描述】:

当我收到来自另一台设备的消息时,我的聊天应用程序崩溃了。它是用 android studio 和 firebase 制作的。这是我得到的异常:java.util.ConcurrentModificationException at

for (User user1 : nUsers) {

存在于 readChats() 中:

 private void readChats() {
        nUsers = new ArrayList<>();

        reference = FirebaseDatabase.getInstance().getReference("Users");

        reference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                nUsers.clear();

                for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
                    User user = dataSnapshot.getValue(User.class);

                    for (String id : usersList){
                        if (user.getId().equals(id)) {
                            if (nUsers.size() != 0) {
                                 for (User user1 : nUsers) {
                                    if (!user.getId().equals(user1.getId()))
                                        nUsers.add(user);
                                }
                            } else {
                                nUsers.add(user);
                            }
                        }
                    }
                }

整个代码:

public class ChatsFragment extends Fragment {
   
       private RecyclerView recyclerView;
       private userAdapter userAdapter;    private List<User> nUsers;
       FirebaseUser fuser;    DatabaseReference reference;
       private List<String> usersList;
       @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                            Bundle savedInstanceState) {
   
       View view = inflater.inflate(R.layout.fragment_chats, container, false);
   
       recyclerView = view.findViewById(R.id.chat_list);
       recyclerView.setHasFixedSize(true);
       recyclerView.setLayoutManager(new LinearLayoutManager((getContext())));
   
       fuser = FirebaseAuth.getInstance().getCurrentUser();
   
       usersList = new ArrayList<>();
   
       reference = FirebaseDatabase.getInstance().getReference("Chats");
       reference.addValueEventListener(new ValueEventListener() {
           @Override
           public void onDataChange(@NonNull DataSnapshot snapshot) {
   
               usersList.clear();
               for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
                   Chat chat = dataSnapshot.getValue(Chat.class);
   
                   assert chat != null;
                   if (chat.getSender().equals(fuser.getUid())) {
                       usersList.add(chat.getReceiver());
                   }
                   if (chat.getReceiver().equals(fuser.getUid())) {
                       usersList.add(chat.getSender());
                   }
               }
               readChats();
           }
   
           @Override
           public void onCancelled(@NonNull DatabaseError error) {
   
           }
       });
       return view;    }
       private void readChats() {
       nUsers = new ArrayList<>();
   
       reference = FirebaseDatabase.getInstance().getReference("Users");
   
       reference.addValueEventListener(new ValueEventListener() {
           @Override
           public void onDataChange(@NonNull DataSnapshot snapshot) {
               nUsers.clear();
   
               for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
                   User user = dataSnapshot.getValue(User.class);
   
                   for (String id : usersList){
                       if (user.getId().equals(id)) {
                           if (nUsers.size() != 0) {
                                for (User user1 : nUsers) {
                                   if (!user.getId().equals(user1.getId()))
                                       nUsers.add(user);
                               }
                           } else {
                               nUsers.add(user);
                           }
                       }
                   }
               }
   
               userAdapter = new userAdapter(getContext(), nUsers);
               recyclerView.setAdapter(userAdapter);
           }
   
           @Override
           public void onCancelled(@NonNull DatabaseError error) {
   
           }
       });    } }

【问题讨论】:

    标签: java android android-studio


    【解决方案1】:

    在这里,您在使用 foreach 循环进行迭代的同一列表中添加项目,例如

    for (User user1 : nUsers) {
                   if (!user.getId().equals(user1.getId()))
                        nUsers.add(user);
    }
    

    Java Collection 类是快速失败的,这意味着如果在某个线程使用迭代器遍历它时更改 Collection,iterator.next() 将抛出 ConcurrentModificationException。

    这种情况可能出现在多线程和单线程环境中。 - www.javacodegeeks.com

    在for/each循环内调用.add()会修改内容,后台使用的Iterator看到这个并抛出这个异常

    解决方案

    1. 使用迭代器

    我们可以通过将增强的 for 循环替换为使用 Iterator 对象的 while 循环来改变我们的迭代方式。 Iterator 允许我们安全地删除匹配的元素,因为我们没有直接在列表对象上调用 remove()

    1. 填充单独的列表以跟踪要删除的项目

    这种方法避免了引入 Iterator 对象,但它需要另一个列表来跟踪我们要删除的名称

    【讨论】:

      猜你喜欢
      • 2017-05-31
      • 2021-04-20
      • 2016-04-06
      • 1970-01-01
      • 2019-01-19
      • 1970-01-01
      • 1970-01-01
      • 2017-07-22
      • 1970-01-01
      相关资源
      最近更新 更多