2010-06-16 11 views
5

Ich habe eine Klasse, die die Thread-Klasse erweitert und hat seine Laufmethode als so implementiert.android thread management onPause

public void run(){ 
    while(!terminate){ 
     if(paused){ 
      Thread.yield(); 
     }else{ 
      accummulator++; 
     } 
    } 
} 

Dieser Thread stammt von der onCreate-Methode.

Wenn meine Benutzeroberfläche ausgeblendet ist (wenn die Home-Taste gedrückt wird), setzt meine onPause-Methode das pausierte Flag auf "true" und gibt das Profil zurück. In der DDMS sehe ich jedoch immer noch die uTime des Threads und seinen Zustand als "running".

Also meine Frage ist. Was ist der richtige Weg, um den Thread zu stoppen, so dass es nicht CPU-Zeit verbraucht?

Antwort

4

Es ist eigentlich eine schlechte Übung, einen Thread nach onPause laufen zu lassen. Der Grund dafür ist, dass Ihre Anwendung nach onPause zu keinem Zeitpunkt den Speicher verlassen kann, ohne dass Sie es wissen können. Daher können Sie sich nicht selbst aufräumen.

Der richtige Weg, dies zu tun, ist das Anhalten des Threads onPause und das erneute Erstellen onResume. Wenn Sie einen Status benötigen, können Sie die integrierten saveState-Methoden oder Einstellungen von Android verwenden oder die entsprechenden Einstellungen beibehalten.

+0

Ja, das ist die Schlussfolgerung, die ich auch gefunden habe. Darüber hinaus denke ich, die beste Methode der Implementierung besteht nicht direkt von Thread ableiten, sondern die Runnable-Schnittstelle verwenden. Auf diese Weise können Sie den Thread beenden, haben aber immer noch die Möglichkeit, ihn "fortzusetzen", indem Sie einen anderen Thread instanziieren, ohne den Status zu verlieren. Zugegeben, dass onDestroy oder die Anwendung nicht getötet und neu erstellt wird. –

0

Ihre paused Variable wird höchstwahrscheinlich lokal zwischengespeichert. Dies liegt daran, dass es nur in der Schleife gelesen und nicht geändert wird. Was also passiert, ist, dass Compiler/Interpreter/Jitter optimiert wird, indem nur einmal die Variable gelesen wird und dann nur der Zweig else ausgeführt wird. Sie müssen dieses Feld als volatile für die pause Variable markieren, die bei jeder Iteration durch die Schleife gelesen werden soll. Überprüfen Sie die documentation des volatile Schlüsselworts. Hier ist some info about threading und some info about synchronization and concurrency.

+0

Ich bin nicht so sehr besorgt über die pausierten variablen Besatzungsressourcen. Ich bin besorgt besorgt, dass der Thread noch schleift, obwohl der UI-Thread gestoppt hat. –

+0

Ich habe die Antwort aktualisiert, um klarer zu erklären, was passiert. Die Antwort war nicht über die Pause Variable und Ressourcen. Der Thread wird immer noch wiederholt, da die pausierte Variable nicht als flüchtig markiert ist und nicht erneut gelesen wird. Dies ist nur eine der Feinheiten der Multi-Thread-Programmierung. – Qberticus

1

Obwohl Sie thread.yield() aufrufen, befinden Sie sich in einer while() -Schleife, die wahrscheinlich tausende von Malen pro Sekunde ausführt, jedes Mal, wenn .yield() aufgerufen wird, aber die Tatsache, dass es ausläuft Kontrolle bedeutet, dass es Ressourcen verbraucht. Wenn Sie eine Log.d Nachricht dort eingeben, werden Sie sehen, was ich meine.

Ich empfehle die Verwendung einer Thread.sleep() anstelle von Thread.yield(). Der Grund dafür ist, dass, während ein Thread schläft, er nachgibt. Zusätzlich zu dem Schlaf erhalten Sie den zusätzlichen Vorteil, dass Sie die while() verlangsamen und keine Ressourcen verbrauchen. Ein Sleep-Intervall von 500ms sollte ausreichen =)

+0

der Thread wird schließlich als Render-Thread auf einem Canvas verwendet und es sollte so schnell wie möglich ausgeführt werden. Ich denke, ich werde versuchen, den Thread zu töten und es in der onresume-Handler neu zu erstellen –

+0

Fair genug. Es lohnt sich zu betonen, dass geschlossene Schleifen wie die in Ihrem Code CPU-Schweine sind. Auf einem mobilen Gerät wird ein CPU-Schwein die Batterie in Eile auffressen. –

+0

Ich hatte kein Problem mit 'Thread.yield' (aka' Thread.sleep (0) ') und hoher Prozessorauslastung - der Thread-Scheduler hat eine minimale Granularität * deutlich unter *" tausendmal pro Sekunde ". –