Hintergrundaufgabe, Fortschrittsdialog, Orientierungsänderung - Gibt es eine 100% ige Arbeitslösung?
Lade ich einige Daten aus dem internet im hintergrund-thread (ich benutze AsyncTask
) und zeigt eine Fortschrittsanzeige, die beim herunterladen. Ausrichtung ändert, die Aktivität neu gestartet wird und dann mein AsyncTask beendet ist - ich will, zu entlassen, der Fortschritts-dialog und starten Sie eine neue Aktivität. Aber anrufen dismissDialog manchmal wirft eine Ausnahme (wahrscheinlich, weil die Aktivität zerstört wurde und eine neue Aktivität noch nicht gestartet wurde).
Was ist der beste Weg, um mit dieser Art problem umzugehen (Aktualisierung der Benutzeroberfläche aus hintergrund-thread, der funktioniert sogar, wenn die Benutzer die Orientierung ändert)? Hat jemand von Google bieten einige "offizielle Lösung"?
InformationsquelleAutor der Frage fhucho | 2010-09-29
Du musst angemeldet sein, um einen Kommentar abzugeben.
Schritt #1: Machen Sie Ihre
AsyncTask
einestatic
geschachtelte Klasse oder einer ganz eigenen Klasse, nicht nur ein innerer (nicht-statischen verschachtelten) Klasse.Schritt #2: die
AsyncTask
halten Sie auf derActivity
über ein Daten-member, die per Konstruktor und eine setter.Schritt #3: Beim erstellen der
AsyncTask
liefern die aktuellenActivity
an den Konstruktor übergeben.Schritt #4:
onRetainNonConfigurationInstance()
zurückAsyncTask
nach dem trennen Sie es von der ursprünglichen, jetzt-geht-Weg-Aktivität.Schritt #5:
onCreate()
wenngetLastNonConfigurationInstance()
ist nichtnull
cast es zu IhremAsyncTask
Klasse und rufen Sie Ihren setter zu verbinden, Ihre neue Tätigkeit mit der Aufgabe.Schritt #6: beziehen sich nicht auf die Aktivitätsdaten Mitglied aus
doInBackground()
.Wenn Sie Folgen Sie den oben genannten Rezept, es wird alles funktionieren.
onProgressUpdate()
undonPostExecute()
ausgesetzt sind zwischen dem Beginn desonRetainNonConfigurationInstance()
und das Ende des nachfolgendenonCreate()
.Hier ist ein Beispielprojekt demonstriert die Technik.
Ein weiterer Ansatz ist, Graben der
AsyncTask
und bewegen Sie Ihre Arbeit in einerIntentService
. Dies ist besonders nützlich, wenn die Arbeit getan werden kann lang sein und sollte gehen, unabhängig davon, was der Benutzer hat in Bezug auf Aktivitäten (z.B., herunterladen einer großen Datei). Sie können eine bestellte SendungIntent
entweder haben die Aktivitäten reagieren auf die Arbeit (wenn es noch im Vordergrund steht) oder erhöhen eineNotification
lassen den Benutzer wissen, wenn die Arbeit getan ist. Hier ist ein blog-post mit mehr auf dieses Muster.InformationsquelleAutor der Antwort CommonsWare
Akzeptierte Antwort war sehr hilfreich, aber es muss nicht ein Fortschritts-dialog.
Glücklicherweise für Sie, die Leser, die ich erstellt habe, eine äußerst umfassendes und funktionsfähiges Beispiel eines AsyncTask mit einem Fortschritt-dialog!
InformationsquelleAutor der Antwort Timmmm
Habe ich geschuftet für eine Woche zu finden, eine Lösung für dieses dilemma, ohne Rückgriff auf die Bearbeitung der manifest-Datei. Die Annahmen für diese Lösung sind:
Umsetzung
Müssen Sie kopieren die beiden Dateien gefunden an der Unterseite von diesem post in Ihrem Arbeitsbereich. Stellen Sie sicher, dass:
Alle Ihre
Activity
s erweitern sollteBaseActivity
In
onCreate()
super.onCreate()
sollte aufgerufen werden, nachdem Sie initialisiert alle Mitglieder, die erreicht werden müssen, indem Sie IhreASyncTask
s. Auch, überschreibengetContentViewId()
um die Formular-id.Überschreiben
onCreateDialog()
wie üblich zu erstellen, die Dialoge gelungen, die von der Aktivität.Siehe code unten ein Beispiel-statische innere Klasse, um Ihren AsyncTasks. Sie können speichern Sie Ihr Ergebnis in mResult für den späteren Zugriff.
Und schließlich, starten Sie Ihre neue Aufgabe:
Das ist es! Ich hoffe, dass diese robuste Lösung, die hilft jemand.
BaseActivity.java (Importe verwalten sich selbst)
SuperAsyncTask.java
InformationsquelleAutor der Antwort Oleg Vaskevich
Ja.
Die Lösung ist eher ein Anwendungs-Architektur-Vorschlag eher, dass nur einige code.
Schlugen Sie 3 design patterns , ermöglicht es einer Anwendung zu arbeiten, in-sync mit einem server, unabhängig von der Anwendung staatlichen (es funktioniert sogar, wenn der Benutzer beendet die app, die änderungen durch Benutzer-Bildschirm, die app wird beendet, alle anderen möglichen Zustand, in dem ein hintergrund-Daten-Betrieb könnte interrumpted dies deckt es)
Den Vorschlag erläutert Android REST client applications Rede während Google I/O 2010 von Virgil Dobjanschi. Es ist 1 Stunde lang, aber es ist äußerst sehenswert.
Basis ist es Abstraktion der Netzwerk-Operationen zu einer
Service
das funktioniert unabhängig von einerActivity
in der Anwendung. Wenn Sie die Arbeit mit Datenbanken, der Einsatz vonContentResolver
undCursor
würde Ihnen eine out-of-the-box Observer-Muster das ist bequem zu aktualisieren, UI-ohne zusätzliche Logik, sobald Sie aktualisiert Ihre lokale Datenbank mit dem aktuellen remote-Daten. Alle anderen nach-operation-code würde ausgeführt werden über einen callback, der an dieService
(ich benutze eineResultReceiver
Unterklasse).Jedenfalls meine Erklärung ist eigentlich Recht vage, Sie sollten definititely Uhr die Rede.
InformationsquelleAutor der Antwort Christopher Francisco
Während Mark ' s (CommonsWare) Antwort funktioniert in der Tat für die Ausrichtung ändert, schlägt es fehl, wenn die Activity zerstört wird direkt (wie im Fall von einem Anruf).
Können Sie die Ausrichtung ändert UND die seltenen zerstört Aktivität Ereignisse durch die Nutzung von Application-Objekt verweisen Sie Ihre ASyncTask.
Gibt es eine hervorragende Erklärung für das problem und die Lösung hier:
Kredit geht vollständig an Ryan herauszufinden.
InformationsquelleAutor der Antwort Scott Biggs
Nach 4 Jahren Google das problem, nur zum telefonieren setRetainInstance(true) in der Activity onCreate. Es wird bewahren Sie Ihre Tätigkeit Instanz während der Drehung des Geräts. Ich habe auch eine einfache Lösung für ältere Android.
InformationsquelleAutor der Antwort Singagirl
sollten Sie rufen alle Aktivitäten Aktionen, die mit Aktivität handler. Also, wenn Sie in einigen thread-erstellen Sie eine Ausführbare und gebucht Activitie Handler. Andernfalls wird Ihre app zum Absturz, manchmal mit fatalen Ausnahme.
InformationsquelleAutor der Antwort xpepermint
Dies ist meine Lösung: https://github.com/Gotchamoh/Android-AsyncTask-ProgressDialog
Grundsätzlich die Schritte sind:
onSaveInstanceState
zum speichern der Aufgabe, wenn es nochVerarbeitung.
onCreate
ich bekomme die Aufgabe, wenn es gespeichert wurde.onPause
verwerfe ich dieProgressDialog
wenn es gezeigt wird.onResume
zeige ich dieProgressDialog
wenn die Aufgabe nochVerarbeitung.
InformationsquelleAutor der Antwort Gotcha