Ich habe eine einfache App, die Internetressourcen liest und die Informationen in einem Widget oder in einer Listenansicht in Form von ImageViews und TextViews anzeigt. Neben dem Herunterladen der Daten aus dem Internet zeigt es diese auch in einem Widget in einem ViewFlipper an.
Wenn ich das Widget dem Startbildschirm hinzufüge, wird onUpdate sofort aufgerufen, lädt die Daten aus dem Internet herunter und aktualisiert das Widget. Das funktioniert einwandfrei. Das Log zeigt onUpdate
und dataDownloaded
mit etwa 3 Sekunden Abstand. Beim nächsten Update (wenn das Telefon im Schlafmodus ist), erfolgt das Update nicht und das zeigen meine Logs an.
- onUpdate wird aufgerufen.
dataDownloading
wird aufgerufen, aber erst nach 20 Sekunden nachdemonUpdate
initial aufgerufen wurde. Ich nehme an, dass dies daran liegt, dass das Telefon im Schlafmodus ist und Zeit benötigt, um Netzwerksockets usw. zu initialisieren.- Danach erhalte ich den ANR-Logeintrag und das Widget-Update erfolgt nicht, der Prozess ist praktisch blockiert, das Widget bleibt auf dem Bildschirm und reagiert nicht auf manuelle Updates von innerhalb der Aktivität, was sonst funktioniert, wenn keine ANR-Ausnahme geworfen wird.
Ich suche nach einer möglichen Lösung dafür. Ich dachte daran, alle Downloads in einem anderen Thread (von innerhalb des AppWidgetProvider, möglicherweise mit AsyncTask
) durchzuführen, die Daten in SQLite oder im lokalen Speicher zu speichern und das Widget-Update (keine Downloads, nur das Lesen der Daten aus SQLite und dem lokalen Speicher) beim nächsten onUpdate
-Aufruf durchzuführen. Damit würde der Anwendungs-/Widget-Prozess reaktionsfähiger werden und nicht in einen ANR-Fehler geraten.
Ist dieser Ansatz mit Threads eine schlechte Praxis? Gibt es eine Alternative? Sollte ich stattdessen einen Service verwenden? Ich neige dazu, keinen Service zu verwenden, es sei denn, es gibt viele Vorteile dafür.
Entschuldigung für die Textwand :)
Bearbeiten: Aus den Dokumenten http://developer.android.com/guide/practices/design/responsiveness.html
Android zeigt den ANR-Dialog für eine bestimmte Anwendung an, wenn es eine der folgenden Bedingungen feststellt:
- Keine Antwort auf ein Eingabebegnissen (z. B. Tastendruck, Bildschirmtouch) innerhalb von 5 Sekunden
- Ein BroadcastReceiver hat die Ausführung nicht innerhalb von 10 Sekunden abgeschlossen