我遇到了一个致命异常:主进程:umo.com.players,PID:29401。

huangapple go评论82阅读模式
英文:

I am having a FATAL EXCEPTION: main Process: umo.com.players, PID: 29401

问题

以下是翻译好的部分:

我遇到了一个 FATAL EXCEPTION: main
    进程umo.com.playersPID29401
如何解决 Fatal Exception 的错误
我从未遇到过这种错误
我需要尝试并完成这个项目  java.util.ConcurrentModificationException
这是我的日志记录
请帮忙

2020-10-14 15:52:11.691 29401-29401/? E/AndroidRuntime: FATAL EXCEPTION: main
    进程umo.com.playersPID29401
    java.util.ConcurrentModificationException
        在 java.util.ArrayList$Itr.next(ArrayList.java:860)
        在 umo.com.players.Home.ChatFragment$2.onDataChange(ChatFragment.java:98)
        在 com.google.android.gms.internal.zzbpx.zza(Unknown Source:13)
        在 com.google.android.gms.internal.zzbqx.zzZV(Unknown Source:2)
        在 com.google.android.gms.internal.zzbra$1.run(Unknown Source:63)
        在 android.os.Handler.handleCallback(Handler.java:790)
        在 android.os.Handler.dispatchMessage(Handler.java:99)
        在 android.os.Looper.loop(Looper.java:164)
        在 android.app.ActivityThread.main(ActivityThread.java:6739)
        在 java.lang.reflect.Method.invoke(Native Method)
        在 com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:449)
        在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

这是聊天片段

public class ChatFragment extends Fragment {

    private RecyclerView recyclerView;
    private UserAdapter userAdapter;
    private List<User> mUsers;

    FirebaseUser fuser;
    DatabaseReference reference;

    private List<String> usersList;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_messages, container, false);

        recyclerView = view.findViewById(R.id.recycler_view);
        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(DataSnapshot dataSnapshot) {
                usersList.clear();
                for (DataSnapshot snapshot : dataSnapshot.getChildren()){
                    Chat chat = snapshot.getValue(Chat.class);

                    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(DatabaseError databaseError) {

            }
        });

        return view;
    }

    private void readchats() {
        mUsers = new ArrayList<>();

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

        reference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                mUsers.clear();

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

                    for (String id : usersList){
                        if (user.getUser_id().equals(id)){
                            if (mUsers.size() !=0 ){
                                for (User user1 : mUsers){
                                    if (!user.getUser_id().equals(user1.getUser_id())){
                                        mUsers.add(user);
                                    }
                                }
                            }else {
                                mUsers.add(user);
                            }
                        }
                    }
                }
                userAdapter = new UserAdapter(getContext(), mUsers);
                recyclerView.setAdapter(userAdapter);
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });
    }
}
英文:

I am having a FATAL EXCEPTION: main
Process: umo.com.players, PID: 29401
How do you solve the error of Fatal Exception
I have never had any kind of this error
I need to try and finish this project java.util.ConcurrentModificationException
here is my logcat
Please help

2020-10-14 15:52:11.691 29401-29401/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: umo.com.players, PID: 29401
java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.next(ArrayList.java:860)
at umo.com.players.Home.ChatFragment$2.onDataChange(ChatFragment.java:98)
at com.google.android.gms.internal.zzbpx.zza(Unknown Source:13)
at com.google.android.gms.internal.zzbqx.zzZV(Unknown Source:2)
at com.google.android.gms.internal.zzbra$1.run(Unknown Source:63)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6739)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:449)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

here is chat fragment

public class 
ChatFragment 
extends Fragment {
private RecyclerView recyclerView;
private UserAdapter userAdapter;
private List&lt;User&gt; mUsers;
FirebaseUser fuser;
DatabaseReference reference;
private List&lt;String&gt; usersList;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_messages, container, false);
recyclerView = view.findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
fuser = FirebaseAuth.getInstance().getCurrentUser();
usersList = new ArrayList&lt;&gt;();
reference = FirebaseDatabase.getInstance().getReference(&quot;chats&quot;);
reference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
usersList.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()){
Chat chat = snapshot.getValue(Chat.class);
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(DatabaseError databaseError) {
}
});
return view;
}
private void readchats() {
mUsers = new ArrayList&lt;&gt;();
reference = FirebaseDatabase.getInstance().getReference(&quot;users&quot;);
reference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
mUsers.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()){
User user = snapshot.getValue(User.class);
for (String id : usersList){
if (user.getUser_id().equals(id)){
if (mUsers.size() !=0 ){
for (User user1 : mUsers){
if (!user.getUser_id().equals(user1.getUser_id())){
mUsers.add(user);
}
}
}else {
mUsers.add(user);
}
}
}
}
userAdapter = new UserAdapter(getContext(), mUsers);
recyclerView.setAdapter(userAdapter);
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}

答案1

得分: 1

这个异常意味着你正在尝试在某段代码正在迭代列表时对其进行结构性修改。

这是ArrayList的默认行为,并可以通过以下文档支持:

> 该类的iterator和listIterator方法返回的迭代器是快速失败的:如果在创建迭代器之后,任何时候以任何方式对列表进行了结构性修改,除非是通过迭代器自己的remove或add方法,否则迭代器将抛出ConcurrentModificationException。因此,在面对并发修改时,迭代器会快速而干净地失败,而不是冒着在未来某个不确定的时间面临任意的、不确定的行为的风险。
>
> 请注意,由于在存在不同步的并发修改的情况下很难做出任何硬性保证,迭代器的快速失败行为无法得到保证。快速失败迭代器基于最大努力原则在抛出ConcurrentModificationException。因此,编写一个依赖于此异常来确保正确性的程序是错误的:迭代器的快速失败行为只应用于检测错误。

有关所涉及文档的链接在此

现在根据我从共享代码中获取的信息,你有一个名为

private List&lt;String&gt; usersList;

的普通列表,你在这里对它进行了修改:

@Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            usersList.clear();
            for (DataSnapshot snapshot : dataSnapshot.getChildren()){
                Chat chat = snapshot.getValue(Chat.class);

                if (chat.getSender().equals(fuser.getUid())){
                    usersList.add(chat.getReceiver());
                }
                if (chat.getReceiver().equals(fuser.getUid())){
                    usersList.add(chat.getSender());
                }
            }
            readchats();
        }

这里有两种类型的修改:

  1. 清空列表
  2. 添加新元素

与此同时,你在以下代码段中迭代了所涉及的列表:

 for (String id : usersList){
                    if (user.getUser_id().equals(id)){
                        if (mUsers.size() !=0 ){
                            for (User user1 : mUsers){
                                if (!user.getUser_id().equals(user1.getUser_id())){
                                    mUsers.add(user);

                                }
                            }
                        }else {
                            mUsers.add(user);
                        }
                    }
                }

由于这两段代码是以异步方式执行的,没有保证在某人修改列表的同时,另一个人将在其上进行迭代。

我建议您重新检查代码以解决这个问题,或者找到其他迭代所涉及列表的方法。

英文:

This exception means that you are attempting to structurally modify a list while some piece of code is in the process of iterating it.

This is the default behavior of the ArrayList and can be backed up by the following piece of documentation:

> The iterators returned by this class's iterator and listIterator
> methods are fail-fast: if the list is structurally modified at any
> time after the iterator is created, in any way except through the
> iterator's own remove or add methods, the iterator will throw a
> ConcurrentModificationException. Thus, in the face of concurrent
> modification, the iterator fails quickly and cleanly, rather than
> risking arbitrary, non-deterministic behavior at an undetermined time
> in the future.
>
> Note that the fail-fast behavior of an iterator cannot be guaranteed
> as it is, generally speaking, impossible to make any hard guarantees
> in the presence of unsynchronized concurrent modification. Fail-fast
> iterators throw ConcurrentModificationException on a best-effort
> basis. Therefore, it would be wrong to write a program that depended
> on this exception for its correctness: the fail-fast behavior of
> iterators should be used only to detect bugs.

Link to the document in question here.

Now from what I can tell from the share code, you can a common list named

private List&lt;String&gt; usersList;

Which you modify here:

@Override
public void onDataChange(DataSnapshot dataSnapshot) {
usersList.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()){
Chat chat = snapshot.getValue(Chat.class);
if (chat.getSender().equals(fuser.getUid())){
usersList.add(chat.getReceiver());
}
if (chat.getReceiver().equals(fuser.getUid())){
usersList.add(chat.getSender());
}
}
readchats();
}

There are two kind of modifications here:

  1. Clearing the list
  2. Adding new elements

At the same time you iterate the list in question in this code segment:

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

Since both piece of code are executed in an asynchronous manner, there is no guarantee that someone will be modifying the list while someone else will be iterating over it.

I suggest you revisit your code to address this or find some other way of iterating the list in question.

答案2

得分: 0

你遇到了ConcurrentModificationException,这是因为你正在尝试在for循环内部修改列表。可以通过以下几种方式解决这个问题:

  1. 你可以使用CopyOnWriteArrayList作为mUsers列表的类型。

  2. 或者你可以在循环内部创建新的列表来进行操作

    for (User user1 : new ArrayList&lt;&gt;(mUsers)){...}

  3. 或者你可以通过为新项目添加临时列表的方式以更经济的方式解决

List&lt;User&gt; usersToBeAdded = new ArrayList&lt;User&gt;();
for (User user1 : mUsers){
    if (!user.getUser_id().equals(user1.getUser_id())){
        usersToBeAdded.add(user);
}}
mUsers.addAll(usersToBeAdded);
英文:

You are getting ConcurrentModificationException because you are trying to modify the list inside the for loop.
This can be solved in several ways:

  1. You can use CopyOnWriteArrayList as a type for mUsers list.

  2. Or you can just create new List to be used inside the loop

    for (User user1 : new ArrayList&lt;&gt;(mUsers)){...}

  3. Or you can solve it in more economical way by adding temporary list for new items

List&lt;User&gt; usersToBeAdded = new ArrayList&lt;User&gt;();
for (User user1 : mUsers){
if (!user.getUser_id().equals(user1.getUser_id())){
usersToBeAdded.add(user);
}}
mUsers.addAll(usersToBeAdded);

huangapple
  • 本文由 发表于 2020年10月14日 21:43:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/64354667.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定