2013-04-12 8 views
7

Ich habe einen Thread, der meine Spielschleife behandelt, wenn ich .join() auf diesem Thread die Anwendung nicht mehr reagiert. Ich habe versucht, ein Problem zu beheben, wo die Programme nie an den Code gelangen, I.E der Thread nie endet.Android- Thread.join() verursacht Anwendung zu hängen

System.out.println("YAY"); 

Mein Thema für das Spiel Loop:

Dieser Thread druckt erfolgreich aus "Game Ended" aber scheint nie zu beenden.

Runnable startGameLoop = new Runnable() {//game loop 
      @Override 
      public void run() { 

       AiFactory ai = new AiFactory(); 
       final Button play = (Button) findViewById(R.id.Play); 
       final Button pass = (Button) findViewById(R.id.Pass); 

       while(finish==false){ 
        try { 
         Thread.sleep(500); 
        } catch (InterruptedException e) { 
         e.printStackTrace(); 
        } 
        currentPlayer = game.getPlayer(); 

        if(currentPlayer.isPlayer()==false){ 

         //System.out.println("passCount:" +game.getPasscount()); 
         ai.decide(nextPlay, game.getPreviousPlayed(), currentPlayer, game.getPasscount()); 
         if(nextPlay.size()!=0){ 
          runOnUiThread(new Runnable(){ 
          public void run(){ 
           changeArrow(); 
           if(nextPlay.size() ==1){ 
            play1Card(); 
           } 
           else if(nextPlay.size()==2){ 
            play2Card(); 
           } 
           else if(nextPlay.size()==3){ 
            play3Card(); 
           } 
           else if(nextPlay.size()==5){ 
            play5Card(); 
           } 
          } 
         } 
         else{ 
          game.addPassCount(); 
          game.nextTurn(); 
          runOnUiThread(new Runnable(){ 
           public void run(){ 
            changeArrow(); 
           } 
          }); 
         }  
        } 
        else if (currentPlayer.isPlayer()==true){ 
         runOnUiThread(new Runnable(){ 
          public void run(){ 
           changeArrow(); 
           play.setClickable(true); 
           if(game.getPasscount()==3){ 
            pass.setClickable(false); 
           } 
           else{ 
            pass.setClickable(true); 
           } 
          } 
         }); 
        } 

      } 
      System.out.println("Game Ended"); 
      } 
    }; 

starten und den Faden auf dem Hauptthread Beitritt:

 Thread myThread = new Thread(startGameLoop); 

    myThread.start(); 
    try { 
     myThread.join(); 
    } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    System.out.println("YAY"); 
} 

Zu meinem Verständnis .join() macht den aktuellen Thread warten, bis die neuen Thread vor Ausübung beendet hat.

Sorry, wenn das eine dumme Frage ist, bin ich ziemlich neu im Threading.

+2

Wir brauchen ein wenig mehr Kontext. Woher kommt dieser Aufruf zu 'join()'? Höchstwahrscheinlich tust du dies im UI-Thread, was erklären würde, warum deine App hängt. –

+0

Join tritt in onCreate() in einer Aktivitätsklasse auf –

+0

Ihre App wartet also auf das Beenden eines Threads, bevor die Erstellung der Aktivität beendet wird. Ist das wirklich das, was du tun willst? Wenn nicht, was versuchst du hier? –

Antwort

5

Wenn Sie myThread.join() innerhalb Activity.onCreate aufrufen, blockieren Sie den Haupt-UI-Thread. Natürlich sieht es so aus, als ob Ihre Anwendung nicht mehr reagiert, da der UI-Thread für das erneute Zeichnen der UI verantwortlich ist (duh). Alle Ihre Anrufe runOnUiThread passieren nie, weil Ihr UI-Thread beschäftigt ist, auf Ihre Spielschleife zu warten.

5

Thread.join macht den aktuellen Thread warten, bis der Faden Sie es an den Enden nennen. Der Thread, den Sie aufrufen, wird nicht beendet. Wenn also dieser Thread nie endet (wie Sie oben sagen), wird der Aufruf von Join für immer hängen bleiben.

Wenn Sie möchten, um tatsächlich den Faden zu beenden, rufen sie abzubrechen. Aber das erfordert, dass Ihr Thread gelegentlich isCanceled() aufruft und seine Ausführungsfunktion beendet, wenn es wahr zurückgibt.

1

mythread.join() stellt nicht sicher, dass Ihr "mythread" beendet ist.

Sie müssen plazieren() in der Spielschleife informieren.

... ...

System.out.println("Game Ended"); 
synchronized(mythread){ 
    mythread.notify(); 
} 

Grundsätzlich, wenn Sie einen Anruf warten() machen, der Code wartet auf dem Monitor des Thread, und ein Anruf() zu benachrichtigen, verursacht ein Thread wartet auf der Monitor des Objekts aufzuwachen. Sie können notifyAll() auch verwenden, um alle wartenden Threads zu aktivieren.

Alternativ können Sie die Timeout-Version von wait() verwenden, in der der Thread entweder wartet, bis er benachrichtigt wird oder eine Zeitüberschreitung auftritt.

+0

Sie sollten 'Lock' besser mit' Condition' verwenden, um dies besser zu erreichen –

Verwandte Themen