Ali*_*lin 23 animation android concurrentmodification
我在Android中同步代码的概念中遗漏了一些东西.
脚本
屏幕上总是绘制3个项目.每个图像都存储在ArrayList(lstGraphics)中.为此,我使用SurfaceView.一旦用户点击图像,图像就会被移除市场并且将添加新的市场.
代码示例:
AnimationHideThread
...
@Override
public void run() {
Canvas c;
while (run) {
c = null;
try {
c = panel.getHolder().lockCanvas(null);
synchronized (panel.getHolder()) {
panel.updatePhysics();
panel.manageAnimations();
panel.onDraw(c);
}
} finally {
if (c != null) {
panel.getHolder().unlockCanvasAndPost(c);
}
}
}
}
...
Run Code Online (Sandbox Code Playgroud)
所以你可以先看看updatePhysics().这意味着我计算每个图像移动到的方向.在这里,我还将删除列表中的点击图像.之后,我检查是否需要在manageAnimations()的列表中添加一个新项目,然后最后一步绘制整个事物.
public class Panel extends SurfaceView implements SurfaceHolder.Callback {
....
public void manageAnimations()
{
synchronized (this.getHolder()) {
...
while (lstGraphics.size()<3) {
lstGraphics.add(createRandomGraphic());
}
}
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
synchronized (getHolder()) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
//... check if a image has been clicked and then set its property
graphic.setTouched(true);
}
}
return true;
}
}
public void updatePhysics() {
synchronized (getHolder()) {
for (Graphic graphic : lstGraphics) {
//.... Do some checks
if (graphic.isTouched())
{
lstGraphics.remove(graphic);
}
}
}
}
@Override
public void onDraw(Canvas canvas) {
/// draw the backgrounds and each element from lstGraphics
}
public class Graphic {
private Bitmap bitmap;
private boolean touched;
private Coordinates initialCoordinates;
....
}
Run Code Online (Sandbox Code Playgroud)
我得到的错误是:
> 03-01 10:01:53.365: ERROR/AndroidRuntime(454): Uncaught handler: thread Thread-12 exiting due to uncaught exception
> 03-01 10:01:53.365: ERROR/AndroidRuntime(454): java.util.ConcurrentModificationException
> 03-01 10:01:53.365: ERROR/AndroidRuntime(454): at java.util.AbstractList$SimpleListIterator.next(AbstractList.java:66)
> 03-01 10:01:53.365: ERROR/AndroidRuntime(454): at com.test.customcontrols.Panel.updatePhysics(Panel.java:290)
> 03-01 10:01:53.365: ERROR/AndroidRuntime(454): at com.test.customcontrols.AnimationHideThread.run(AnimationHideThread.java:41)
Run Code Online (Sandbox Code Playgroud)
任何帮助是极大的赞赏.谢谢.
mon*_*nty 78
您的问题出在物理方法中,您可以在其中添加图形和列表
public void updatePhysics() {
synchronized (getHolder()) {
for (Graphic graphic : lstGraphics) {
//.... Do some checks
if (graphic.isTouched()) {
lstGraphics.remove(graphic); //your problem
}
}
}
Run Code Online (Sandbox Code Playgroud)
的组合for(Graphic graphic : lstGraphics),并lst.Graphics.remove(graphic);导致ConcurrentModificationException的,因为你是运行在你的清单,同时试图修改它.
到目前为止我知道两个解决方案
如果有可用的话,请使用Iterator(到目前为止从未为Android编码).
while (iter.hasNext) {
if (physicsCondition) iter.remove();
}
Run Code Online (Sandbox Code Playgroud)使用第二个列表来存储要删除的元素,然后删除它们
List<GraphicsItem> toRemove = new ....
for (Graphic graphic : lstGraphics) {
if (physicsCondition) {
toRemove.add(graphic);
}
}
lstGraphics.removeAll(toRemove);
Run Code Online (Sandbox Code Playgroud)正如@idefix所说,您可以在单线程上下文中轻松获取ConcurrentModificationException,如下所示:
public static void main(String[] args) {
List<String> list = new ArrayList<String>(Arrays.asList("AAA", "BBB"));
for (String s : list) {
if ("BBB".equals(s)) {
list.remove(s);
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
29892 次 |
| 最近记录: |