Benötigen Sie ein Beispiel für ein Android REST Client-Projekt, das das REST-Implementierungsmuster von Virgil Dobjanschi implementiert

82

Ich möchte einen REST-Client auf einem Android-Handy erstellen.

Der REST-Server stellt mehrere Ressourcen bereit, z. B. (GET)

http://foo.bar/customer      List of all customer
http://foo.bar/customer/4711    The customer with id 4711
http://foo.bar/customer/vip     List of all VIP customer

http://foo.bar/company           List of all companys
http://foo.bar/company/4711     The company with the ID 4711
http://foo.bar/company/vip      List of all VIP companys

Ich (denke) weiß, wie ich mit dem REST-Server sprechen und die Informationen erhalten kann, die ich brauche. Ich würde eine REST-Client-Klasse mit einer API wie dieser implementieren

public List<Customer> getCustomers();
public Customer getCustomer(final String id);
public List<Customer> getVipCustomer();

public List<Company> getCompanies();
public Customer getCompany(final String id);
public List<Customer> getVipCompanies();

In Bezug auf die Präsentation " Entwickeln von Android-REST-Clientanwendungen " von Virgil Dobjanschi habe ich erfahren, dass es keine gute Idee ist, die REST-Anforderung in einem Worker-Thread der Aktivität zu bearbeiten. Stattdessen sollte ich die Service- API verwenden.

Ich mag die Idee, einen Singleton ServiceHelper zu haben, der an einen (lokalen) Service gebunden ist, aber ich befürchte, dass ich das Servicekonzept nicht richtig verstanden habe.

Im Moment verstehe ich nicht, wie ein REST-Anrufergebnis (das in einem Dienst asynchron ausgeführt wird) an die Anruferaktivität zurückgemeldet wird. Ich frage mich auch, ob ich EINEN Dienst benötige, der alle REST-Anforderungen (mit unterschiedlichen Rückgabetypen) verarbeitet, oder ob ich für jede REST-Anforderung einen dedizierten Dienst benötige.

Wahrscheinlich habe ich viele andere Verständnisprobleme, daher wäre das Beste für mich eine Beispielanwendung, die meinen Anforderungen entspricht. Mein Anwendungsfall ist nicht ungewöhnlich und ich hoffe, dass es eine Beispielanwendung gibt.

Würdest du es mich bitte wissen lassen?

Alle anderen Vorschläge, die mich in die richtige Implementierungsrichtung weisen, sind ebenfalls hilfreich (Android API-Demo entspricht nicht meinem Anwendungsfall).

Danke im Voraus.

Klaus

EDIT : Ähnliche Themen auf SO (nach dem Posten), die mich in die Richtung führen, die ich brauche (Minimierung des komplexen "Dobjanschi-Musters"):

FrVaBe
quelle
1
Claszen, Haben Sie eine Meinung zu einem einzelnen Service für alle Anfragen und zu dedizierten Services für jede Anfrage erhalten? Wenn ja, können Sie bitte teilen. Szenario in meinem Fall: Ich habe viele REST-Anforderungen [ca. 20], die in meiner App verwendet werden sollen. Ich habe die oben erwähnte wertvolle Sitzung in Google I / O gesehen. Meine Frage ist, welches der bessere Ansatz ist. Damit ein einzelner Dienst alle Anforderungen in einem einzigen Dienst bearbeitet? oder einen eigenen Service für jede der Anfragen zu haben? Ich habe einige der Anforderungen, die nacheinander ausgelöst werden sollen, und einige können gleichzeitig ausgelöst werden. Irgendwelche Vorschläge ?
@ user778869 Ich habe endlich einen IntentService und einen ResultReceiver für jede ('Top Level') REST-Ressource (wie 'Firma', 'Kunde') verwendet. Ich fand, dass dies eine Art "natürliche" Struktur ist und gut funktioniert. Es kann zu einigen Codeduplikationen kommen, verhindert jedoch, dass Kontrollstrukturen zu häufig verwendet werden, wenn alles in einem Dienst ausgeführt wird.
FrVaBe
Dies kann sehr hilfreich sein, wenn Sie die Implementierung des Android REST-Clients lernen. Dobjanschis Präsentation wurde in ein PDF übertragen: drive.google.com/file/d/0B2dn_3573C3RdlVpU2JBWXdSb3c/…
Kay Zed

Antworten:

50

Überblick

Bearbeiten:

Jeder, der Interesse hat, sollte sich auch RESTful android ansehen. Dies könnte Ihnen einen besseren Einblick geben.

Was ich aus den Erfahrungen beim Versuch, das Dobjanschi-Modell zu implementieren, gelernt habe, ist, dass nicht alles in Stein gemeißelt ist und er Ihnen nur einen Überblick darüber gibt, was zu tun ist. Dies könnte sich von App zu App ändern, aber die Formel lautet:

Folgen Sie diesen Ideen + Fügen Sie Ihre eigene = Happy Android-Anwendung hinzu

Das Modell einiger Apps kann von den Anforderungen abweichen. Einige benötigen möglicherweise nicht das Konto für den SyncAdapter. Andere verwenden möglicherweise C2DM. Dieses, an dem ich kürzlich gearbeitet habe, kann jemandem helfen:


Erstellen Sie eine Anwendung mit Account und AccountManager

Damit können Sie den SyncAdapter verwenden, um Ihre Daten zu synchronisieren. Dies wurde unter Erstellen eines eigenen SyncAdapters erläutert

Erstellen Sie einen ContentProvider (falls er Ihren Anforderungen entspricht).

Mit dieser Abstraktion können Sie nicht nur auf die Datenbank zugreifen, sondern auch zum ServiceHelper gehen, um REST-Aufrufe auszuführen, da dieser über eine Eins-zu-Eins-Zuordnungsmethode mit dem REST-Bogen verfügt.

Inhaltsanbieter | REST-Methode

Abfrage ----------------> GET

Einfügen ----------------> PUT

Update ----------------> POST

löschen ----------------> LÖSCHEN

ServiceHelper Layering

Dieser Typ startet grundsätzlich (a) Dienste, die eine HTTP-REST-Methode (nicht unbedingt das Protokoll, aber die häufigste) ausführen, mit den Parametern, die Sie vom ContentProvider übergeben haben. Ich habe die Match-Ganzzahl, die vom UriMatcher auf dem Inhaltsanbieter abgerufen wurde, übergeben, damit ich weiß, auf welche REST-Ressource zugegriffen werden soll, d. H.

class ServiceHelper{

    public static void execute(Context context,int match,String parameters){
//find the service resource (/path/to/remote/service with the match
//start service with parameters 
    }

}

Der Service

Wird ausgeführt (ich benutze IntentService die meiste Zeit) und es geht zur RESTMethod mit den vom Helfer übergebenen Parametern. Wofür ist es gut? Denken Sie daran, dass Service gut ist, um Dinge im Hintergrund auszuführen.

Implementieren Sie auch einen BroadCastReceiver. Wenn der Dienst mit seiner Arbeit fertig ist, benachrichtigen Sie meine Aktivität, die diesen Broadcast und diese Anforderung erneut registriert hat. Ich glaube, dieser letzte Schritt ist nicht auf der Virgill-Konferenz, aber ich bin mir ziemlich sicher, dass dies ein guter Weg ist.

RESTMethod-Klasse

Übernimmt die Parameter, fügt die WS-Ressource ( http://myservice.com/service/path ) die Parameter hinzu, bereitet alles vor, führt den Aufruf aus und speichert die Antwort.

Wenn das Authtoken benötigt wird, können Sie es vom AccountManager anfordern. Wenn der Aufruf des Dienstes aufgrund der Authentifizierung fehlgeschlagen ist, können Sie das Authtoken und die Reauth ungültig machen, um ein neues Token zu erhalten.

Schließlich gibt mir die RESTMethod entweder XML oder JSON, unabhängig davon, ob ich einen Prozessor basierend auf dem Matcher erstelle und die Antwort übergebe.

Der Prozessor

Es ist dafür verantwortlich, die Antwort zu analysieren und lokal einzufügen.

Eine Beispielanwendung? Natürlich!

Auch wenn Sie an einer Testanwendung interessiert sind, die Sie sich für Eli-G ansehen , ist sie möglicherweise nicht das beste Beispiel, folgt jedoch dem Service REST-Ansatz. Sie basiert auf ServiceHelper, Processor, ContentProvider, Loader und Broadcast.

Necronet
quelle
Danke für deine Antwort. Ich habe schließlich einen IntentService und einen ResultReceiver für jede ('oberste Ebene') REST-Ressource verwendet (wie 'Firma', 'Kunde'). Das Dobjanschi-Modell war mir viel zu schwer.
FrVaBe
Nun, wenn Sie IntentService und einen ResultReseiver verwenden, verwenden Sie wahrscheinlich das erste Beschreibungsszenario, das ein serviceorientiertes Modell ist, obwohl er Binder anstelle von ResultReceiver für die Kommunikation verwendet, aber das ist gut, wie gesagt, nicht in Stein gemeißelt!.
Necronet
Vor einiger Zeit habe ich die Frage gestellt und eine Lösung gefunden, die zu mir passt. Ich hatte nicht die Möglichkeit, alle Verweise auf Beispielanwendungen zu überprüfen - aber da dies die aktuellste Antwort ist, werde ich sie akzeptieren. Trotzdem empfehle ich auch alle anderen Antworten zu überprüfen.
FrVaBe
Hervorragender Vorschlag, überprüfen Sie alle Antworten, alle haben viele gute Ressourcen und Ideen! wie Jeremy mit dem Programmier-Android-Buch Yoni mit der iosched-Quelle.
Necronet
@Necronet Hallo zusammen, bin gerade über deine vielversprechende Beispiel-App gestolpert - ich habe jedoch Probleme beim Erstellen. Würde es Ihnen etwas ausmachen, uns mitzuteilen, gegen welche Version von ActionBarSherlock es gebaut werden muss (anscheinend funktioniert es mit dem neuesten ABS 4.1 nicht)? Außerdem habe ich in Ihrem Beitrag nicht wirklich herausgefunden, welches Muster (A, B oder C) von Dobjanschis Modellen Sie anstrebten (ich weiß, Sie hatten wahrscheinlich einige Variationen, aber ich nehme an, Sie haben sich hauptsächlich auf eines von ihnen konzentriert die Muster - ich nehme an Muster B?) Danke!
Vaiomike
17

Programmieren von Android enthält ein vollständiges Kapitel (13. Erkunden von Inhaltsanbietern) zu 'Option B: Verwenden der ContentProvider-API' aus Virgils Google I / O-Vortrag.

Wir sind nicht die einzigen, die die Vorteile dieses Ansatzes erkennen. Auf der Google I / O-Konferenz im Mai 2010 präsentierte Virgil Dobjanschi von Google einen Vortrag, in dem die folgenden drei Muster für die Verwendung von Inhaltsanbietern zur Integration von RESTful-Webdiensten in Android-Anwendungen beschrieben wurden.

In diesem Kapitel werden wir das zweite Muster anhand unseres zweiten Finch-Videobeispiels im Detail untersuchen. Diese Strategie bietet eine Reihe wichtiger Vorteile für Ihre Anwendungen. Aufgrund der Eleganz, mit der dieser Ansatz den Netzwerkbetrieb in Android MVC integriert, haben wir ihm den Spitznamen "Network MVC" gegeben.

Eine zukünftige Ausgabe von Programming Android befasst sich möglicherweise mit den beiden anderen Ansätzen und dokumentiert weitere Details dieser Google-Präsentation. Nachdem Sie dieses Kapitel gelesen haben, empfehlen wir Ihnen, den Vortrag von Google anzuzeigen.

Sehr empfehlenswert.

Programmieren von Android von Zigurd Mednieks, Laird Dornin, G. Blake Meike und Masumi Nakamura. Copyright 2011 O'Reilly Media, Inc., 978-1-449-38969-7.

Jeremy Haberman
quelle
11

"Entwickeln von Android REST-Client-Anwendungen" von Virgil Dobjanschi führte zu vielen Diskussionen, da während der Sitzung kein Quellcode präsentiert oder danach bereitgestellt wurde.

  • Eine Referenzimplementierung finden Sie unter http://datadroid.foxykeep.com (die Google IO-Sitzung wird unter / präsentation erwähnt). Es ist eine Bibliothek, die Sie in Ihrer eigenen Anwendung verwenden können.
  • Die Android Priority Job Queue wurde von Dobjanschis Vortrag inspiriert und klingt für mich sehr vielversprechend.

Bitte kommentieren Sie, wenn Sie weitere Implementierungen kennen.

ChrLipp
quelle
Vielen Dank für das Teilen dieses wahrscheinlich nützlichen Links (haben Sie im Moment keine Gelegenheit, einen
genaueren
Das sieht nach einer Lösung aus. Danke !
Vincent Cantin
7

Wir haben eine Bibliothek entwickelt, die dieses Problem behebt : RoboSpice .

Die Bibliothek verwendet den von Virgil Dobjanschi und Neil Goodmann beschriebenen "Service-Ansatz". Wir bieten jedoch eine Komplettlösung, die:

  • führt asynchrone (in einem AndroidService-Hintergrund) Netzwerkanforderungen aus, die POJOs zurückgeben (z. B. REST-Anforderungen)
  • Zwischenspeichert Ergebnisse (in Json- oder XML- oder Flat-Text-Dateien oder Binärdateien)
  • benachrichtigt Ihre Aktivitäten (oder einen anderen Kontext) über das Ergebnis der Netzwerkanforderung, wenn diese noch aktiv sind
  • benachrichtigt Ihre Aktivitäten nicht über das Ergebnis, wenn sie nicht mehr leben
  • benachrichtigt Ihre Aktivitäten auf ihrem UI-Thread
  • verwendet ein einfaches, aber robustes Ausnahmebehandlungsmodell
  • unterstützt mehrere ContentServices, um unterschiedliche Webdienstergebnisse zu aggregieren
  • unterstützt Multithreading von Anforderungsausführungen
  • ist stark getippt!
  • ist Open Source;)
  • und getestet

Wir suchen tatsächlich nach Feedback von der Community.

Snicolas
quelle
4

Eine Nachrüstung kann hier sehr hilfreich sein. Sie erstellt einen Adapter für Sie aus einer sehr einfachen Konfiguration wie:

Retrofit verwandelt Ihre REST-API in eine Java-Schnittstelle.

public interface GitHubService {
  @GET("/users/{user}/repos")
  List<Repo> listRepos(@Path("user") String user);
}

Die RestAdapter-Klasse generiert eine Implementierung der GitHubService-Schnittstelle.

RestAdapter restAdapter = new RestAdapter.Builder()
    .setEndpoint("https://api.github.com")
    .build();

GitHubService service = restAdapter.create (GitHubService.class); Bei jedem Aufruf des generierten GitHubService wird eine HTTP-Anforderung an den Remote-Webserver gesendet.

List<Repo> repos = service.listRepos("octocat");

Weitere Informationen finden Sie auf der offiziellen Website: http://square.github.io/retrofit/

Hinweis : Der Adapter, den RestAdapterSie von Retrofit erhalten, ist nicht von BaseAdapterIhnen abgeleitet. Sie sollten einen Wrapper dafür erstellen, wie diese SO-Frage erstellen, Warum ist meine ListView leer, nachdem Sie setListAdapter in ListFragment aufgerufen haben?

MhdSyrwan
quelle
Können Sie ein vollständiges Beispiel posten, das einen Restdienst
exequielc
3

Sie sollten zunächst den Quellcode für die offizielle I / O 2010-App von Google lesen , insbesondere den SyncService und die verschiedenen Klassen im io-Unterpaket .

Yoni Samlan
quelle
+1 Nicht wirklich mein Anwendungsfall, aber auf jeden Fall ein gutes und hilfreiches Android-Anwendungsbeispiel. Vielen Dank!
FrVaBe
0

Gute Nachrichten Jungs. Eine Implementierung des Service-Helfers finden Sie hier: https://github.com/MathiasSeguy-Android2EE/MythicServiceHelper Es handelt sich um ein Open Source-Projekt (Apache 2). Ich bin am Anfang des Projekts. Ich habe ein Projekt durchgeführt, in dem ich das Muster definiert habe, aber ich habe den Code noch nicht extrahiert, um eine saubere Bibliothek zu erstellen. Es wird bald fertig sein.

Mathias Seguy Android2ee
quelle