2017-01-05 4 views
6

Ich bin neugierig, warum das unten ein Speicherleck ist, weil der mHandler auf dem mainThread erstellt wird und jetzt, wenn onDestroy aufgerufen wird, wird es nicht einfach den Thread töten? Wie kann der Handler existieren, nachdem die Aktivität zerstört wurde? Ich habe keinen neuen Thread erstellt. Muss ich verstehen, dass ein Handler, wenn er Dinge in der Nachrichtenwarteschlange hat, auch nach der Zerstörung eines Threads bleibt?Android - können MainThread-Handler Speicherlecks verursachen?

Die Referenz doc im Lesen ist here enter image description here

Antwort

13

Handler werden hauptsächlich verwendet, um Ereignisse in die MessageQueue des Threads zu schreiben. Jede Handler-Instanz ist einem einzelnen Thread und der Nachrichtenwarteschlange dieses Threads zugeordnet.

so, wenn Sie einen lauffähiges mit einer Verzögerung veröffentlichen, und Austritt aus der Tätigkeit, wird der Mainthread nicht zerstört werden, da es noch Ereignisse in dem Message sind nach einer Verzögerung verarbeitet werden, so kann dies dazu führen, eine Memoryleak als Ihre anonyme innere Klasse von Runnable hält die Referenz AktivitätInstanz.

so stellen Sie sicher, dass alle Nachrichten in OnStop() von Aktivität zu entfernen, indem

handler.removeCallbacksAndMessages(null); 

dieser Aufruf wird alle anstehenden Meldung und Rückrufe löschen, bevor Sie Ihre Tätigkeit zu verlassen.

+0

also, wenn ein Handler Nachrichten in der Warteschlange hat, muss er weiter ausgeführt werden, selbst wenn die Aktivität, an der er erstellt wurde, endet, richtig? – j2emanue

+0

Und im Fall meines Beispiels ist der Handler dem mainThread zugeordnet. und ich reite Runnables zum Hauptthreadlooper. Wenn die Aktivität nun onDestroy aufruft, da sich noch Nachrichten in der looper-Warteschlange von mainThreads befinden, erfasst der GC die Aktivität nicht? Oder ist es so, dass der GC die Aktivität wegen der Referenz, die das Runnable enthält, nicht sammelt? Sehen Sie, was ich meine? Sagen wir, das Runnable hatte keine Aktivitätsreferenz? Wäre es noch durchgesickert? – j2emanue

+0

@ j2emanue Wenn Ihr Runnable keine Aktivitätsreferenz enthält, tritt in diesem Fall kein Aktivitätsleck auf, aber der Hauptthread bleibt aktiv, da er die Ereignisse in der Nachrichtenwarteschlange beenden muss, die vom Runnable gepostet werden. –

0

können sie, aber nicht von der Handler- des Runnable, die gebucht wird. Die Funktionsweise eines Handlers besteht darin, dass er mit einem Thread verknüpft ist. Dieser Thread muss einen Looper haben. Ein Looper hat eine Nachrichtenwarteschlange. Wenn Sie postDelayed senden, fügen Sie das Runnable der Nachrichtenwarteschlange dieses Loopers hinzu. Der Thread selbst hat also einen Verweis auf das Runnable. Damit würde Runnable durchgelassen, und wenn nicht-statisch, wird die Elternklasse durchgesickert.

Verwandte Themen