Senden von Daten mit Retrofit 2 HTTP-Client für Android

Was Sie erstellen werden

Was ist Retrofit??

Retrofit ist ein typsicherer HTTP-Client für Android und Java. Retrofit macht es einfach, eine Verbindung zu einem REST-Webdienst herzustellen, indem die API in Java-Schnittstellen übersetzt wird. In diesem Tutorial zeige ich Ihnen, wie Sie eine der beliebtesten und häufig empfohlenen HTTP-Bibliotheken für Android verwenden.

Diese leistungsstarke Bibliothek vereinfacht die Verwendung von JSON- oder XML-Daten, die dann in einfache alte Java-Objekte (POJOs) analysiert werden.. ERHALTENPOSTSTELLENPATCH, und LÖSCHEN Anfragen können alle ausgeführt werden. 

Wie die meisten Open-Source-Software wurde Retrofit auf einigen anderen leistungsstarken Bibliotheken und Tools aufgebaut. Hinter den Kulissen verwendet Retrofit OkHttp (vom selben Entwickler), um Netzwerkanfragen zu bearbeiten. Retrofit verfügt auch nicht über einen integrierten JSON-Konverter, um JSON-Objekte in Java-Objekte zu analysieren. Stattdessen wird die Unterstützung für die folgenden JSON-Konverter-Bibliotheken bereitgestellt, um dies zu verarbeiten:

  • Gson: com.squareup.retrofit: converter-gson
  • Jackson: com.squareup.retrofit: converter-jackson
  • Moshi: com.squareup.retrofit: converter-moshi

Für Protokollpuffer unterstützt Retrofit:

  • Protobuf: com.squareup.retrofit2: converter-protobuf
  • Draht: com.squareup.retrofit2: Konverterdraht

Und für XML Retrofit unterstützt:

  • Einfaches Framework: com.squareup.retrofit2: Converter-Simpleframework

Warum also nachrüsten??

Die Entwicklung einer eigenen typsicheren HTTP-Bibliothek als Schnittstelle zu einer REST-API kann sehr schwierig sein: Sie müssen viele Aspekte behandeln, z. B. das Herstellen von Verbindungen, Zwischenspeichern, Wiederherstellen fehlgeschlagener Anforderungen, Threading, Antwortanalyse, Fehlerbehandlung und vieles mehr. Retrofit hingegen ist eine gut geplante, dokumentierte und getestete Bibliothek, die Ihnen viel kostbare Zeit und Kopfschmerzen erspart.

In diesem Lernprogramm werde ich erklären, wie Retrofit 2 zum Bearbeiten von Netzwerkanforderungen verwendet wird, indem eine einfache Anwendung erstellt wird, die ausgeführt wird POST Anfragen, STELLEN Anfragen (zur Aktualisierung von Entitäten) und LÖSCHEN Anfragen. Ich zeige Ihnen auch, wie Sie RxJava integrieren und Anfragen abbrechen können. Wir werden die von JSONPlaceholder bereitgestellte API verwenden. Hierbei handelt es sich um eine gefälschte Online-REST-API zum Testen und Prototyping.

Sehen Sie sich meinen vorherigen Beitrag "Erste Schritte mit Retrofit 2 HTTP-Client" an, um zu erfahren, wie er ausgeführt wird ERHALTEN Anfragen und wie man Retrofit in RxJava integriert. 

1. Erstellen Sie ein Android Studio-Projekt

Starten Sie Android Studio und erstellen Sie ein neues Projekt mit einer leeren Aktivität Hauptaktivität.

2. Abhängigkeiten deklarieren

Deklarieren Sie nach dem Erstellen eines neuen Projekts die folgenden Abhängigkeiten in Ihrem build.gradle. Zu den Abhängigkeiten zählen die Retrofit-Bibliothek und auch Googles Gson-Bibliothek zum Konvertieren von JSON in POJO (einfache alte Java-Objekte) sowie die Retrofit-Gson-Integration. 

// Retrofit kompilieren 'com.squareup.retrofit2: retrofit: 2.1.0' // JSON-Analyse kompilieren 'com.google.code.gson: gson: 2.6.1' compile 'com.squareup.retrofit2: converter-gson: 2.1 .0 '

Stellen Sie sicher, dass Sie Ihr Projekt synchronisieren, nachdem Sie die Abhängigkeiten hinzugefügt haben. 

3. Internet-Berechtigung hinzufügen

Um Netzwerkoperationen durchzuführen, müssen wir die INTERNET Erlaubnis im Anwendungsmanifest: AndroidManifest.xml.

           

4. Modelle automatisch generieren

Wir werden Modelle automatisch aus den JSON-Antwortdaten erstellen, indem wir ein sehr nützliches Werkzeug einsetzen: jsonschema2pojo. Wir möchten eine machen POST request (neue Ressource erstellen) an die API. Bevor wir diese Anfrage ausführen, müssen wir jedoch die JSON-Antwort kennen, die wir erwarten sollten, wenn sie erfolgreich ausgeführt wird, damit Retrofit die JSON-Antwort parsen und sie in Java-Objekte deserialisieren kann. Laut der API senden wir folgende Daten in a POST anfordern:

Daten: title: 'foo', body: 'bar', userId: 1

Wir sollten die folgende Antwort erhalten:

"title": "foo", "body": "bar", "userId": 1, "id": 101

Ordnen Sie die JSON-Daten Java zu 

Kopieren Sie die Beispielantwortdaten aus dem vorherigen Abschnitt. Besuchen Sie nun jsonschema2pojo und fügen Sie die JSON-Antwort in das Eingabefeld ein. Wählen Sie den Quellentyp aus JSON, Anmerkungsstil von Gson, deaktivieren Zusätzliche Eigenschaften zulassen, und ändern Sie den Klassennamen aus Beispiel zu Post

Klicken Sie dann auf Vorschau Schaltfläche, um die Java-Objekte zu generieren. 

Sie fragen sich vielleicht, was das ist @ SerializedName und @Entlarven Anmerkungen in diesem generierten Code! Keine Sorge, ich erkläre alles!

Das @ SerializedName Anmerkung, damit Gson die JSON-Schlüssel Java-Objektfeldern zuordnen kann.

@SerializedName ("userId") @Expose private Integer userId;

In diesem Fall der JSON-Schlüssel Benutzeridentifikation wird dem Klassenfeld zugeordnet Benutzeridentifikation. Beachten Sie jedoch, dass es nicht dasselbe ist, da sie gleich sind @ SerializedName Anmerkung auf dem Feld, da Gson es automatisch für uns zuordnen wird.

Das @Entlarven Die Anmerkung weist darauf hin, dass der Klassenmitglied für die JSON-Serialisierung oder Deserialisierung verfügbar gemacht werden sollte. 

Importieren Sie Datenmodelle in Android Studio

Kommen wir nun zu Android Studio zurück. Erstellen Sie ein neues Unterpaket in der Main Paket und benennen Sie es Daten. Erstellen Sie in dem neu erstellten Paket ein anderes Paket und benennen Sie es Modell-. Erstellen Sie in diesem Paket eine neue Java-Klasse und benennen Sie sie Post. Nun kopiere die Post Klasse, die von jsonschema2pojo generiert wurde, und fügte sie in die Post Klasse, die Sie erstellt haben. 

Paket com.chikeandroid.retrofittutorial2.data.model; import com.google.gson.annotations.Expose; importieren Sie com.google.gson.annotations.SerializedName; öffentliche Klasse Post @SerializedName ("title") @Expose private String title; @SerializedName ("body") @Expose private String body; @SerializedName ("userId") @Expose private Integer userId; @ SerializedName ("id") @Expose private Integer-ID; public String getTitle () return title;  public void setTitle (String title) this.title = title;  public String getBody () return body;  public void setBody (String body) this.body = body;  public Integer getUserId () return userId;  public void setUserId (Integer userId) this.userId = userId;  public Integer getId () return id;  public void setId (Integer-ID) this.id = id;  @Override public String toString () return "Post " + "title = '" + title +' \ "+", + body + "\" + ", userId =" + userId + ", / posts") @FormUrlEncoded Call savePost (@Field ("title") Zeichenfolge title, @Field ("body") Zeichenfolge body, @Field ("userId") long userId); 

Mit Blick auf die APIService Klasse haben wir eine Methode namens savePost (). Auf der Methode steht die @POST Anmerkung, die angibt, dass wir a ausführen möchten POST request, wenn diese Methode aufgerufen wird. Der Argumentwert für die @POST Annotation ist der Endpunkt / Beiträge. Die vollständige URL lautet also http://jsonplaceholder.typicode.com/posts. 

Okay, was ist mit dem @FormUrlEncoded? Dies zeigt an, dass für die Anforderung der MIME-Typ (ein Headerfeld, das das Format des Hauptteils einer HTTP-Anforderung oder -Antwort angibt) festgelegt ist application / x-www-form-urlencoded und außerdem, dass seine Feldnamen und -werte UTF-8-codiert sind, bevor sie URI-codiert werden. Das @Field ("Schlüssel") Die Anmerkung mit dem Parameternamen sollte mit dem Namen übereinstimmen, den die API erwartet. Retrofit konvertiert die Werte implizit mit Hilfe von Strings String.valueOf (Objekt), und die Zeichenfolgen werden dann über eine URL-codiert. Null Werte werden ignoriert. 

Zum Beispiel anrufen APIService.savePost ("Mein Besuch in Lagos", "Ich besuchte…", 2) ergibt einen Anfragekörper von title = Mein + Besuch + An + Lagos & body = Ich + besuchte… & userId = 2.

Verwendung der @Karosserie Anmerkung

Wir können auch die verwenden @Karosserie Anmerkung zu einem Servicemethodenparameter, anstatt einen Anfrage-Body im Formularstil mit einer Anzahl einzelner Felder anzugeben. Das Objekt wird mit der serialisiert Nachrüstung Beispiel Konverter während der Erstellung angegeben. Dies wird nur verwendet, wenn entweder a POST oder STELLEN Operation. 

@POST ("/ posts") @FormUrlEncoded Call savePost (@Body Post Post);

7. Erstellen der API-Dienstprogramme

Wir werden eine Utility-Klasse erstellen. Erstellen Sie also eine Klasse in Daten.Remote und nennen Sie es ApiUtils. Diese Klasse hat die Basis-URL als statische Variable und stellt auch die APIService Schnittstelle von mit einem getAPIService () statische Methode für den Rest unserer Anwendung.

Paket com.chikeandroid.retrofittutorial2.data.remote; public class ApiUtils private ApiUtils ()  public static final Zeichenfolge BASE_URL = "http://jsonplaceholder.typicode.com/"; public static APIService getAPIService () return RetrofitClient.getClient (BASE_URL) .create (APIService.class); 

Stellen Sie sicher, dass Sie die Basis-URL mit einem /

8. Layout erstellen

Die Datei activity_main.xml ist das Layout für unsere Hauptaktivität. Dieses Layout enthält ein Textbearbeitungsfeld für den Titel des Beitrags und ein weiteres für den Hauptteil des Beitrags. Es enthält auch eine Schaltfläche zum Senden des Beitrags an die API. 

     

9. Ausführen der POST-Anforderung

In dem onCreate () Methode in Hauptaktivität, wir initialisieren eine Instanz von APIService Schnittstelle (Zeile 14). Wir initialisieren auch die Text bearbeiten Felder und einen Senden-Button, der die sendPost () Methode beim Anklicken (Zeile 22).

private TextView mResponseTv; privater APIService mAPIService; @Override protected void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); final EditText titleEt = (EditText) findViewById (R.id.et_title); final EditText bodyEt = (EditText) findViewById (R.id.et_body); Button submitBtn = (Button) findViewById (R.id.btn_submit); mResponseTv = (TextView) findViewById (R.id.tv_response); mAPIService = ApiUtils.getAPIService (); submitBtn.setOnClickListener (neuer View.OnClickListener () @Override public void onClick (Ansichtsansicht) String title = titleEt.getText (). toString (). trim (); String body = bodyEt.getText (). toString () .trim (); if (! TextUtils.isEmpty (title) &&! TextUtils.isEmpty (body)) sendPost (title, body);); 

In dem sendPost (String, String) Methode in der Hauptaktivität Klasse, haben wir den Titel und den Hauptteil des Beitrags dieser Methode übergeben. Diese Methode wird als API-Service-Interface-Methode bezeichnet savePost (String, String) dessen Aufgabe ist es, eine POST Fordern Sie an, den Titel und den Hauptteil an die API zu senden. Das showResponse (String-Antwort) Methode zeigt die Antwort auf dem Bildschirm.

public void sendPost (String title, String body) mAPIService.savePost (title, body, 1) .enqueue (neuer Rückruf() @Override public void onResponse (Aufruf anrufen, antworten Antwort) if (response.isSuccessful ()) showResponse (response.body (). toString ()); Log.i (TAG, "Beitrag an API übermittelt".) + Response.body (). ToString ());  @Override public void onFailure (Anrufen call, Throwable t) Log.e (TAG, "Post kann nicht an API übergeben werden."); );  public void showResponse (Zeichenfolgeantwort) if (mResponseTv.getVisibility () == View.GONE) mResponseTv.setVisibility (View.VISIBLE);  mResponseTv.setText (Antwort); 

Unsere APIService Beispiel mAPIService Methode savePost (String, String) wird ein zurückkehren Anruf Instanz, die eine Methode aufgerufen hat Enqueue (Rückruf) Ruf zurück).

Verstehen Enqueue ()

Enqueue () asynchron sendet die Anforderung und benachrichtigt Ihre App mit einem Rückruf, wenn eine Antwort zurückkommt. Da diese Anforderung asynchron ist, behandelt Retrofit die Ausführung in einem Hintergrundthread, sodass der Haupt-UI-Thread nicht blockiert oder gestört wird. 

Um die Enqueue () Methode müssen Sie zwei Callback-Methoden implementieren: onResponse () und onFailure (). Nur eine dieser Methoden wird als Antwort auf eine gegebene Anforderung aufgerufen. 

  • onResponse (): für eine empfangene HTTP-Antwort aufgerufen. Diese Methode wird für eine Antwort aufgerufen, die auch dann korrekt verarbeitet werden kann, wenn der Server eine Fehlernachricht zurückgibt. Wenn Sie also einen Statuscode von 404 oder 500 erhalten, wird diese Methode trotzdem aufgerufen. Um den Statuscode zu erhalten, damit Sie mit darauf basierenden Situationen umgehen können, können Sie die Methode verwenden Antwortcode(). Sie können auch die ist erfolgreich() Methode, um herauszufinden, ob der Statuscode im Bereich von 200 bis 300 liegt, was den Erfolg anzeigt.
  • onFailure (): Wird aufgerufen, wenn eine Netzwerkausnahme bei der Kommunikation mit dem Server aufgetreten ist oder wenn eine unerwartete Ausnahmebedingung aufgetreten ist, bei der die Anforderung oder die Antwort verarbeitet wurde.

Synchrone Anfragen

Um eine synchrone Anforderung auszuführen, können Sie das verwenden ausführen() Methode in einem Anruf Beispiel. Beachten Sie jedoch, dass synchrone Methoden im Haupt- / UI-Thread alle Benutzeraktionen blockieren. Führen Sie also keine synchronen Methoden im Haupt- / UI-Thread von Android aus! Führen Sie sie stattdessen in einem Hintergrundthread aus.

Verwendung von RxJava 

RxJava wurde standardmäßig in Retrofit 1 integriert, aber in Retrofit 2 müssen Sie einige zusätzliche Abhängigkeiten hinzufügen. Retrofit wird mit einem Standardadapter zur Ausführung geliefert Anruf Instanzen. Sie können den Ausführungsmechanismus von Retrofit so ändern, dass RxJava eingeschlossen wird, indem Sie RxJava einschließen CallAdapter. Dies sind die Schritte:

Schritt 1

Fügen Sie die Abhängigkeiten hinzu.

"io.reactivex: rxjava: 1.1.6" kompilieren "io.reactivex: rxandroid: 1.2.1" compile "com.squareup.retrofit2: adapter-rxjava: 2.1.0" kompilieren

Schritt 2

Fügen Sie den neuen CallAdapter hinzu RxJavaCallAdapterFactory.create () beim Erstellen einer Retrofit-Instanz (Zeile 5).  

public static Retrofit getClient (String baseUrl) if (retrofit == null) retrofit = new Retrofit.Builder () .baseUrl (baseUrl) .addCallAdapterFactory (RxJavaCallAdapterFactory.create ()) .addConverterFactory.) ();  Retrofit zurückgeben; 

Schritt 3

Aktualisieren Sie die APIService savePost (String title, String body, String userId) Methode, um ein Observable zu werden. 

@POST ("/ posts") @FormUrlEncoded Observable savePost (@Field ("title") Zeichenfolge title, @Field ("body") Zeichenfolge body, @Field ("userId") long userId);

Schritt 4

Bei der Anfrage reagiert unser anonymer Teilnehmer auf den beobachtbaren Datenstrom, der in unserem Fall Ereignisse auslöst Post. Das onNext Die Methode wird dann aufgerufen, wenn unser Abonnent ein Ereignis empfängt, das dann an unseren übergeben wird showResponse (String-Antwort) Methode. 

public void sendPost (String title, String body) // RxJava mAPIService.savePost (title, body, 1) .subscribeOn (Schedulers.io ()). observOn (AndroidSchedulers.mainThread ()) .subscribe (neuer Abonnent)() @Override public void onCompleted ()  @Override public void onError (Throwable)  @Override public void onNext (Beitrag posten) showResponse (post.toString ()); ); 

Weitere Informationen zu RxJava und RxAndroid finden Sie unter Erste Schritte mit ReactiveX auf Android von Ashraff Hathibelagal. 

10. Testen der App

An diesem Punkt können Sie die App ausführen und auf die Schaltfläche "Senden" klicken, wenn Sie einen Titel und einen Text eingegeben haben. Die Antwort von der API wird unter der Schaltfläche "Senden" angezeigt. 

11. Ausführen einer PUT-Anforderung

Nun, da wir wissen, wie man eine ausführt POST Bitte, lassen Sie uns sehen, wie wir ein ausführen können STELLEN anfordern, welche Entitäten aktualisiert. Fügen Sie der folgenden neue Methode hinzu APIService Klasse. 

@PUT ("/ posts / id") @FormUrlEncoded Aufruf updatePost (@Path ("id") long id, @Field ("title") Zeichenfolge title, @Field ("body") String body, @Field ("userId") long userId);

Um einen Beitrag aus der API zu aktualisieren, haben wir den Endpunkt / posts / id mit Ich würde Platzhalter für die ID des Beitrags, den wir aktualisieren möchten. Das @Pfad Anmerkung ist die benannte Ersetzung in einem URL-Pfadsegment Ich würde. Beachten Sie, dass Werte mithilfe von in String konvertiert werden String.valueOf (Objekt) und URL-kodiert. Wenn der Wert bereits codiert ist, können Sie die URL-Codierung wie folgt deaktivieren: @Path (value = "name", encoded = true)

12. Eine DELETE-Anfrage ausführen

Mal sehen, wie man eine ausführt LÖSCHEN anfordern. Bei Verwendung der JSONPlaceholder-API zum Löschen einer Post-Ressource ist der erforderliche Endpunkt erforderlich / posts / id mit der HTTP-Methode LÖSCHEN. Zurück zu unserem APIService Schnittstelle müssen wir nur die Methode einschließen Beitrag löschen() das wird es ausführen. Wir übergeben die ID des Beitrags an die Methode und werden im URL-Pfadsegment ersetzt Ich würde.

@ DELETE ("/ posts / id") Aufruf deletePost (@Path ("id") lange id);

13. Eine Anfrage stornieren

Angenommen, Sie möchten Ihren Benutzern die Möglichkeit geben, eine Anfrage abzubrechen oder abzubrechen. Dies ist in Retrofit sehr einfach durchzuführen. Die Nachrüstung Anruf Klasse hat eine Methode aufgerufen stornieren() das wird genau das tun (Zeile 32 unten). Diese Methode löst das aus onFailure () Methode im Rückruf. 

Diese Methode kann beispielsweise aufgerufen werden, wenn keine Internetverbindung besteht oder wenn eine unerwartete Ausnahmebedingung beim Erstellen der Anforderung oder beim Bearbeiten der Antwort aufgetreten ist. Um zu wissen, ob die Anfrage abgebrochen wurde, verwenden Sie die Methode ist storniert() in dem Anruf Klasse (Zeile 20). 

privater Anruf mCall;… public sendPost (String title, String body) mCall = mAPIService.savePost (title, body, 1); mCall.enqueue (neuer Rückruf() @Override public void onResponse (Aufruf anrufen, antworten Antwort) if (response.isSuccessful ()) showResponse (response.body (). toString ()); Log.i (TAG, "Beitrag an API übermittelt".) + Response.body (). ToString ());  @Override public void onFailure (Anrufen call, Throwable t) if (call.isCanceled ()) Log.e (TAG, "Anforderung wurde abgebrochen");  else Log.e (TAG, "Post kann nicht an API übermittelt werden.");  showErrorMessage (); );  public void cancelRequest () mCall.cancel (); 

Fazit

In diesem Lernprogramm haben Sie mehr über Retrofit erfahren: Warum sollten Sie es verwenden und wie Sie es in Ihr Projekt integrieren, um es auszuführen POSTSTELLENLÖSCHEN und Anfragen stornieren. Sie haben auch gelernt, wie Sie RxJava damit integrieren. In meinem nächsten Beitrag mit Retrofit zeige ich Ihnen, wie Sie Dateien hochladen. 

Weitere Informationen zu Retrofit finden Sie in der offiziellen Dokumentation. Bei Envato Tuts finden Sie einige unserer anderen Tutorials und Kurse zur Android-Entwicklung+!

  • Animieren Sie Ihre Android App

    Animationen sind zu einem wichtigen Bestandteil der Android-Benutzererfahrung geworden. Dezente, gut gemachte Animationen werden im gesamten Android-Betriebssystem verwendet und können…
    Ashraff Hathibelagal
    Mobile Entwicklung
  • Praktische Parallelität auf Android mit HaMeR

    In diesem Tutorial werden wir das HaMeR-Framework (Handler, Message and Runnable), eines der leistungsfähigsten Parallelitätsmodelle für Android, kennenlernen. Mit einer…
    Tin Megali
    Android SDK
  • Codierung funktionaler Android-Apps in Kotlin: Erste Schritte

    Sie haben positive Dinge über die Kotlin-Sprache für Android-Apps gehört und möchten es selbst ausprobieren? Finden Sie heraus, wie Sie die Codierung in diesem neuen Programm einrichten und starten können…
    Jessica Thornsby
    Android Studio
  • Migrieren Sie eine Android-App zu Material Design

    Vor Jahren, als Android noch ein aufstrebendes mobiles Betriebssystem war, war es für seine hässliche Benutzeroberfläche ziemlich berüchtigt. Weil es kein Design gab…
    Ashraff Hathibelagal
    Android