我的android应用程序出了点问题。
我有一个线程,它不断迭代列表或形状,更新它们的位置,有时还会从列表中删除一项。在线程的while循环结束时,它调用postInvalidate()来提示重新绘制。
以下是对ArrayList进行修改的代码。
Iterator<Shape> iterator = this.myList.iterator();
while (iterator.hasNext()) {
Shape nextShape = iterator.next();
nextShape.move();
if(condition) {
iterator.remove()
}
}onDraw方法使用for each循环来绘制其中的每一项。尽管我只通过迭代器修改了列表,但我在onDraw方法中得到了并发修改。我试过CopyOnWriteArrayList和Collections.synchronized,结果是一样的。
任何帮助都将不胜感激。
发布于 2012-11-15 12:32:23
有几种方法可以解决这个问题。一种方法是在线程和onDraw中使用synchronized块,但这会阻止第二个线程与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();
}
}这将使您的绘图函数在迭代结束时创建的列表副本上进行操作。如果你正在处理一个深度拷贝,你不会遇到任何同步问题,因为线程不会改变相同的列表。同步块将停止线程在绘制期间覆盖绘制函数的副本。唯一剩下的问题是,线程中列表的覆盖将挂起,直到绘制完成,但由于更新它的频率更高,无论如何都不会在屏幕上显示,我猜这是可以接受的。
https://stackoverflow.com/questions/13391077
复制相似问题