BaseGameActivity.runOnUpdateThread() 和 Entity.registerUpdateHandler() 的区别

8
如果我使用runOnUpdateThread()执行Runnable,或者将更新处理程序注册到实体中并使用它来执行代码,这两种方式有什么区别吗? 我想使用Sprite.detachSelf()从场景中移除一个Sprite。在这种情况下,教程说必须在更新线程中使用BaseGameActivity.runOnUpdateThread()调用此方法。但是这样做的话,我必须将活动对象传递给每个想要使用runOnUpdateThread()的对象。嗯...我不喜欢这种方法。我的问题是,如果我在实体中创建一个RunnableHandler对象,并使用registerUpdateHandler()进行注册,然后向RunnableHandler添加新的Runnable,那么这种解决方案是否与runOnUpdateThread()功能相同? 这个Runnable是否在更新线程中执行?
/* MySprite is attached to a Scene object */
public class MySprite extends Sprite {
   private final RunnableHandler UPDATE_HANDLER = new RunnableHandler();

   public MySprite() {
       registerUpdateHandler(UPDATE_HANDLER);
   }

   /* called when the sprite has to be removed from scene */
   public void removeMyself() {
       Runnable r = new Runnable() {
           public void run() {
               detachSelf();
           }
       };
       UPDATE_HANDLER.postRunnable(r);
   }
}

我之所以询问这个问题,是因为标准解决方案一切正常。但是使用更新处理程序解决方案时,我遇到了以下异常:

致命异常:UpdateThread
java.lang.IndexOutOfBoundsException: Invalid index 19, size is 19
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
at java.util.ArrayList.get(ArrayList.java:308)
at org.andengine.entity.Entity.onManagedUpdate(Entity.java:1402)
at org.andengine.entity.scene.Scene.onManagedUpdate(Scene.java:284)
at org.andengine.entity.Entity.onUpdate(Entity.java:1167)
at org.andengine.engine.Engine.onUpdateScene(Engine.java:591)
at org.andengine.engine.Engine.onUpdate(Engine.java:586)
at org.andengine.engine.Engine.onTickUpdate(Engine.java:548)
at org.andengine.engine.Engine$UpdateThread.run(Engine.java:820)

当attach/detach函数不在Update线程中调用时,通常会发生这种情况。我的理解是否正确?提前感谢您的帮助。

为什么不在包含那些精灵的场景中创建分离逻辑呢?你的场景可以从一个包含 Activity 引用的 BaseScene 扩展,或者如果你不想使用 BaseScene 方法,也可以在该场景中创建一个 Activity 的 WeekReference。这些方法中的任何一个都能帮助你实现你的目标吗? - GuilhE
嗨GuilhE,我当然可以用其他方法解决问题。但我的问题完全不同。当我使用划分的代码时,我不明白为什么会出现上述异常。注册的更新处理程序代码是否按照我预期的那样在更新线程中调用?如果不是,为什么? - albundyszabolcs
1个回答

2
在查看Entity源代码时,有一个理论是:
  1. 显示的行选择了实体计数=19 (从日志中)
  2. 其中一个entity.get(i).onUpdate()调用removeMyself()
  3. detachSelf的可运行程序被排队。
  4. 在下一个entity.get(i).onUpdate()将导致通过onUpdate运行UpdateHandler(updatehandlers在onManagedUpdate中运行)
  5. detachSelf从父列表(调用者)中删除子项(其中条目计数仍为19,但mChildren/entities的长度现在为18)
只是从代码中推测出来的一个理论...我认为开始寻找答案的好方法是查看Entity中的循环,并查看在循环期间是否修改了'entities'。(注意: 'final entities'仅防止重新分配变量,而不修改列表)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接