2015-06-22 10 views
8

Czy jest jakaś różnica, jeśli wykonuję Runnable z runOnUpdateThread() lub rejestruję program obsługi aktualizacji w Entity i wykonuję kod z tym?BaseGameActivity.runOnUpdateThread() vs. Entity.registerUpdateHandler()

Chciałbym usunąć Sprite ze sceny z Sprite.detachSelf(). W tym przypadku samouczek mówi, że ta metoda musi zostać wywołana w wątku aktualizacji pod numerem BaseGameActivity.runOnUpdateThread(). Ale dzięki temu rozwiązaniu muszę przekazać obiekt aktywności do każdego obiektu, który chce korzystać z runOnUpdateThread(). Cóż ... Nie podoba mi się to.

Moje pytanie brzmi, czy mogę utworzyć RunnableHandler obiektu w jednostce i zarejestrować go z registerUpdateHandler() i nowa Runnable jest dodawany do RunnableHandler, jest to rozwiązanie identyczne z funkcjonalnością runOnUpdateThread(). Czy to Runnable zostało wykonane w aktualizacji wątku?

/* 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); 
    } 
} 

Pytam o to, ponieważ przy standardowym rozwiązaniu wszystko działa poprawnie. Ale z roztworem zmiana procedury obsługi mam ten wyjątek:

krytyczny wyjątek: UpdateThread java.lang.IndexOutOfBoundsException: nieprawidłowy wskaźnik 19, rozmiar to 19 na java.util.ArrayList.throwIndexOutOfBoundsException (ArrayList.java:255) na java.util.ArrayList.get (ArrayList.java:308) at org.andengine.entity.Entity.onManagedUpdate (Entity.java:1402) at org.andengine.entity.scene.Scene.onManagedUpdate (Scena .java: 284) w org.andengine.entity.Entity.onUpdate (Entity.java:1167) at org.andengine.engine.Engine.onUpdateScene (Engine.java:591) at org.andengine.engine.Engin e.onUpdate (Engine.java:586) at org.andengine.engine.Engine.onTickUpdate (Engine.java:548) at org.andengine.engine.Engine $ UpdateThread.run (Engine.java:820)

Zazwyczaj przychodzi, gdy funkcje dołączania/odłączania nazywają się , a nie w wątku aktualizacji. Czy mam rację? Z góry dziękuję za pomoc.

+0

Dlaczego nie stworzysz logiki odłączania wewnątrz sceny, która będzie zawierała te duszki? Twoja scena może rozciągać się od BaseScene, która zawiera odnośnik do działania lub jeśli nie chcesz tego podejścia BaseScene, możesz także utworzyć WeekReference swojej aktywności w tej scenie. Czy któreś z tych podejść pomoże ci osiągnąć twoje cele? – GuilhE

+0

Witam GuilhE, oczywiście udało mi się rozwiązać problem w inny sposób. Ale moje pytanie było zupełnie inne. Nie rozumiem, dlaczego mam powyższy wyjątek, gdy użyłem wyszczególnionego kodu. Czy zarejestrowany kod obsługi aktualizacji jest rzeczywiście wywoływany w wątku aktualizacji zgodnie z oczekiwaniami, czy nie? Jeśli nie, dlaczego nie? – albundyszabolcs

Odpowiedz

2

Patrząc na kod źródłowy w Entity teoria, co się dzieje:

  1. Linia pokazano, podnosi liczbę jednostki = 19 (z dziennika)
  2. jednego z (i na entity.get) .onUpdate() wywołania removeMyself()
  3. Uruchomienie dla detachSelf jest kolejkowane.
  4. Na następnej entity.get (i) .onUpdate() spowoduje w UpdateHandler być uruchamiany poprzez onUpdate (updatehandlers są prowadzone w onManagedUpdate)
  5. detachSelf usuwa dziecko z listy nadrzędnej (rozmówcy) (gdzie wpis liczy się nadal 19 ale długość mChildren/podmiotów wynosi teraz 18)

Tylko teoria z patrzenia na kod ... Myślę, że dobrym punktem wyjścia do uzyskania odpowiedzi jest spojrzenie na pętlę w Entity i zobacz, czy "jednostki" są modyfikowane podczas pętli.(Uwaga: "ostateczne elementy" po prostu uniemożliwiają zmianę przypisania, nie modyfikując listy)