Редактирование ArrayList в onTouchEvent - PullRequest
3 голосов
/ 07 декабря 2011

Я пишу приложение для Android со следующей базовой структурой:


MyActivity.java - устанавливает вид как MyView.

MyThread.java - содержит surfaceHolder, вызывает update() и render() функции в MyView.java

MyView.java - рисует на холст, используя функцию render(), обновляет класс MyPuzzle, обрабатывает события касания.

MyPuzzle.java - содержит ArrayList/Vector элементов.


Мой вопрос:

В классе MyView, в функции render() я перебираю содержимоеArrayList/Vector проведите в классе MyPuzzle и нарисуйте их на холсте.Однако я иногда получал indexOutOfBounds ошибок (возможно, один раз каждые 10 раз), несмотря на цикл из i=0; i<arraylist.size()...

В том же классе MyView, в функции onTouchEvent у меня есть код, который добавляет/ удаляет элементы из ArrayList/Vector, который рисуется.

Являются ли ошибки моего индекса вне границ, вероятно, вызванные обработкой onTouchEvent s в то время, когда функция render() проходит циклArrayList/Vector и рисование элементов на экране?

Я пытался внедрить систему, в которой onTouchEvent не обрабатывались сразу, а добавлялись в очередь ArrayList и обрабатывались только до render() называется.Похоже, это решило проблему с проведенным ограниченным тестированием.Звучит ли это правильно?Это сводит меня с ума.

Спасибо за вашу помощь заранее, извиняюсь за плохо написанный вопрос, я могу добавить любую дополнительную информацию, которая вам может понадобиться.

1 Ответ

2 голосов
/ 07 декабря 2011

IndexOutOfBounds, вероятно, является прямым результатом ситуации, когда итерирующий поток изначально увидит Список в размере N и начнет итерацию с 0 до N. Поток-2 входит и удаляется из списка, делая его эффективно N-1так что если Thread-1 попытается прочитать в list.get (N), вы получите свое исключение.

Если глубина списка не очень велика, и вы не удаляете и не добавляете весь потерянный своп Списокреализация с CopyOnWriteArrayList.В противном случае вам потребуется synchronize для всех действий в списке, включая итерацию, например

public void render(){
  synchronized(list){
    for(int i =0; i <list.size();i++){
      //....
    }
  }
}
public void update(Object element){
 synchronized(list){
  list.remove(element);  
 }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...