9 Stimmen

MediaPlayer in separatem Thread vs. Ausführung im Dienst über startForeground()

Ich streame also Musik in einem separaten Thread. Wenn ich die App verlasse ( onPause() , onStop() angerufen werden usw.), die Musik spielt weiter, aber schließlich - nachdem ich andere Anwendungen geöffnet und zwischen ihnen gewechselt habe und zum Startbildschirm zurückgekehrt bin - wird meine Anwendung beendet. Kein Absturz, nur ein WIN DEATH y process com.myapp.android has died in logcat. Offensichtlich ist es legitim, dass Anwendungen vom System zerstört werden, um Ressourcen zurückzugewinnen.

Meine Frage ist: bedeutet das Ausführen von Sachen in einem Thread außerhalb des Haupt-(UI)-Threads, dass es jetzt weniger Priorität hat, soweit das System betroffen ist? Das heißt, ist es wahrscheinlicher, dass es beendet wird, als wenn ich den Media Player in einem Service und verwenden sogar startForeground() um den Dienst im Vordergrund laufen zu lassen?

Für jeden Gedanken oder jede Klarstellung wären wir Ihnen sehr dankbar!

EDITAR

Außerdem verwirrt mich ein Teil der Dokumentation über Dienste. Dort heißt es unter anderem:

Vorsicht! Ein Dienst läuft im Haupt-Thread seines Hosting-Prozesses - dem Dienst erstellt keinen eigenen Thread und läuft nicht in einem separaten Prozess (sofern Sie nichts anderes angeben). Das bedeutet, dass, wenn Ihr Dienst CPU-intensive Arbeit oder blockierende (z.B. MP3-Wiedergabe oder Netzwerkbetrieb), sollten Sie einen neuen Thread innerhalb des Dienstes erstellen, um diese Arbeit zu erledigen.

Ich habe die MP3-Wiedergabe immer in einem Dienst auf dem Hauptthread laufen lassen, und die Benutzeroberfläche war immer ansprechbar. Wenn ich es in einem separaten Thread setzen soll, wie in dem obigen Zitat empfohlen, dann werde ich nicht am Ende wieder, wo ich begann, nämlich mit der Medienwiedergabe aus dem Haupt-Thread auftreten, wodurch die Wahrscheinlichkeit, dass die Wiedergabe beendet wird, wenn andere Anwendungen geöffnet werden, usw.?

8voto

ajacian81 Punkte 6971

Einen Teil dieser Antwort habe ich gerade an anderer Stelle gepostet, aber sie ist immer noch relevant.

Leider reicht der Aufruf von prepareAsync() nicht aus, um ANR-Eingabeaufforderungen zu vermeiden und zu verhindern, dass Ihre Anwendung einige Sekunden lang hängen bleibt, insbesondere wenn Sie eine Datei aus dem Netzwerk wiedergeben. Am besten ist es, wenn Sie Ihre MediaPlayer-Instanz in einen eigenen Thread packen oder zumindest intensive Aufrufe in einem Handler (wie mediaplayer.start()) ausführen. Ich benutze den MediaPlayer seit über einem Jahr und ich kann Ihnen sagen, dass er sich nach verschiedenen Aufrufen definitiv aufhängt, je nach den Umständen.

Idealerweise sollten Sie einen Thread starten, der Ihren MediaPlayer von einem Dienst aus steuert. Auf diese Weise stellen Sie sicher, dass Ihre Medien weiterhin abgespielt werden, während Ihre Anwendung im Hintergrund läuft, und dass blockierende Aufrufe (abgesehen von prepare()/prepareAsync()) Ihre Anwendung nicht aufhalten.

2voto

nicholas.hauschild Punkte 41528

Ich denke, der größte Teil Ihrer Frage wird in der Android-Dokumentation über Dienste .

Aus dem Link:

Ein Vordergrunddienst ist ein Dienst, der als etwas betrachtet wird, das der Benutzer aktiv wahrnimmt und daher kein Kandidat für das System ist zu beenden, wenn der Speicher knapp wird. Ein Vordergrunddienst muss eine Benachrichtigung für die Statusleiste bereitstellen, die sich unter der Rubrik "Laufend" befindet Das bedeutet, dass die Benachrichtigung nur dann gelöscht werden kann, wenn der Dienst entweder beendet oder aus dem Vordergrund entfernt wird.

Um Ihre Frage zu beantworten: Ja, die Ausführung einer separaten Thread von einem Activity wird eine niedrigere Priorität haben als eine Service im Vordergrund laufen, wenn die Activity die den Thread wurde gestoppt/angehalten.

Ich persönlich würde empfehlen, dies in einem Service da dies genau die Art von Dingen ist, die die Service Klasse erstellt worden ist.

Bearbeiten:

Interessant, was Sie vorschlagen, scheint im Gegensatz zu dem zu stehen, was ich gelesen habe (alles ist ansprechbar, wenn kein Gewinde in Service ). Wie auch immer, es sollte wahrscheinlich in einem Hintergrund-Thread begonnen werden.

Der Thread (ein Thread, den SIE erstellen) wird nicht sterben, es sei denn, der Prozess stirbt, und das wird passieren, wenn die Laufzeit entscheidet, dass Ressourcen benötigt werden. Activity können getötet werden, wenn sie sich nicht im Vordergrund befinden, so dass ihre Thread können ebenfalls zerstört werden. Wenn Sie eine Service als Vordergrund markiert ist, ist es weniger wahrscheinlich, dass sie zerstört wird, und daher sollten Sie nicht das gleiche Problem haben.

-1voto

Robin Davies Punkte 7124

Es besteht keine Notwendigkeit, einen MediaPlayer in einem Thread auszuführen. Solange Sie MediaPlayer.prepareAsync und nicht MediaPlayer.prepare verwenden, gibt es keine Methoden auf MediaPlayer, die lange genug blockieren, um Probleme zu verursachen. Führen Sie ihn im Vordergrund-Thread Ihres Dienstes aus.

Wenn Ihr Prozess beendet wird, gehen die Threads mit ihm. Prozesse, die Dienste hosten, haben eine längere Lebensdauer als Aktivitäten, vorausgesetzt, Sie rufen die Methode Service.startForeground auf (und zeigen die von startForeground geforderte Benachrichtigung in der Statusleiste an). Sobald eine Aktivität pausiert, wird der gesamte Prozess zu einem erstklassigen Kandidaten für das Recycling (vorausgesetzt, es gibt nicht auch einen Vordergrunddienst im Prozess).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X