Android ConcurrentOnDraw()

Android ConcurrentOnDraw(),android,concurrency,android-canvas,concurrentmodification,Android,Concurrency,Android Canvas,Concurrentmodification,我有一个android应用程序的问题 我有一个线程,它不断迭代列表或形状,更新它们的位置,有时从列表中删除项目。在线程的while循环结束时,它调用postInvalidate()来提示重新绘制 下面是对ArrayList进行修改的代码 Iterator<Shape> iterator = this.myList.iterator(); while (iterator.hasNext()) { Shape nextShape = iterator.next();

我有一个android应用程序的问题

我有一个线程,它不断迭代列表或形状,更新它们的位置,有时从列表中删除项目。在线程的while循环结束时,它调用postInvalidate()来提示重新绘制

下面是对ArrayList进行修改的代码

Iterator<Shape> iterator = this.myList.iterator();
while (iterator.hasNext()) {
     Shape nextShape = iterator.next();
     nextShape.move();
     if(condition) {
         iterator.remove()
     }
}
Iterator Iterator=this.myList.Iterator();
while(iterator.hasNext()){
Shape nextShape=iterator.next();
nextShape.move();
如果(条件){
iterator.remove()
}
}
onDraw方法使用for-each循环来绘制每个项目。我在onDraw方法中得到了并发修改,尽管只通过迭代器修改了列表。我尝试了CopyOnWriteArrayList和Collections.synchronized,结果相同


任何帮助都将不胜感激。

有几种方法可以解决这个问题。一种是在线程和onDraw中使用同步块,但这会阻止第二个线程与UI线程同时运行

我认为最好的方法是使用两个集合。您的代码应该如下所示

onDraw(){
    synchronized(myList){
        //Do your draw code.  Get the iterator inside this block
    }
}

threadFunction(){
    List threadList;
    while(1){
        //Update threadList, which holds all the objects
        synchronized(myList){
            myList = threadList.copy();  //Do a deep copy, don't just copy over the reference
        }
        postInvalidate();
    }
}
这将使draw函数在迭代结束时生成的列表副本上运行。如果您正在处理深度副本,则不会出现任何同步问题,因为线程不会更改相同的列表。同步块将阻止线程在绘图期间覆盖绘图函数的副本。唯一剩下的问题是,线程中列表的覆盖将挂起,直到绘制完成,但由于更新的频率高于此频率不会显示在屏幕上,我猜这是可以接受的