Question

I have simple TimerHandler that change replace some Sprites (Place extends Sprite).

My code

ArrayList<Place> itemsToVisit = new ArrayList<Place>();

public void Somemethod(){}
    TimerHandler effectTimer = new TimerHandler(3f, true, new ITimerCallback() {

        @Override
        public void onTimePassed(final TimerHandler pTimerHandler) {

            delegate.RequestEntity().unregisterUpdateHandler(pTimerHandler);
            updateOnEffect = new Handler(Looper.getMainLooper());
            updateOnEffect.post(new Runnable() {

                @Override
                public void run() {

                    for (Place l : itemsToVisit) {

                            if (youAreThePlace(l)) {

                                int indexForChange = itemsToVisit.indexOf(l);
                                swapPlace(l, indexForChange);
                            }

                        }
                    }
                }
            });
        }
    });
    delegate.RequestEntity().registerUpdateHandler(effectTimer);
}
public void swapPlace(Place l, int indexForChange) {
    ((Scene) delegate.RequestEntity().getParent()).unregisterTouchArea(l);
    l.detachSelf();

    l = createNewPlace(l, false);

    itemsToVisit.set(indexForChange, l);
    delegate.RequestEntity().attachChild(l);
    ((Scene) delegate.RequestEntity().getParent()).registerTouchArea(l);
}

Sometimes it work 4 times before crash, sometimes after first run.

Error

java.lang.IndexOutOfBoundsException: Invalid index 40, size is 40
            at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251)
            at java.util.ArrayList.get(ArrayList.java:304)
            at org.andengine.entity.Entity.onManagedDraw(Entity.java:1635)
            at org.andengine.entity.Entity.onDraw(Entity.java:1398)
            at org.andengine.entity.Entity.onManagedDraw(Entity.java:1635)
            at org.andengine.entity.scene.Scene.onManagedDraw(Scene.java:259)
            at org.andengine.entity.Entity.onDraw(Entity.java:1398)
            at org.andengine.engine.Engine.onDrawScene(Engine.java:647)
            at org.andengine.engine.Engine.onDrawFrame(Engine.java:637)
            at org.andengine.opengl.view.EngineRenderer.onDrawFrame(EngineRenderer.java:105)
            at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1516)
            at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240)

I don't know what I'm doing wrong? When I replace handler with activity.runOnUpdateThread((new Runnable() { then in first run I got error about Looper.prepare()

 java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
            at android.os.Handler.<init>(Handler.java:121)
            at android.widget.Toast$TN.<init>(Toast.java:322)
            at android.widget.Toast.<init>(Toast.java:91)
            at android.widget.Toast.makeText(Toast.java:238)
            at pl.newaxis.szyfraki.Controller.LetterManager$1$1$1.run(PlaceManager.java:51)
            at org.andengine.engine.handler.runnable.RunnableHandler.onUpdate(RunnableHandler.java:42)
            at org.andengine.engine.Engine.onUpdateUpdateHandlers(Engine.java:617)
            at org.andengine.engine.Engine.onUpdate(Engine.java:605)
            at org.andengine.engine.Engine.onTickUpdate(Engine.java:568)
            at org.andengine.engine.Engine$UpdateThread.run(Engine.java:858)

Could You suggest me what I'm doing wrong?


SOLVE

I had to put activity.runOnUpdateThread only item to detach. So finaly swapPlace look like this

public void swapPlace(Place l, int indexForChange) {
    ((Scene) delegate.RequestEntity().getParent()).unregisterTouchArea(l);
    activity.runOnUpdateThread(new Runnable() {
            @Override
            public void run() {
                finalL.detachSelf();
            }
        });

    l = createNewPlace(l, false);

    itemsToVisit.set(indexForChange, l);
    delegate.RequestEntity().attachChild(l);
    ((Scene) delegate.RequestEntity().getParent()).registerTouchArea(l);
}
Was it helpful?

Solution

this error is almost always because the Sprite is being removed outside of the updateThread. WHen you remove it like that, the indexes don't get updated properly and the next time the updateThread tries to refresh things - something is missing, thus the indexOutofBounds.

See this question/answer java.lang.IndexOutOfBoundsException: Invalid index 13, size is 13 for some hints on how to make sure you remove the Sprite on the updateThread.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top