2013-03-22 4 views
5

In meiner App habe ich viele GET, POST, PUT Anfragen. Im Moment habe ich eine Singleton-Klasse, die meine heruntergeladenen Daten enthält und viele innere Klassen hat, die AsyncTask erweitern. In meiner Singletonklasse, ich habe auch ein paar Schnittstellen wie folgt aus:Gute Entwurfsmuster zum Codieren vieler HTTP-Anfragen in Android

/** 
* Handlers for notifying listeners when data is downloaded 
* 
*/ 
public interface OnQuestionsLoadedListener { 

    public void onDataLoadComplete(); 

    public void onDataLoadingError();  
} 

Gibt es etwas falsch mit diesem Muster (viele innere Klassen, die AsyncTask verlängern)? Könnte es effizienter sein mit vielleicht nur einer inneren Klasse für jeden HTTP-Aufruf (1 für GET, 1 für POST, ...)? Wenn ja, wie zu entscheiden, was nach z. GET Anfrage?

Antwort

0

In einem kürzlich entwickelten App folgte ich ein ähnliches Schema, sondern zusätzlich eine WebRequest-Klasse des tatsächlichen GET tun implementiert, POST, PUT usw.

Was ich habe jetzt eine „Connector“ Klasse ist, die eine ganze Menge hat von AsyncTask-Unterklassen innerhalb. In meiner Implementierung habe ich sie jedoch dazu gebracht, ein Callback-Objekt zu akzeptieren, an das jede dieser Unterklassen das Http-Ergebnis übergibt.

Ich denke, das ist eine gültige, wenn nicht vielleicht ideale Weise. Wenn ich nur eine Unterklasse von Asynctask hätte, an die ich den Request-Body (der jetzt in diesen verschiedenen Tasks eingebaut ist), die Request-URL und -Methode sowie den Callback übergeben würde, könnte ich mir eine Verbesserung vorstellen (was meiner Meinung nach eine ziemlich gute Möglichkeit ist, die Ergebnisse zu erhalten).

4

Als Ganzes sollten Sie von AsyncTasks während der Vorbereitung von Netzwerkanforderungen wegkommen.

Ihre AsyncTasks sind mit Ihrer Aktivität verknüpft. Das heißt, wenn Ihre Aktivität beendet wird, wird Ihre AsyncTask beendet. Dies ist nicht das größte Problem beim Abrufen von Daten, die in dieser Aktivität angezeigt werden, da es nicht wichtig ist, dass das Abrufen gestoppt wurde. Wenn Sie jedoch einige gespeicherte Daten an den Server senden möchten und Ihr Benutzer "Zurück" oder etwas Ähnliches gedrückt hat, bevor alles gesendet wurde, können die Daten verloren gehen und nicht gesendet werden.

Was Sie stattdessen haben möchten, ist ein Dienst, der unabhängig davon läuft, was mit Ihren Aktivitäten passiert.

Ich würde Ihnen raten, einen Blick in RoboSpice zu werfen. Selbst wenn Sie sich entschließen, es nicht zu verwenden, können Sie durch das Lesen dessen, was es tut und warum es funktioniert, einen guten Einblick in die ziemlich lange Liste der Gründe erhalten, AsyncTasks für Netzwerkanforderungen nicht zu verwenden und warum Dienste besser zu nutzen sind. Wenn Sie dies verwenden, ist der Rest Ihrer Frage über effiziente Netzwerkanforderung auch veraltet, da sie es für Sie auf die bestmögliche Weise behandeln werden.

+0

Danke für den Link! Ich habe RoboSpice noch nie ausprobiert und noch nie davon gehört, aber nachdem ich darüber gelesen habe, finde ich es großartig. So, jetzt werde ich es so schnell wie möglich versuchen. – Michael

+0

Viel Glück :) Wenn Sie mit Ihrer App schon ziemlich weit sind und RoboSpice nicht einfach zu implementieren ist, können Sie auch einfach Ihren eigenen Dienst erstellen, der die Absichten verarbeitet, die Sie ihm senden.Sie werden wahrscheinlich einige Optimierungen vermissen und sicherlich das Caching, aber dennoch die Kernprobleme von AsyncTasks und Loadern für das Netzwerk umgehen. Viel Glück –

+1

Also, wenn ich Bildschirm während meiner asynctask Ausführung rotieren, wird es neu gestartet? – DixieFlatline

1

Nichts ist falsch mit vielen asynchronen Klassen.

Welche Ido haben eine Netzwerkschicht, eine Serviceklasse. Senden Sie eine Absicht an die Serviceklasse mit einem Ergebnisempfangsobjekt als Teil der Absicht. dann in den Service http http Anfrage in async Aufgabe und senden Sie das Ergebnis durch Ergebnis-Empfänger-Objekt.

Ein gutes Design ist die UI (Aktivität oder Fragment) von Netzwerkzugriff zu abstrahieren.