1

I have a task to load some images from a website and load them into a gridview. But when I try to update the mangaGridArrayAdapter I get the error:

08-24 21:03:03.433  22791-22791/com.solomobile.englishmanga W/System.err﹕ java.util.ConcurrentModificationException
08-24 21:03:03.433  22791-22791/com.solomobile.englishmanga W/System.err﹕ at java.util.AbstractList$SubAbstractList.size(AbstractList.java:360)
08-24 21:03:03.434  22791-22791/com.solomobile.englishmanga W/System.err﹕ at java.util.AbstractList$SubAbstractList.addAll(AbstractList.java:280)
08-24 21:03:03.434  22791-22791/com.solomobile.englishmanga W/System.err﹕ at android.widget.ArrayAdapter.addAll(ArrayAdapter.java:195)
08-24 21:03:03.434  22791-22791/com.solomobile.englishmanga W/System.err﹕ at com.solomobile.englishmanga.task.PopularMangaTask.onPostExecute(PopularMangaTask.java:128)
08-24 21:03:03.434  22791-22791/com.solomobile.englishmanga W/System.err﹕ at com.solomobile.englishmanga.task.PopularMangaTask.onPostExecute(PopularMangaTask.java:19)

Following is the code for my Task:

package com.solomobile.englishmanga.task;

import android.app.Activity;
import android.content.Context;
import android.os.AsyncTask;
import android.widget.GridView;
import android.widget.AbsListView;
import com.solomobile.englishmanga.R;
import com.solomobile.englishmanga.adapter.MangaGridArrayAdapter;
import com.solomobile.englishmanga.controller.EnglishMangaController;
import com.solomobile.englishmanga.domain.Manga;
import com.solomobile.englishmanga.util.Util;

import java.util.List;

public class PopularMangaTask extends AsyncTask<Context, Void, Void> {

    private Activity activity = null;
    private MangaGridArrayAdapter mangaGridArrayAdapter = null;
    private List<Manga> mangas = null;
    String erro = null;
    private final int MAX_PER_PAGE = 6;
    private int currentPage = 0;
    private static Boolean loading = new Boolean(false);



    public Activity getActivity() {
        return activity;
    }

    public void setActivity(Activity activity) {
        this.activity = activity;
    }

    @Override
    protected synchronized Void doInBackground(Context... params) {
        this.activity = (Activity) params[0];
        if(mangas == null) {
            System.out.println("Getting Mangas first time");
            EnglishMangaController controller = EnglishMangaController.getInstance();
            mangas = controller.getPopularMangas();
            List<Manga> mangaList = mangas.subList(currentPage * MAX_PER_PAGE, (currentPage * MAX_PER_PAGE) + MAX_PER_PAGE);
            EnglishMangaController.getInstance().defineMangaCover(mangaList);
            mangaGridArrayAdapter = new MangaGridArrayAdapter(activity, mangaList);
        }else{
            System.out.println("Loading more covers");
            List<Manga> mangaList = mangas.subList(currentPage * MAX_PER_PAGE, (currentPage * MAX_PER_PAGE) + MAX_PER_PAGE);
            EnglishMangaController.getInstance().defineMangaCover(mangaList);
        }
        System.out.println("Previous Current Page: " + currentPage);
        currentPage++;
        System.out.println("After Current Page: " + currentPage);
        return null;
    }

    public int getCurrentPage() {
        return currentPage;
    }

    public void setCurrentPage(int currentPage) {
        this.currentPage = currentPage;
    }

    public List<Manga> getMangas() {
        return mangas;
    }

    public void setMangas(List<Manga> mangas) {
        this.mangas = mangas;
    }

    public MangaGridArrayAdapter getMangaGridArrayAdapter() {
        return mangaGridArrayAdapter;
    }

    public void setMangaGridArrayAdapter(MangaGridArrayAdapter mangaGridArrayAdapter) {
        this.mangaGridArrayAdapter = mangaGridArrayAdapter;
    }

    @Override
    protected synchronized void onPostExecute(Void result) {
        super.onPostExecute(result);
        try{
            GridView gridView = (GridView) activity.findViewById(R.id.gridviewPopular);
            if(gridView != null){
                if(currentPage == 1) {
                    gridView.setAdapter(mangaGridArrayAdapter);
                    gridView.setOnScrollListener(new AbsListView.OnScrollListener() {
                        @Override
                        public void onScrollStateChanged(AbsListView view, int scrollState) {

                        }

                        @Override
                        public synchronized void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                            int lastInScreen = firstVisibleItem + visibleItemCount;
                            int maxPages = (int)(mangas.size() / MAX_PER_PAGE);
                            System.out.println("Scrolling - CurrentPage: " + currentPage + " Max Pages: " + maxPages + " Loading: " + loading);
                            if (!loading && lastInScreen == totalItemCount && currentPage <= maxPages) {
                                loading = true;
                                System.out.println("Call new popular manga task: " + loading);
                                    PopularMangaTask popularMangaTask = new PopularMangaTask();
                                    popularMangaTask.setCurrentPage(currentPage);
                                    popularMangaTask.setMangas(mangas);
                                    popularMangaTask.setMangaGridArrayAdapter(mangaGridArrayAdapter);
                                    Util.startMyTask(popularMangaTask, activity);
                            }
                        }
                    });
                }else{
                    System.out.println("Adding More Mangas to the Popular list - Current Page: " + currentPage);
                    int maxSubList = (currentPage * MAX_PER_PAGE) + MAX_PER_PAGE;
                    if(maxSubList >= mangas.size()){
                        maxSubList = mangas.size()-1;
                    }
                    System.out.println("MaxSubList: " + maxSubList);
                    System.out.println("Mangas.size: " + mangas.size());
//                    mangaGridArrayAdapter = new MangaGridArrayAdapter(activity, mangas.subList(0, maxSubList));
//                    mangaGridArrayAdapter.clear();
//                    mangaGridArrayAdapter.getMangas().clear();
//                    List<Manga> subListManga = mangas.subList(currentPage * MAX_PER_PAGE,maxSubList);
                    List<Manga> subListManga = mangas.subList(8,maxSubList > mangas.size() ? mangas.size() : maxSubList);
                    System.out.println("subListManga.size: " + subListManga.size());
                    mangaGridArrayAdapter.addAll(subListManga);
//                    loading = false;
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }

    }
}

And here is the code for the Adapter:

package com.solomobile.englishmanga.adapter;

import java.util.List;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import com.solomobile.englishmanga.R;
import com.solomobile.englishmanga.controller.EnglishMangaController;
import com.solomobile.englishmanga.domain.Manga;
import com.squareup.picasso.Picasso;

public class MangaGridArrayAdapter extends ArrayAdapter<Manga>{
    private final Context context;
    private final List<Manga> mangas;

    public List<Manga> getMangas() {
        return mangas;
    }

    public MangaGridArrayAdapter(Context context, List<Manga> mangas) {
        super(context, R.layout.manga_grid_layout, mangas);
        this.context = context;
        this.mangas = mangas;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        final View rowView = inflater.inflate(R.layout.manga_grid_layout, parent, false);
        final Manga selectedManga = mangas.get(position);
        final ImageView imageView = (ImageView) rowView.findViewById(R.id.iconManga);
        System.out.println("Loading image: " + selectedManga.getCoverLink());

        Picasso.with(context).load(selectedManga.getCoverLink()).into(imageView);

        TextView textView = (TextView) rowView.findViewById(R.id.name);
        textView.setText(selectedManga.getName());
        return rowView;
    }
}

What am I doing to wrong in this case? I have quite the same code working for a ListView, but for this Gridview I'm getting this.

How can I do that without getting this error?

Igor
  • 1,397
  • 3
  • 24
  • 56
  • IMO, you can find helpful information with the answer at [ConcurrentModificationException: .add() vs .addAll()](http://stackoverflow.com/questions/26184532/concurrentmodificationexception-add-vs-addall) – BNK Aug 25 '15 at 04:30
  • can I see the code for `MangaGridArrayAdapter `? – Kise Aug 25 '15 at 04:57
  • specifically the `addAll` method. – Kise Aug 25 '15 at 04:57
  • tried to use the loop and add one by one, but worked just for the first item. after that I get the same error... I've updated the question with the code for the MangaGridArrayAdapter – Igor Aug 25 '15 at 06:25
  • @haint, any ideia? There is no implementation for this addAll method. It's from the adapter. – Igor Aug 25 '15 at 15:26
  • I guess you used the enhanced for loop right? – Kise Aug 25 '15 at 15:31

1 Answers1

2

Add this method to your MangaGridArrayAdapter

public void addAllManga(List<Manga> list) {
    for(int i = 0; i < list.size(); i++) {
        mangas.add(list.get(i));
    }
    notifyDataSetChanged();
}

In your Task

mangaGridArrayAdapter.addAllManga(subListManga);
Kise
  • 2,823
  • 1
  • 24
  • 43
  • Still getting the same error in the line (for(int i = 0; i < list.size(); i++)... Seems that there is some problem with the list and not with the gridview... – Igor Aug 25 '15 at 16:20
  • still got `ConcurrentModificationException` ? – Kise Aug 25 '15 at 16:21
  • 1
    Yes... I fixed it here... thanks to you I saw that the error was is the list... so instead of using subList... I used a loop and created a new list. With this new List I got no concurrent problem. – Igor Aug 25 '15 at 16:31
  • I had a very simmilar problem that was solved by replacing ```listA.addAll(listB.subList(0, listB.size))``` by a for loop adding item by item to ```listA```. – Igor Grecco Lacourt Jun 10 '20 at 15:17