Async-Task funktioniert nicht ordnungsgemäß (doInBackground wird nicht ausgeführt), wenn der Dienst im Hintergrund ausgeführt wird, Android

9

Ich habe bemerkt, dass manchmal die Async-Aufgabe nicht richtig funktioniert. Tatsächlich wird die Methode doInBackground () nicht aufgerufen, dies geschieht meistens, wenn ein Dienst im Hintergrund für diese Aktivität ausgeführt wird. Wenn Musik beispielsweise im Hintergrund mit dem Dienst ausgeführt wird, analysiert die Async-Task XML im Hintergrund nicht, da ihr doInBackground zu dieser Zeit nicht funktioniert und der Fortschrittsdialog oder die progressBar sich weiter dreht.

Ich habe in einigen Artikeln gelesen, dass AsyncTask.THREAD_POOL_EXECUTOR bei folgenden Problemen helfen kann:

%Vor%

aber das hat in meinem Fall nicht geholfen . Das gleiche Problem nach der obigen Implementation.

Hier gebe ich nur ein bisschen meinen Beispielcode um zu verstehen, was ich mache ::

%Vor%

Dies funktioniert im Allgemeinen gut, hängt aber, wenn der Dienst im Hintergrund läuft (ich meine, wenn Musik auf der Rückseite abgespielt wird).

Ich bekomme nicht den genauen Grund für dieses Problem der Async-Aufgabe. Funktioniert die manuelle Thread-Implementierung in diesem Fall ... ??

Nun, ich denke, das Problem liegt daran, dass "Service im Hauptthread läuft, also wenn er ausgeführt wird, blockiert er meine AsyncTask zum Ausführen" ... Also denke ich, wenn wir Service im Hintergrundthread ausführen können, dann kann das helfen . Das ist der Grund, warum ich IntentService ausprobiert habe, um den Dienst in einem separaten Thread auszuführen, aber ich bin nicht sicher, ob IntentService auf unbestimmte Zeit laufen kann, ähnlich wie Service ... und auch IntentService blockiert AsyncTask einige Male. Daher denke ich nicht, dass es 100% perfekte Lösungen für diese Art von Problemen gibt.

Kann jemand mir helfen, dieses Problem zu lösen und das komplette Szenario zu verstehen.

Vielen Dank im Voraus.

    
Dinesh Sharma 15.02.2013, 09:46
quelle

7 Antworten

1

Hier ist ein Hinweis, wie ich mein Problem endlich gelöst habe ::

1) Ich habe IntentService anstelle von Service verwendet, während Service in mainThread ausgeführt wird, während IntentService in einem separaten Thread als mainThread ausgeführt wird, um sicherzustellen, dass mein Hintergrunddienst meine aktuelle Aufgabe nicht beeinflusst. Außerdem verwende ich AIDL für die Kommunikation zwischen meiner UI und dem Hintergrund-Thread (dies funktionierte bereits für den Dienst, also nichts Neues in diesem Teil).

2) Ich habe painless thread anstelle von AsyncTask verwendet, ich unterbreche den Thread in der Methode onDestroy () , um sicherzustellen, dass der Thread unbegrenzt fortfährt.

App scheint jetzt viel besser als früher zu funktionieren.

Hoffe, das wird auch anderen helfen:)

    
Dinesh Sharma 25.02.2013, 07:35
quelle
3

Manchmal möchten Sie mehr Kontrolle über den Lebenszyklus Ihres Dienstes haben als das, was Ihnen IntentService zur Verfügung stellt. In diesen Fällen können Sie einfach einen Thread im Dienst erstellen und Ihren Hintergrundcode darin ausführen. Um genauer zu sein, erstellen Sie einen HandlerThread, der einen Looper enthält, so dass Sie die Standard-Android-Methode für die Kommunikation (Nachrichten) zwischen Ihrem Haupt-Thread und dem Hintergrund-Thread verwenden können.

hier beantwortet

    
Aashish Bhatnagar 22.02.2013 10:50
quelle
1

Ich denke, das Problem ist, ein weiteres GetData AsyncTask zu starten, bevor das vorherige fertig ist. Stellen Sie vor dem Ausführen einer anderen Aufgabe sicher, dass die vorherige abgeschlossen ist. Verwenden Sie dazu folgenden Code:

%Vor%

Stellen Sie außerdem sicher, dass Sie eine Referenz für die Ausführung von Aufgaben haben. Sie können dafür die Unterklasse Application class verwenden, während Ihre Anwendung läuft oder onSaveInstanceState(Bundle outState) überschreibt. und erhalten eine Referenz darauf in onCreate(Bundle savedInstanceState) .

    
bohlool.mohammadi 21.02.2013 17:30
quelle
1

Lesen Sie alle Probleme und Antworten, die hier gepostet wurden. Korrigieren Sie mich, wenn ich falsch liege Ihr Szenario ist, dass Sie das XML analysieren und die Liste der Lieder bekommen und wenn der Benutzer ein Lied auswählt, das mit dem Service gespielt werden soll, oder?

Wenn das Szenario korrekt ist, können wir es auf viel einfachere Weise implementieren.

  1. In der Activity analysiert die onResume() -Methode die XML-Datei und ruft die Liste der Songs ab und aktualisiert die Listenansicht (starten Sie hier nichts, was mit dem Service zu tun hat)
  2. Wenn der Benutzer auf den Song klickt, dann den bestimmten Schlüssel / String mit Absicht an den Service weiterleiten und den Service starten
  3. In der OnStartCommand() -Methode des Services erhalten Sie den Bezeichner und starten den Song wie bei normalen Medien-APIs

Das wird tatsächlich die Arbeit für Sie tun.

Zum Problem von

%Vor%

Dies ist für unterschiedliches Verhalten von AsyncTask auf Verschiedene Versionen von Android. Wenn Sie Ihren Code betrachten, wird in der Aktivität der Service initialisiert, so dass der Service im Hintergrund läuft, ohne etwas fruchtbares zu tun. und wenn der Benutzer auf Play klickt, rufen Sie die Funktion play of service auf, die problme hier erzeugt.

, um die Funktion des Dienstes von der Aktivität zu nennen, sollten Sie AIDL, das Sie nicht erwähnt haben, rechts. und wenn du so geschrieben hast sollte es perfekt sein.

aber hier Empfehlung ist die Song-ID an den Dienst übergeben und es sollte vom Dienst spielen sollte Service-Funktion nicht in Aktivität aufrufen.

Wenn Sie die Songliste in der onResume der Aktivität aktualisieren möchten, müssen Sie AIDL schreiben und das Szenario

ausführen

Hoffe, das wird helfen.

    
Dinesh Prajapati 22.02.2013 11:19
quelle
1
  

Ich habe bemerkt, dass manchmal Async-Task nicht richtig funktioniert, eigentlich   Die Methode doInBackground () wird nicht aufgerufen, dies geschieht meistens

Sie wissen, dass es ein Limit von AsyncTasks gibt, die gleichzeitig ausgeführt werden können? Ich hatte einmal ein Problem, bei dem eine Aufgabe nicht richtig gestartet wurde und das war, weil ich diese Zahl überschritten habe. Weitere Informationen zu diesem Thema finden Sie unter Grenzwerte für Android-AsyncTask-Threads

  

wenn ein Service im Hintergrund für diese Aktivität ausgeführt wird. Beispielsweise ,   Wenn Musik im Hintergrund mit dem Dienst ausgeführt wird, funktioniert die Async-Aufgabe nicht   parse XML im Hintergrund, da sein doInBackground zu dieser Zeit nicht funktioniert   und der Fortschritt Dialog oder Fortschrittsbalken drehte sich weiter.

Haben Sie die Möglichkeiten von Deadlocks überprüft (insbesondere wenn Sie wait() und notify() verwenden)?

  

Nun, ich denke das Problem liegt daran, dass "Service im Hauptthread läuft   Wenn es ausgeführt wird, blockiert es meine AsyncTask zum Ausführen von "... Also ich denke, wenn wir können   Führen Sie Service im Hintergrund Thread dann das kann helfen. Deshalb ich

Die Dinge, die Sie in einem Service tun werden, sollten trotzdem in einem eigenen Thread laufen. So können Sie sicher sein, dass nichts blockiert wird. Wenn Sie etwas zu bevölkern haben, können Sie beispielsweise einen Empfänger verwenden.

Ich hoffe, ich könnte ein bisschen helfen ...

    
Trinimon 23.02.2013 18:46
quelle
0

Im Abschnitt "Threadingregeln" des Android Developer AsyncTask-Dokuments muss AsyncTask erstellt und auf dem Benutzeroberflächenthread gestartet werden. Wenn Sie es aus einem Hintergrundthread in einem Service starten, würde dies den Fehler verursachen Verhalten.

Ссылка

    
Brent Hronik 22.02.2013 04:42
quelle
-2

Sie sollten wirklich nicht AsyncTasks im Allgemeinen verwenden :) Es gibt eine ziemlich gute Erklärung hier . Denken Sie darüber nach, was passiert, wenn der Benutzer das Gerät dreht, während Ihre Aufgabe ausgeführt wird. Die Aktivität wird neu erstellt, die Aufgabe wird jedoch im Hintergrund ausgeführt und enthält einen Verweis auf die "alte" Aktivität. Es gibt Möglichkeiten, um dies zu umgehen, und sie sind sicherlich noch einige Fälle, in denen ein AsyncTasks der richtige Ansatz ist.

Sie sollten jedoch wirklich erwägen, zu einem Loader zu wechseln oder (wenn Sie abenteuerlustig sind) RoboSpice :)

    
stoilkov 22.02.2013 09:04
quelle