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.. ERHALTEN
, POST
, STELLEN
, PATCH
, 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:
com.squareup.retrofit: converter-gson
com.squareup.retrofit: converter-jackson
com.squareup.retrofit: converter-moshi
Für Protokollpuffer unterstützt Retrofit:
com.squareup.retrofit2: converter-protobuf
com.squareup.retrofit2: Konverterdraht
Und für XML Retrofit unterstützt:
com.squareup.retrofit2: Converter-Simpleframework
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.
Starten Sie Android Studio und erstellen Sie ein neues Projekt mit einer leeren Aktivität Hauptaktivität
.
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.
Um Netzwerkoperationen durchzuführen, müssen wir die INTERNET
Erlaubnis im Anwendungsmanifest: AndroidManifest.xml.
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.
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 CallsavePost (@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
.
@Karosserie
AnmerkungWir 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 CallsavePost (@Body Post Post);
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 /
.
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.
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)
.
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.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.
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:
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
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;
Aktualisieren Sie die APIService
savePost (String title, String body, String userId)
Methode, um ein Observable zu werden.
@POST ("/ posts") @FormUrlEncoded ObservablesavePost (@Field ("title") Zeichenfolge title, @Field ("body") Zeichenfolge body, @Field ("userId") long userId);
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.
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.
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 AufrufupdatePost (@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)
.
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") AufrufdeletePost (@Path ("id") lange id);
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 AnrufmCall;… 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 ();
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 POST
, STELLEN
, LÖ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+!