Мое приложение аварийно завершает работу с addAll (int Index, Collection c) в более старой версии Android (не потому, что подсписок) - PullRequest
0 голосов
/ 19 сентября 2018

Я пытаюсь добавить новые элементы в просмотр списка с помощью метода addAll, и я могу сделать это на последней версии Android, но когда я пытаюсь в более старых версиях, он вылетает.

Может кто-нибудь помочь мне понятьпочему и как это исправить.

Функция, где я получаю ошибку

public void appendMessages(List<Message> moreMessages){
        this.messages.addAll(0,moreMessages);
    }

Мне нужно добавить их в начало списка.

Ошибка

09-19 13:12:59.437 12909-12909/com.example.rjrod.legendchat E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.rjrod.legendchat, PID: 12909
    java.util.ConcurrentModificationException
        at java.util.AbstractList$SubAbstractList.size(AbstractList.java:360)
        at java.util.AbstractList$SubAbstractList.addAll(AbstractList.java:265)
        at com.example.rjrod.legendchat.adapter.MensagemAdapter.appendMessages(MensagemAdapter.java:136)
        at com.example.rjrod.legendchat.MainActivity$2.onScroll(MainActivity.java:169)
        at android.widget.AbsListView.invokeOnItemScrollListener(AbsListView.java:1461)
        at android.widget.AbsListView.trackMotionScroll(AbsListView.java:4987)
        at android.widget.AbsListView.scrollIfNeeded(AbsListView.java:3398)
        at android.widget.AbsListView.onTouchMove(AbsListView.java:3774)
        at android.widget.AbsListView.onTouchEvent(AbsListView.java:3612)
...

Где я это называю

listMensages.setOnScrollListener(new AbsListView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {

            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                Log.d(TAG, "onScroll: " + view.getFirstVisiblePosition() + " " + listMensages.getCount() +" " + (19*(k)-visibleItemCount) +" " + k+" " +numberLists);


                if(view.getFirstVisiblePosition() == 0 && listMensages.getCount()>=19*(k)-visibleItemCount && k<numberLists && k>=1 && k!=z){

                    Log.d(TAG, "ENTREI: " + z + " " + k);


                        adapter.appendMessages(messagesList.subList(messagesList.size()-20*(k+1),messagesList.size()-21-((k-1)*20)));
                        adapter.notifyDataSetChanged();
                        listMensages.smoothScrollToPosition(19);
                        z=k;
                    handler.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            k++;
                        }
                    }, 100);


                        //loaded=true;
                    }
                    if(view.getFirstVisiblePosition() == 0 && listMensages.getCount()>=19-visibleItemCount && k==numberLists){
                        Log.d(TAG, "ENTREI 2: ");

                        adapter.appendMessages(messagesList.subList(messagesList.indexOf(messagesList.get(0)),messagesList.size()-21-((k-1)*20)));
                        adapter.notifyDataSetChanged();
                        listMensages.smoothScrollToPosition(19);
                        k++;
                    }
                    if(k==0){
                        k=1;
                    }



            }
        });

Если что-то еще нужно, просто скажите мне, и я добавлю его,(Мне нужно, чтобы это работало как минимум с SDK 21)

Спасибо

Адаптер

public class MensagemAdapter extends ArrayAdapter<Message> {

    private Context context;
    private List<Message> messages;
    private List<Users> users;
    private static final String TAG = "MensagemAdapter";


    public MensagemAdapter(@NonNull Context context, @NonNull List<Message> objects, @NonNull List<Users> users) {
        super(context, 0, objects);
        this.context=context;
        this.messages = objects;
        this.users = users;
    }

    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        View view = null;
        //Log.d(TAG, "getView: " + position);


            if (messages != null) {

                LayoutInflater inflater = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
                Message message = messages.get(position);
                //Log.d("Num", "getView: " + message.getUserId() + " " + message.getId());
                if (message.getUserId() == 1) {
                    assert inflater != null;
                    view = inflater.inflate(R.layout.right_no_attach, parent, false);
                    TextView textoMensagem = view.findViewById(R.id.tv_mensage);
                    textoMensagem.setText(message.getContent());
                    if (message.getAttachments() != null) {

                        for (int i = 0; i < message.getAttachments().size(); i++) {
                            //view = inflater.inflate(R.layout.right_attach,parent,false);
                            if (i == 0) {
                                ImageView attach = view.findViewById(R.id.imageView1);
                                attach.setVisibility(View.VISIBLE);
                                Picasso.get().load(message.getAttachments().get(i).getThumbnailUrl()).into(attach);

                            } else if (i == 1) {
                                ImageView attach = view.findViewById(R.id.imageView2);
                                attach.setVisibility(View.VISIBLE);
                                Picasso.get().load(message.getAttachments().get(i).getThumbnailUrl()).into(attach);
                            } else if (i == 2) {
                                ImageView attach = view.findViewById(R.id.imageView3);
                                attach.setVisibility(View.VISIBLE);
                                Picasso.get().load(message.getAttachments().get(i).getThumbnailUrl()).into(attach);
                            } else {
                                ImageView attach = view.findViewById(R.id.imageView3);
                                attach.setVisibility(View.VISIBLE);
                                Picasso.get().load(message.getAttachments().get(i).getThumbnailUrl()).into(attach);
                            }

                        }
                    }

                } else {
                    assert inflater != null;
                    view = inflater.inflate(R.layout.left_no_attach, parent, false);
                    TextView nomeMensagem = view.findViewById(R.id.nomeId);
                    nomeMensagem.setText(users.get(message.getUserId() - 1).getName());
                    ImageView avatar = view.findViewById(R.id.avatarIm);
                    Picasso.get().load(users.get(message.getUserId() - 1).getAvatarId()).transform(new CircleTransform()).into(avatar);
                    TextView textoMensagem = view.findViewById(R.id.tv_mensage);
                    textoMensagem.setText(message.getContent());
                    if (message.getAttachments() != null) {

                        for (int i = 0; i < message.getAttachments().size(); i++) {
                            //view = inflater.inflate(R.layout.right_attach,parent,false);
                            if (i == 0) {
                                ImageView attach = view.findViewById(R.id.imageViewA);
                                attach.setVisibility(View.VISIBLE);
                                Picasso.get().load(message.getAttachments().get(i).getThumbnailUrl()).into(attach);

                            } else if (i == 1) {
                                ImageView attach = view.findViewById(R.id.imageViewB);
                                attach.setVisibility(View.VISIBLE);
                                Picasso.get().load(message.getAttachments().get(i).getThumbnailUrl()).into(attach);
                            } else if (i == 2) {
                                ImageView attach = view.findViewById(R.id.imageViewC);
                                attach.setVisibility(View.VISIBLE);
                                Picasso.get().load(message.getAttachments().get(i).getThumbnailUrl()).into(attach);
                            } else {
                                ImageView attach = view.findViewById(R.id.imageViewD);
                                attach.setVisibility(View.VISIBLE);
                                Picasso.get().load(message.getAttachments().get(i).getThumbnailUrl()).into(attach);
                            }

                        }
                    }

                }


                if (message.getAttachments() == null) {
                    TextView textoMensagem = view.findViewById(R.id.tv_mensage);

                    textoMensagem.setText(message.getContent());
                }



        }
        return view;
        }


    public void appendMessages(List<Message> moreMessages){
        Log.d(TAG, "appendMessages: " + this.messages + " " + moreMessages);
        this.messages.addAll(moreMessages);

    }


    }

Ответы [ 2 ]

0 голосов
/ 19 сентября 2018

Проблема в том, что вы пытаетесь изменить список, когда список уже изменяется где-то еще, поэтому вы получаете ConcurrentModificationException.

Попробуйте ограничить изменения списка одним потоком, например, пользовательским интерфейсом.,Из вашего опубликованного кода я предполагаю, что параллелизм происходит в методе onScoll, который вызывается многократно, пока изменение списка еще не закончено.Вот простой пример перемещения вашей функции adapter.appendMessages() в очередь потоков пользовательского интерфейса:

runOnUiThread(new Runnable() {
    @Override
    public void run() {
        adapter.appendMessages(messagesList.subList(messagesList.indexOf(messagesList.get(0)),messagesList.size()-21-((k-1)*20)));
        adapter.notifyDataSetChanged();
        listMensages.smoothScrollToPosition(19);
        ...
    }
});
0 голосов
/ 19 сентября 2018

Чтобы решить проблему с туром, просто измените конструктор адаптера.

public MensagemAdapter(@NonNull Context context, @NonNull List<Message> objects, @NonNull List<Users> users) {
        super(context, 0,  new ArrayList<>(objects));
        this.context=context;
        this.messages =   new ArrayList<>(objects);
        this.users = users;
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...