2010-05-17 14 views
5

In einer Android-Anwendung führe ich eine Aufgabe in einem separaten Thread aus. Während der Thread läuft, aktualisiert er eine Fortschrittsleiste im Hauptfenster, um den Benutzer wissen zu lassen, was vor sich geht. Das Problem ist, dass der Fortschrittsbalken nicht zurückgesetzt wird, wenn ein Benutzer den Thread ein zweites Mal startet. Es wird nur auf 100% sitzen, ohne etwas zu tun.ProgressBar wird beim zweiten Öffnen nicht auf "0" zurückgesetzt

Die ganze Quelle ist available on github. Als Beispiel nehmen Sie die BackupThread und JsonBackup (die Hauptklasse). Beachten Sie, dass "RestoreThread" das gleiche Verhalten zeigt, aber ich nehme an, dass in beiden Fällen das Problem identisch ist.

auf einen kurzen Spaziergang durch:

Gegen line 300 in JsonBackup.java, öffne ich ein neues ProgressDialog. Da es sich um eine neue Instanz handelt, gehe ich davon aus, dass alles korrekt initialisiert wird. Auf meiner aktuellen Arbeitskopie habe ich eine Zeile hinzugefügt, die den Fortschritt auf "0" setzt, aber daran hat sich nichts geändert. Im selben Block erstelle ich den Sicherungs-Thread und führe ihn aus.

Das nächste Bit des Codes von Interesse ist der Moment, wenn der Thread Fortschritte zurück zu der Hauptanwendung ist es in Verbindung steht. Dies geschieht um line 185 of BackupThread.java.

Die Nachricht wird in line 80 of JsonBackup.java behandelt, die den Fortschrittsbalken aktualisieren.

Bisher für den Code Durchlauf. Eine Sache, die mir während des Schreibens aufgefallen ist, ist line 87 of JsonBackup.java. Ich denke, es wäre am besten, wenn der Thread eine andere Nachricht senden würde, die ausdrücklich darauf hinweist, dass es erledigt ist. Aber ich nehme an, das ist hier nicht das eigentliche Problem. Ich sage das, weil sich der Fortschrittsdialog korrekt beendet, sobald er 100% erreicht. So

wenn diese ganze Sache einmal ausgeführt wird, funktioniert alles wie erwartet. Nehmen Sie nun an, dass der Benutzer die Anwendung verlässt, aber das Betriebssystem beschließt, sie im Arbeitsspeicher zu belassen. Später kommt der Benutzer zurück und möchte ein neues Backup erstellen. Dann wird die App nicht funktionieren, da der Fortschritt bei 100% hängt. Wenn Sie die App beenden, so dass sie vollständig entladen ist, wird sie wieder funktionieren. Ich nehme also an, dass eine Objektinstanz noch im Speicher ist und einen unreinen Zustand hat, wenn sie erneut ausgeführt wird. Aber für das Leben von mir kann ich nicht herausfinden, was vor sich geht. Als eine Tangente könnte ich hinzufügen: Abgesehen von den Notepad-Tutorials, das ist meine erste Android-App, und bla di blah blah ...

Was fehlt mir hier ...?

+0

Gerade für mehr für jemanden wie mich zu erklären, wenn Sie die Fortschrittsbalken in einem AsyncTask verwenden, können Sie den Fortschritt der Fortschritte auf Null auf der OnPostExecute Funktion für die nächste Zeit mit Dialog gesetzt. – Behzad

Antwort

4

Die Dialog wird von Activity zwischengespeichert, das ist das erwartete Verhalten.
Optionen sind:

  1. Überschreibung onPrepareDialog(..)removeDialog(..) zurücksetzen
  2. Anruf es ist Zustand, bevor es wieder
  3. verwalten den Dialog selbst, manuell aufrufen show(), dismiss()

ich in der Regel gehen # 1 zeigt für häufig verwendete Dialog s und # 3 für die seltenen.

+0

Danke. Das brachte mich auf den richtigen Weg. – exhuma

1

Normalerweise verwende ich onCreateDialog() und onPrepareDialog() Dialoge zu verwalten.

From dev guide on android developers:

Der beste Weg, um die onCreateDialog (int) und onPrepareDialog (int, Dialog) Callback-Methoden ist mit einem Schalter Anweisung, die die ID-Parameter überprüft, um zu definieren, die in das Verfahren geführt wird. Jeder Fall sollte nach einer eindeutigen Dialog-ID suchen und dann den entsprechenden Dialog erstellen und definieren.

onCreateDialog() -Methode wird einmal aufgerufen, wenn das Dialogfeld zum ersten Mal erstellt wird; fügt hier den Code ein, der Ihre Dialoge initialisiert.

Die Methode onPrepareDialog() wird jedes Mal aufgerufen, wenn das Dialogfeld angezeigt wird.

Es bietet die Möglichkeit, ein verwaltetes Dialog vorzubereiten, bevor es gezeigt wird. Überschreiben Sie diese Option, wenn Sie benötigen einen verwalteten Dialog aktualisieren basierend auf dem Zustand der Anwendung

Wenn der Dialog geschlossen werden muss, können Sie:

Wenn Sie onCreateDialog (int) verwenden Um den Zustand Ihrer Dialoge zu verwalten (wie in der vorherigen Abschnitt diskutiert), dann jedes Mal, wenn Ihr Dialogfeld wird entlassen, wird der Status des Dialogs Objekt von der Aktivität beibehalten. Wenn Sie entscheiden, dass Sie nicht mehr dieses Objekt benötigen oder es wichtig ist , dass der Status gelöscht wird, dann sollten Sie removeDialog (int) aufrufen. Diese wird alle internen Verweise auf das Objekt entfernen und wenn das Dialogfeld zeigt, wird es es entlassen.

Verwandte Themen