Параллельная модификация при запросе размера списка

Я пытаюсь получить список его размера, но при этом я получаю исключение ConcurrentModificationException для метода size(). Это странно, потому что я не пытаюсь изменить список, перебирая его. Вот часть моего кода, который мог вызвать это, но я не вижу в этом проблемы.

Основной метод:

private void setupCharacterGrid() {

    currentCharacters.add(0, new Character("add", "add"));
    if (currentCharacters.size() < 9) {
        sub(0, currentCharacters.size(), currentCharacters.size());
    } else {
        sub(0, 9, 9);
    }

    fillGrids();

    charPager.setAdapter(new CustomPagerAdapter(characterGrids));
    charPager.setCurrentItem(0);

}

Обратите внимание, что подметод (метод, в котором заполняется список) состоит в том, что DivisionCharList имеет тип: List>, где Character — это настраиваемый POJO.

private void sub(int start, int end, int n) {
    int size = currentCharacters.size();
    if (start > size) {
        return;
    } else if (start == size) {
        // new list(currentcharacters.get(start))
        // check if it fits on the previous grid
        List<Character> lastGrid = dividedCharList.get(dividedCharList
                .size() - 1);
        if (lastGrid.size() < 9) {
            lastGrid.add(currentCharacters.get(start - 1));
        } else {
            List<Character> finalCharList = new ArrayList<Character>();
            finalCharList.add(currentCharacters.get(start - 1));
            dividedCharList.add(finalCharList);
        }
        return;
    } else {
        if (size < start + n) {
            sub(start, end, n--);
        } else {
            // new list(currentcharacters.sublist(start, end);
            // end = end + n;
            // start = end + 1
            dividedCharList.add(currentCharacters.subList(start, end));
            start = end + 1;
            end = end + n;
            sub(start, end, n);
        }
    }
}

Метод, при котором возникает исключение при попытке получить размер:

private synchronized void fillGrids() {
    for (int i = 0; i < dividedCharList.size(); i++) {
        GridView gridView = new GridView(this);
        gridView.setNumColumns(3);
        CharacterGridAdapter aa = new CharacterGridAdapter(this,
                R.layout.charactergrid_cell, dividedCharList.get(i));
        gridView.setAdapter(aa);
        characterGrids.add(gridView);
    }
}

Обратите внимание, что это исключение также возникает, когда я пытаюсь пройтись по списку и попытаться получить значение и отобразить его в журнале

Изменить

Я только что заметил, что исключение возникает при вызове gridView.setAdapter(), метод getCount ArrayAdapter выдает ConcurrentModificationException

Изменить2

Вот трассировка стека, может поможет:

01-24 13:03:44.942: E/AndroidRuntime(15336): FATAL EXCEPTION: main
01-24 13:03:44.942: E/AndroidRuntime(15336): java.util.ConcurrentModificationException
01-24 13:03:44.942: E/AndroidRuntime(15336): at                 java.util.AbstractList$SubAbstractList.size(AbstractList.java:360)
 01-24 13:03:44.942: E/AndroidRuntime(15336):   at    android.widget.ArrayAdapter.getCount(ArrayAdapter.java:330)
 01-24 13:03:44.942: E/AndroidRuntime(15336):   at android.widget.GridView.setAdapter(GridView.java:182)
 01-24 13:03:44.942: E/AndroidRuntime(15336):   at xx.ProfileActivity.fillGrids(ProfileActivity.java:111)
 01-24 13:03:44.942: E/AndroidRuntime(15336): 
 xx.ProfileActivity.setupCharacterGrid(ProfileActivity.java:96)
 01-24 13:03:44.942: E/AndroidRuntime(15336):   at xx.ProfileActivity.access$6(ProfileActivity.java:87)

По запросу код адаптера

public class CharacterGridAdapter extends ArrayAdapter<Character> {

private Context context;
private List<Character> objects;
private int resource;

public CharacterGridAdapter(Context context, int resource, List<Character> listChar) {
    super(context, resource);
    this.context = context;
    this.objects = listChar;
    this.resource = resource;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View rowView = convertView;
    if (rowView == null) {
        LayoutInflater inflater = ((Activity) context).getLayoutInflater();
        rowView = inflater.inflate(R.layout.charactergrid_cell, null);
    } else {
    }
    return rowView;
}

}

Любой, кто мог бы помочь мне с этим?


person Tim Kranen    schedule 24.01.2014    source источник
comment
Каков фактический тип разделенногоCharList ?? это ArrayList ?? какую реализацию списка вы используете?   -  person Karthik Kalyanasundaram    schedule 24.01.2014
comment
Раньше это был ArrayList, но я изменил его на CopyOnWriteList, но это не решило проблему.   -  person Tim Kranen    schedule 24.01.2014


Ответы (1)


Удалите «синхронизированный» и вместо List используйте CopyOnWriteArrayList. Дополнительную информацию можно найти здесь CopyOnWriteArrayList

person YuDroid    schedule 24.01.2014
comment
Я изменил тип DivisionCharList на CopyOnWriteArrayList, но это не решило проблему. Я также удалил синхронизированный. - person Tim Kranen; 24.01.2014
comment
Вместо того, чтобы использовать DivisionCharList непосредственно в методе fillGrids(), создайте его локальную копию, а затем используйте ее для установки адаптера. Попробуй это.. - person YuDroid; 24.01.2014
comment
Является ли CharacterGridAdapter вашим пользовательским классом адаптера? Можете ли вы опубликовать код для него? - person YuDroid; 24.01.2014
comment
Приближается, но на самом деле ничего особенного. Стандартный адаптер, который даже не изменяет представления. - person Tim Kranen; 24.01.2014
comment
Вы не изменили List‹Character› listChar this на CopyOnWriteArrayList в конструкторе, а также частные объекты List‹Character›; это для CopyOnWriteArrayList. Теперь это должно быть одинаковым для всех экземпляров, когда бы оно ни использовалось. - person YuDroid; 24.01.2014
comment
Но у Android ArrayAdapter нет конструктора, который позволяет использовать CopyOnWriteArrayList. Это позволяет только массивы или списки. - person Tim Kranen; 24.01.2014
comment
Чувак, я говорю об этом: CharacterGridAdapter aa = new CharacterGridAdapter(this, R.layout.charactergrid_cell, DivisionCharList.get(i)); Если вы используете вышеуказанный конструктор, то откуда появится ArrayAdapter? - person YuDroid; 24.01.2014
comment
CharacterGridAdapter расширяется от ArrayAdapter‹Character› - person Tim Kranen; 25.01.2014