2

я организовал свой код следующим образом:Ребенка активность нити вызывает приложение, чтобы быть заморожена на подавлении

MainMenu (деятельность) начинает умысел на Game (другая деятельность). Game комплекты GamePanel (поверхностный держатель), который начинается GameThread (нить).

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(); } 
} 

Проблема возникает, когда я возвращаюсь из Game деятельности. Приложение отображает действие MainMenu, но больше не отвечает, и вскоре система попросит его убить. Кроме того, действия и поток отлично работают.

Я не знаю, есть ли его жизненный цикл активности или проблема с потоком. Когда я не запускаю GameThread, приложение работает нормально. Но GamePanelsurfaceDestroyed называется так, я предполагаю, что поток правильно остановлен.

Я пытался позвонить:

  • GameOnDestroy поймать кнопку назад.
  • Gameотделка улавливание задней кнопки.
  • GameonDestroy до onPause.
  • Gameотделка до onPause.
  • Прерывание на GameThread.

Ничто из перечисленного не разрешает ничего (и некоторые причины аварий).

Эта ошибка возникает сразу при открытии приложения, и когда он будет убит:

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) 

И когда приложение не отвечает:

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 РЕШЕНИЕ:

Я, наконец, нашел проблему! Это произошло из последнего спящего в моем прогоне метода в GameThread, удалив его, решает проблему (и не будет пропущен, поскольку это не имеет никакой цели). Если кто-то может объяснить, как эта миллисекунда может заставить приложение полностью замораживаться, не стесняйтесь!

+0

показать некоторые logcat? – uguboz

+0

Я добавил Logcat. Спасибо, что посмотрели мою проблему! – Bipboopbug

+0

Вы уверены, что этот журнал все что у вас есть? Думаю, должно быть и больше. – ozo

ответ

0

DeadObjectException возникает, когда вы вызываете мертвый объект. Я подозреваю, что ваш поток работает, когда происходит onSurfaceDestroyed. Ваша нить использует поверхностный держатель в качестве входных данных, и если он совершает вызов даже один раз, когда он разрушен, он может вызвать эту ошибку. Почему у вас есть какое-то условие. Что делать, если это не выполняется, и поток работает без разрушенного поверхностного владельца. Я не могу видеть ваш класс потока, но я думаю, вы должны положить gameThread.setRunning (false); перед циклом while.

+0

Когда поток работает, зарегистрируйте средний FPS (кратный 30 в Logcat), который он прекращает делать, когда я возвращаюсь. Плюс у меня есть вход в это время, чтобы убедиться, что join() (который только после этого) был вызван. Таким образом, я предположил, что поток успешно остановлен. – Bipboopbug

+0

Теперь интересно то, что я намеренно не остановил поток, чтобы узнать, получу ли я другое поведение и протестирую вашу гипотезу. И при этом он исправил проблему с замораживанием (слишком плохо, что у меня сейчас есть дикая нить)! Я не вижу ссылку, но есть лидерство, за которым я могу следовать хотя бы ... – Bipboopbug

+0

Я поставил цикл while в случае сбоя блока try, чтобы убедиться, что поток остановлен. Я не знаю, если это хорошая практика, хотя ... И хороший вызов метода setRunning(), я переместил его. Спасибо за совет ! – Bipboopbug