Android Retrofit Tutorial und Beispiele.

Was ist Retrofit? Nun, Retrofit ist ein Typesafe HTTP Client, der zuerst von Square Inc. entwickelt wurde.

Die Aufgabe von Retrofit ist es, Ihre HTTP-API in eine Java-Schnittstelle zu verwandeln:

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

In diesem Kurs werden wir uns Retrofit und Retrofit-Beispiele in Bezug auf die Android-Entwicklung ansehen. Wir werden sehen, wie wir es verwenden können, um auf einfache Weise mit Webservices über HTTP zu kommunizieren.

Was sind die Voraussetzungen für Retrofit?

Retrofit hat sehr großzügige Anforderungen:

  1. Java 7 und höher.
  2. Android 2.3 und höher.

Wie kann ich Retrofit installieren?

Retrofit ist eine HTTP-Client-Bibliothek eines Drittanbieters für Android und Java. Daher muss sie in Ihrem Projekt installiert werden.

Wenn Sie nach einer Netzwerkklasse suchen, die standardmäßig im Android-Framework enthalten ist, dann schauen Sie sich HttpURLConnection an.

Ansonsten kann Retrofit auf drei Arten installiert werden:

1. Als jar.

Grundsätzlich laden Sie das Retrofit-Jar herunter und fügen es als Jar-Bibliothek zu Ihrem Android Studio hinzu.

Zum Beispiel habe ich Retrofit 2.4.0 verwendet, das man von hier herunterladen kann.

Andernfalls können Sie die neueste Version hier überprüfen.

2. Über Maven

Maven, auch bekannt als Apache Maven, ist ein Build-Automatisierungswerkzeug, das hauptsächlich für Java-Projekte verwendet wird.

Dadurch hat es zwei Hauptaufgaben:

  1. Beschreiben, wie ein Projekt gebaut wird.
  2. Die Beschreibung der Abhängigkeiten des Projekts.

Nun, wir können Retrofit als unsere Abhängigkeit in einem Java-Projekt beschreiben.

<dependency>
  <groupId>com.squareup.retrofit2</groupId>
  <artifactId>retrofit</artifactId>
  <version>2.4.0</version>
</dependency>

3. Via Gradle

Gradle ist ein Build-System, das von android studio verwendet wird.

Wenn Sie ein Android-Projekt erstellen, stehen die Chancen gut, dass Sie diese Methode zur Installation von Retrofit verwenden werden. Das liegt daran, dass Sie wahrscheinlich [Android Studio] (https://camposha.info/android/android-studio) verwenden, da es die offizielle Entwicklungs-IDE für Android ist. Und Android Studio verwendet das gradle build system.

In diesem Fall müssen Sie zu Ihrer App-Ebene build.gradle gehen und die folgende Anweisung in Ihre Abhängigkeiten DSL hinzufügen:

implementation 'com.squareup.retrofit2:retrofit:2.4.0'

Common Retrofit Interfaces,Classes and Methods.

1. Aufruf

Dies ist eine Retrofit-Schnittstelle, die einen Aufruf einer Retrofit-Methode darstellt, die eine Anfrage an einen Webserver sendet und eine Antwort zurückgibt. Wie der Name schon sagt, stellt sie im Grunde einen HTTP-Aufruf dar, den Sie tätigen.

Jeder Aufruf liefert dann sein eigenes HTTP-Anfrage-Antwort-Paar. Sie können mehrere Aufrufe mit denselben Parametern tätigen. Dazu verwenden Sie jedoch clone. Sie können dies verwenden, um ein Polling zu implementieren oder einen fehlgeschlagenen Aufruf zu wiederholen.

HTTP-Aufrufe können synchron oder asynchron erfolgen. Für synchrone Aufrufe verwenden Sie die Methode execute(). Für asynchrone Aufrufe verwenden Sie die Methode "enqueue()".

Wenn Sie einen Aufruf abbrechen wollen, verwenden Sie die Methode cancel().

Hier ist ihre Definition:

public interface Call<T> extends Cloneable

Beachten Sie, dass in diesem Fall T den Typ eines erfolgreichen Antwortkörpers darstellt.

2. enqueue()

Dies ist eine Methode, die zur Schnittstelle Call<T> gehört. Wir haben darüber gesprochen, dass diese Schnittstelle einen HTTP-Aufruf darstellt, den Sie tätigen.

Und normalerweise kann man entweder einen synchronen oder asynchronen Aufruf oder eine Anfrage machen. Wenn Sie einen asynchronen Aufruf machen wollen, verwenden Sie diese Methode.

Hier ist ihre Definition:

public abstract void enqueue(retrofit2.Callback<T> callback)

Diese Methode sendet dann asynchron Ihre Anfrage und benachrichtigt Callback über die Antwort, falls ein Fehler bei der Kommunikation mit dem Server, der Erstellung der Anfrage oder der Verarbeitung der Antwort auftritt.

Hier ist ein einfaches Anwendungsbeispiel:

        Call<List<Spacecraft>> call = myAPIService.getSpacecrafts();
        call.enqueue(new Callback<List<Spacecraft>>() {

            @Override
            public void onResponse(Call<List<Spacecraft>> call, Response<List<Spacecraft>> response) {
                myProgressBar.setVisibility(View.GONE);
                populateRecyclerView(response.body());
            }
            @Override
            public void onFailure(Call<List<Spacecraft>> call, Throwable throwable) {
                myProgressBar.setVisibility(View.GONE);
                Toast.makeText(MainActivity.this, throwable.getMessage(), Toast.LENGTH_LONG).show();
            }
        });

3. Callback

Dies ist eine Schnittstelle, die Methoden definiert, die für die Übermittlung von Antworten von einem Server oder von Offline-Anfragen verantwortlich sind.

Hier ist ihre Definition:

public interface Callback<T>

Das "T" in der obigen Abbildung steht für einen erfolgreichen Antwortkörpertyp.

Normalerweise wird nur eine einzige Methode als Antwort auf eine bestimmte Anfrage aufgerufen. Diese Methode wird unter Verwendung des Retrofit-Callback-Executors ausgeführt. Wenn Sie keine Methode angeben, werden die folgenden Standardwerte verwendet:

  1. Android: Rückrufe werden auf dem Hauptthread (UI) der Anwendung ausgeführt.
  2. JVM: Rückrufe werden auf dem Hintergrund-Thread ausgeführt, der die Anfrage durchgeführt hat.

Hier ein Anwendungsbeispiel:

new Callback<List<Spacecraft>>() {

            @Override
            public void onResponse(Call<List<Spacecraft>> call, Response<List<Spacecraft>> response) {
                myProgressBar.setVisibility(View.GONE);
                populateRecyclerView(response.body());
            }
            @Override
            public void onFailure(Call<List<Spacecraft>> call, Throwable throwable) {
                myProgressBar.setVisibility(View.GONE);
                Toast.makeText(MainActivity.this, throwable.getMessage(), Toast.LENGTH_LONG).show();
            }
        }

4. Retrofit

Dies ist eine Klasse, die für die Anpassung einer Java-Schnittstelle an HTTP-Aufrufe verantwortlich ist, indem sie Annotationen zu den deklarierten Methoden verwendet, um zu definieren, wie die Anfragen ausgeführt werden.

Hier ist ihre Definition

public final class Retrofit extends Object

Um sie zu verwenden, müssen Sie ihre Instanz erstellen. Dazu verwenden Sie den Builder und übergeben Ihre Schnittstelle an create, um eine Implementierung zu erzeugen. Zum Beispiel:

   Retrofit retrofit = new Retrofit.Builder()
       .baseUrl("https://api.example.com/")
       .addConverterFactory(GsonConverterFactory.create())
       .build();

   MyApi api = retrofit.create(MyApi.class);
   Response<User> user = api.getUser().execute();

Oder ich kann eine einfache Fabrikklasse erstellen, die mir ihre Instanzen zurückgibt:

    static class RetrofitClientInstance {

        private static Retrofit retrofit;
        private static final String BASE_URL = "https://raw.githubusercontent.com/";

        public static Retrofit getRetrofitInstance() {
            if (retrofit == null) {
                retrofit = new Retrofit.Builder()
                        .baseUrl(BASE_URL)
                        .addConverterFactory(GsonConverterFactory.create())
                        .build();
            }
            return retrofit;
        }
    }

Dann verwende ich diese Klasse auf diese Weise:

        MyAPIService myAPIService = RetrofitClientInstance.getRetrofitInstance().create(MyAPIService.class);

Kotlin Android Retrofit Filme Beispiel

In diesem Beispiel wird gezeigt, wie man eine Liste von Filmen von der IMDB-Website abruft und in einer Recycle-Ansicht darstellt. Die Elemente werden über Retrofit abgerufen. Die Bilder werden mit Picasso gerendert.

Hier ist das Demobild:

Schritt 1: Projekt erstellen

Beginnen Sie mit der Erstellung eines leeren Android Studio-Projekts.

Schritt 2: Abhängigkeiten

Zuerst fügen wir Retrofit als Abhängigkeit hinzu, zusammen mit dem Retrofit converter-gson:

    implementation "com.squareup.retrofit2:retrofit:$retrofitVersion"
    implementation "com.squareup.retrofit2:converter-gson:$retrofitConverterGsonVer"

Wir werden auch Abhängigkeiten für RecyclerView und CardView hinzufügen:

    implementation "androidx.recyclerview:recyclerview:$supportVer"
    implementation "androidx.cardview:cardview:$supportVer"

Wir fügen auch eine Abhängigkeit für Picasso, unseren Imageloader, hinzu:

    implementation "com.squareup.picasso:picasso:$picassoVersion"

Schritt 3: Layout entwerfen

Als nächstes werden wir unsere Layouts entwerfen. Wir werden zwei Layouts haben:

(a). list_row.xml

Diese wird in eine einzelne Zeile in unserem Recyclerview aufgeblasen. Wir werden eine Kartenansicht mit Bild und Text haben:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <androidx.cardview.widget.CardView
        android:id="@+id/card_view"
        android:layout_width="match_parent"
        android:layout_height="240dp"
        android:layout_gravity="center"
        android:layout_margin="5dp"
        android:background="#fff"
        card_view:cardCornerRadius="2dp"
        card_view:contentPadding="10dp">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <ProgressBar
                android:id="@+id/progress_bar"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:visibility="gone" />

            <ImageView
                android:id="@+id/image_view_movie"
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="1"
                android:scaleType="fitXY" />

            <TextView
                android:id="@+id/movie_title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:layout_marginStart="10dp"
                android:textColor="@android:color/black"
                android:textSize="18sp"
                android:textStyle="bold" />

        </LinearLayout>

    </androidx.cardview.widget.CardView>

</LinearLayout>

(b). activity_main.xml

In unserem "MainActivity"-Layout fügen wir eine Recycler-Ansicht hinzu, die unsere Liste von Elementen darstellt:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.developers.usingretrofit.MainActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/movie_recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center"
        android:layout_marginEnd="5dp"
        android:layout_marginStart="5dp" />
</LinearLayout>

Schritt 4: Konstanten erstellen

Eine Konstante ist eine Variable, deren Wert sich nicht ändert. Wir werden solche Variablen zum Beispiel für unsere Basis-URL und die Bild-URL in unserem Projekt benötigen. Erstellen Sie eine Datei mit dem Namen Konstanten.kt und fügen Sie den folgenden Code ein:

Constants.kt

class Constants {

    companion object {
        @JvmField
        val BASE_URL = "https://api.themoviedb.org/3/movie/";
        @JvmField
        val IMAGE_BASE_URL = "http://image.tmdb.org/t/p/w185/"
    }

}

Schritt 5: Erstellen von Modellklassen

Wir werden zwei Modellklassen haben:

(a). MovieResult.kt

Dies ist eine Klasse, die einen Aufruf von Filmergebnissen darstellt. Diese Modellklasse wird Eigenschaften wie Seite, Gesamtergebnisse, Gesamtseiten sowie die Liste der Ergebnisse haben:

import com.google.gson.annotations.Expose
import com.google.gson.annotations.SerializedName

data class MovieResult(@SerializedName("page")
                  @Expose
                  var page: Int? = null,
                  @SerializedName("total_results")
                  @Expose
                  var totalResults: Int? = null,
                  @SerializedName("total_pages")
                  @Expose
                  var totalPages: Int? = null,
                  @SerializedName("results")
                  @Expose
                  var results: List<Result>? = null)

(b). Ergebnis.kt

Diese Ergebnisklasse repräsentiert einen einzelnen Film sowie seine Eigenschaften wie Titel, Popularität, Genre-IDs usw:


import com.google.gson.annotations.Expose
import com.google.gson.annotations.SerializedName

data class Result(
        @SerializedName("vote_count")
        @Expose
        var voteCount: Int? = null,
        @SerializedName("id")
        @Expose
        var id: Int? = null,
        @SerializedName("video")
        @Expose
        var video: Boolean? = null,
        @SerializedName("vote_average")
        @Expose
        var voteAverage: Double? = null,
        @SerializedName("title")
        @Expose
        var title: String? = null,
        @SerializedName("popularity")
        @Expose
        var popularity: Double? = null,
        @SerializedName("poster_path")
        @Expose
        var posterPath: String? = null,
        @SerializedName("original_language")
        @Expose
        var originalLanguage: String? = null,
        @SerializedName("original_title")
        @Expose
        var originalTitle: String? = null,
        @SerializedName("genre_ids")
        @Expose
        var genreIds: List<Int>? = null,
        @SerializedName("backdrop_path")
        @Expose
        var backdropPath: String? = null,
        @SerializedName("adult")
        @Expose
        var adult: Boolean? = null,
        @SerializedName("overview")
        @Expose
        var overview: String? = null,
        @SerializedName("release_date")
        @Expose
        var releaseDate: String? = null)

Schritt 6: Erstellen eines API-Dienstes

Dies ist einfach eine Schnittstelle, die eine Methode enthält, die unsere HTTP-Anfrage darstellt:

ApiInterface.kt


import com.developers.usingretrofit.model.MovieResult
import com.developers.usingretrofit.utils.Constants
import retrofit2.Call
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.GET
import retrofit2.http.Query

interface ApiInterface {

    @GET("popular")
    fun getMovies(@Query("api_key") key: String,
                  @Query("page") page: Int): Call<MovieResult>

    companion object Factory {

        fun create(): ApiInterface {

            val retrofit = Retrofit.Builder()
                    .addConverterFactory(GsonConverterFactory.create())
                    .baseUrl(Constants.BASE_URL)
                    .build()

            return retrofit.create(ApiInterface::class.java);

        }

    }

}

Schritt 7: Adapter erstellen

Um unsere Filmliste in unserer Recyclerview zu rendern, benötigen wir einen Adapter. Erstellen Sie einen, indem Sie den RecyclerView.Adapter wie unten gezeigt erweitern:

MovieAdapter.kt

import android.content.Context
import android.net.Uri
import androidx.recyclerview.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.developers.usingretrofit.R
import com.developers.usingretrofit.model.Result
import com.developers.usingretrofit.utils.Constants
import com.squareup.picasso.Callback
import com.squareup.picasso.Picasso
import kotlinx.android.synthetic.main.list_row.view.*

class MovieAdapter(val context: Context, private val resultList: List<Result>?) : RecyclerView.Adapter<MovieAdapter.MyViewHolder>() {

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        holder.bindItems(resultList?.get(position))
    }

    override fun getItemCount(): Int {
        return resultList?.size!!
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        val view = LayoutInflater.from(context).inflate(R.layout.list_row, parent, false)
        return MyViewHolder(view)
    }

    class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

        fun bindItems(result: Result?) {
            itemView.movie_title.text = result?.title
            val posterUri = Uri.parse(Constants.IMAGE_BASE_URL).buildUpon()
                    .appendEncodedPath(result?.posterPath)
                    .build()
            itemView.progress_bar.visibility = View.VISIBLE
            Picasso.with(itemView.context).load(posterUri.toString())
                    .into(itemView.image_view_movie, object : Callback {

                        override fun onError() {
                            //Show Error here
                        }

                        override fun onSuccess() {
                            itemView.progress_bar.visibility = View.GONE
                        }

                    })
        }
    }
}

Schritt 8: MainActivity Code schreiben

Hier ist der vollständige Code für die MainActivity:

import android.content.Context
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
import androidx.recyclerview.widget.GridLayoutManager
import com.developers.usingretrofit.adapter.MovieAdapter
import com.developers.usingretrofit.model.MovieResult
import kotlinx.android.synthetic.main.activity_main.*
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val apiCall = ApiInterface.create()
        apiCall.getMovies(BuildConfig.TV_KEY, 1).enqueue(object : Callback<MovieResult> {
            override fun onFailure(call: Call<MovieResult>?, t: Throwable?) {
                showError(t?.message)
            }

            override fun onResponse(call: Call<MovieResult>?, response: Response<MovieResult>?) {
                val movieResponse = response?.body()
                val resultList = movieResponse?.results
                val layoutManager = GridLayoutManager(applicationContext,2)
                val adapter = MovieAdapter(applicationContext, resultList)
                movie_recycler_view.layoutManager = layoutManager
                movie_recycler_view.adapter = adapter
            }

        })
    }

    private fun showError(message: String?) {
        toast(message.toString())
    }

    fun Context.toast(msg: String) {
        Toast.makeText(applicationContext, msg, Toast.LENGTH_SHORT).show()
    }
}

Run

Kopieren Sie den Code oder laden Sie ihn über den unten stehenden Link herunter, bauen Sie ihn und führen Sie ihn aus.

Referenz

Hier sind die Referenzlinks:

Nummer Link
1. Download Beispiel
2. Folgen Code-Autor
3. Code: Apache 2.0 Lizenz

Categorized in: