Android Kotlin 使用 Retrofit 套件呼叫 API

取得網路權限

在 AndroidManifest.xml 宣告需要使用到網路權限:
    
<uses-permission android:name="android.permission.INTERNET" />
    

加入依賴套件

在 build.gradle(Module :app) 中加入 Retrofit 套件,和 gson 解析回應內容的轉換套件
    
dependencies {
    implementation "com.squareup.retrofit2:retrofit:2.9.0"
    implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
}
    

讀取資料

建立回應實體

本次讀取的範例資料是 JSON Placeholder 服務的測試資料,連結是 https://jsonplaceholder.typicode.com/posts ,使用 Http Get ,不用提供參數,範例回應內容如下:
    
[
  {
    "userId": 1,
    "id": 1,
    "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
    "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
  },
  {
    "userId": 1,
    "id": 2,
    "title": "qui est esse",
    "body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla"
  }
]
    

先依據回應內容建立對應的資料類別:
    
import com.google.gson.annotations.SerializedName

data class Post(
    @SerializedName("userId") val userId: Int,
    @SerializedName("id") val id: Int,
    @SerializedName("title") val title: String,
    @SerializedName("body") val body: String
)
    

SerializedName 是 gson 提供的註解(annotations),用來將 json 的屬性和類別的屬性對應,如果本身屬性名稱一樣就可以省略,是名稱不同的時候才需要使用 SerializedName 映射屬性。

建立服務

建立 JsonPlaceholderService 服務類別,通常會建立一個 network package 放在這裡面。此 Service 是用來對應 api
    
import retrofit2.Call
import retrofit2.http.GET

interface JsonPlaceholderService {

    @GET("posts")
    fun getPosts(): Call<List<Post>>
}
    

建立請求服務
    
val retrofit = Retrofit.Builder()
    .baseUrl("https://jsonplaceholder.typicode.com/") // API 網址
    .addConverterFactory(GsonConverterFactory.create()) // 使用 Gson 解析回應內容
    .build()

val jsonPlaceholderService = retrofit.create(JsonPlaceholderService::class.java)
    

呼叫 API

實際呼叫 API:
    
        jsonPlaceholderService.getPosts().enqueue(object : retrofit2.Callback<List<Post>> {
            override fun onResponse(
                call: retrofit2.Call<List<Post>>,
                response: retrofit2.Response<List<Post>>
            ) {
                val posts = response.body() ?: return

                for (post in posts) {
                    Log.i("GetDataButton", "post.id: ${post.id}")
                    Log.i("GetDataButton", "post.userId: ${post.userId}")
                    Log.i("GetDataButton", "post.title: ${post.title}")
                    Log.i("GetDataButton", "post.body: ${post.body}")
                    Log.i("GetDataButton", "--------")
                }
            }

            override fun onFailure(call: retrofit2.Call<List<Post>>, t: Throwable) {
                Log.i("GetDataButton", "onFailure: ")
            }
        })
    

帶入參數

上面的連結是 https://jsonplaceholder.typicode.com/posts ,如果要在後面帶入參數,變成 https://jsonplaceholder.typicode.com/posts/1 ,則可以使用下列方式執行:
    
import retrofit2.Call
import retrofit2.http.GET
import retrofit2.http.Path

interface JsonPlaceholderService {

    @GET("posts")
    fun getPosts(): Call<List<Post>>
    
    @GET("posts/{id}")
    fun getPostById(@Path("id") postId: Int): Call<Post>
}
    

    
        jsonPlaceholderService.getPostById(1).enqueue(object :retrofit2.Callback<Post>{
            override fun onResponse(call: retrofit2.Call<Post>, response: retrofit2.Response<Post>) {
                val post = response.body() ?: return

                Log.i("GetDataButton", "post.id: ${post.id}")
                Log.i("GetDataButton", "post.userId: ${post.userId}")
                Log.i("GetDataButton", "post.title: ${post.title}")
                Log.i("GetDataButton", "post.body: ${post.body}")
                Log.i("GetDataButton", "--------")
            }

            override fun onFailure(call: retrofit2.Call<Post>, t: Throwable) {
                Log.i("GetDataButton", "onFailure: ")
            }
        })
    



參考資料:
Retrofit

留言