为什么我在Android Gridview上得到java.util.ConcurrentModificationException?

时间:2015-08-25 04:08:55

标签: android gridview concurrency

我有一项任务是从网站加载一些图像并将它们加载到gridview中。 但是当我尝试更新mangaGridArrayAdapter时,我得到错误:

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)

以下是我的任务的代码:

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();
        }

    }
}

以下是适配器的代码:

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;
    }
}

在这种情况下我做错了什么?我有一个相同的代码用于ListView,但对于这个Gridview,我得到了这个。

如何在不收到此错误的情况下执行此操作?

1 个答案:

答案 0 :(得分:0)

将此方法添加到MangaGridArrayAdapter

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

Task

mangaGridArrayAdapter.addAllManga(subListManga);