2

ich meinen Code wie folgt organisiert:Child Aktivität Faden bewirkt, dass die App auf Unterdrückung eingefroren werden

MainMenu (eine Aktivität) beginnt eine Absicht auf Game (eine andere Aktivität). Game setzt GamePanel (ein Flächenhalter), der GameThread startet (ein Thread).

MainMenu.java:

public void buttonPlay(View view) { 
    Intent intent = new Intent(this, Game.class); 
    startActivity(intent); 
} 

Game.java:

protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    requestWindowFeature(Window.FEATURE_NO_TITLE); 
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN); 
    setContentView(new GamePanel(this)); 
} 

GamePanel.java:

@Override 
public void surfaceCreated(SurfaceHolder surfaceHolder) { 
    gameThread = new GameThread(surfaceHolder, this); 
    gameThread.setRunning(true); 
    gameThread.start(); 
} 
@Override 
public void surfaceDestroyed(SurfaceHolder surfaceHolder) { 
    gameThread.setRunning(false); 
    try { 
     gameThread.join(); 
     gameThread = null; 
     } catch (InterruptedException e) { e.printStackTrace(); } 
} 

GameThread.java

@Override 
public void run() { 
    while (running) { 
     frameDelay.setStart(); 
     canvas = null; 
     try { 
      canvas = this.surfaceHolder.lockCanvas(); 
      synchronized (surfaceHolder) { 
       this.gamePanel.update(); 
       this.gamePanel.draw(canvas); 
      } 
     } catch (Exception e) { e.printStackTrace(); } 
     finally { 
      if (canvas != null) { 
       try { 
        surfaceHolder.unlockCanvasAndPost(canvas); 
       } catch (Exception e) {e.printStackTrace();} 
      } 
     } 
     try { 
      sleep(frameDelay.setDelay()); 
     } catch (Exception e) { e.printStackTrace(); } 
     frameDelay.displayFPS(); 
    } 
    try { 
     sleep(1000000); 
    } catch (Exception e) { e.printStackTrace(); } 
} 

Das Problem tritt auf, wenn ich wieder aus der Game Aktivität gehen. Die Anwendung zeigt die Aktivität MainMenu an, antwortet jedoch nicht mehr und das System fordert sie bald auf. Außerdem laufen die Aktivitäten und der Thread gut.

Ich weiß nicht, ob es ein Aktivitätslebenszyklus oder ein Thread-Problem ist. Wenn ich GameThread überhaupt nicht starte, läuft die Anwendung gut. Aber GamePanelSurfaceDestroyed heißt so, ich nehme an, der Thread wird ordnungsgemäß gestoppt.

Ich versuchte zu rufen:

  • GameonDestroy fangen die Zurück-Taste.
  • Gamebeenden fangen die Zurück-Taste.
  • GameonDestroy bis onPause.
  • GameEnde bis onPause.
  • Interrupt auf GameThread.

Keine der oben genannten lösen etwas (und einige Ursachen Abstürze).

Dieser Fehler tritt recht, wenn ich die Anwendung öffnen und wenn es getötet wird:

E/WindowState(3143): Error happens during resized 
E/WindowState(3143): android.os.DeadObjectException 
E/WindowState(3143): at android.os.BinderProxy.transactNative(NativeMethod) 
E/WindowState(3143): at android.os.BinderProxy.transact(Binder.java:496) 
E/WindowState(3143): at android.view.IWindow$Stub$Proxy.resized(IWindow.java:333) 
E/WindowState(3143): at com.android.server.wm.WindowState.reportResized(WindowState.java:1420) 
E/WindowState(3143): at com.android.server.wm.WindowManagerService.performLayoutAndPlaceSurfacesLockedInner(WindowManagerService.java:10129) 
E/WindowState(3143): at com.android.server.wm.WindowManagerService.performLayoutAndPlaceSurfacesLockedLoop(WindowManagerService.java:8887) 
E/WindowState(3143): at com.android.server.wm.WindowManagerService.performLayoutAndPlaceSurfacesLocked(WindowManagerService.java:8829) 
E/WindowState(3143): at com.android.server.wm.WindowManagerService.access$400(WindowManagerService.java:164) 
E/WindowState(3143): at com.android.server.wm.WindowManagerService$H.handleMessage(WindowManagerService.java:7782) 
E/WindowState(3143): at android.os.Handler.dispatchMessage(Handler.java:102) 
E/WindowState(3143): at android.os.Looper.loop(Looper.java:135) 
E/WindowState(3143): at android.os.HandlerThread.run(HandlerThread.java:61) 
E/WindowState(3143): at com.android.server.ServiceThread.run(ServiceThread.java:46) 

Und wenn die App nicht reagiert:

E/ActivityManager(3143): ANR in com.game.app (com.game.app/.MainMenu) 
E/ActivityManager(3143): PID: 27828 
E/ActivityManager(3143): Reason: Input dispatching timed out (Waiting to send non-key event because the touched window has not finished processing certain input events that were delivered to it over 500.0ms ago. Wait queue length: 5. Wait queue head age: 5534.6ms.) 

EDIT LÖSUNG:

Ich habe endlich das Problem gefunden! Es kam aus dem letzten Schlaf in meinem Lauf Methode in GameThread, entfernt es löst das Problem (und wird nicht verpasst werden, da es keinen Zweck hat). Wenn jemand erklären kann, wie diese Millisekunde die App komplett einfrieren lässt, fühlen Sie sich frei!

+0

logcat anzeigen? – uguboz

+0

Ich habe das Logcat hinzugefügt. Danke, dass Sie sich mein Thema angesehen haben! – Bipboopbug

+0

Sind Sie sicher, dass Sie alles protokolliert haben? Ich denke, da sollte mehr sein. – ozo

Antwort

0

DeadObjectException tritt auf, wenn Sie ein totes Objekt aufrufen. Ich vermute, dass dein Thread läuft, wenn onSurfaceDestroyed passiert. Ihr Thread verwendet den Surface Holder als Eingabe und wenn er einmal aufruft, wenn er zerstört wird, kann dieser Fehler auftreten. Warum hast du eine längere Zeit. Was wenn es nicht zufrieden ist und Thread ohne zerstörten Oberflächenhalter läuft. Ich kann Ihre Thread-Klasse nicht sehen, aber ich denke, Sie sollten gameThread.setRunning (false) setzen; vor der while-Schleife.

+0

Wenn der Thread läuft, Logge den durchschnittlichen FPS (die Vielfachen 30 in Logcat), die es stoppt, wenn ich wieder raus bin. Außerdem habe ich ein Login, um sicherzustellen, dass join() (was kurz nachdem) aufgerufen wurde. So nahm ich an, dass der Thread erfolgreich gestoppt wurde. – Bipboopbug

+0

Interessant ist nun, dass ich den Thread absichtlich nicht gestoppt habe, um zu sehen, ob ich ein anderes Verhalten erhalten und Ihre Hypothese testen würde. Und so hat es das Einfrieren Problem behoben (schade, ich habe jetzt einen wilden Faden)! Ich sehe den Link nicht, aber es gibt einen Anhaltspunkt, dem ich zumindest folgen kann ... – Bipboopbug

+0

Ich setze eine while-Schleife für den Fall, dass der try-Block fehlschlägt, um sicherzustellen, dass der Thread gestoppt wird. Ich weiß nicht, ob es aber eine gute Übung ist ... Und ein guter Aufruf an die setRunning() Methode, ich habe es ausgezogen. Danke für den Ratschlag ! – Bipboopbug

Verwandte Themen