iT邦幫忙

2022 iThome 鐵人賽

DAY 11
0
Mobile Development

【Kotlin Notes And JetPack】Build an App系列 第 11

Day 11. 【Corountines】Coroutines 串接 API

  • 分享至 

  • xImage
  •  

這篇會加入新成員,也是就是我們這次會用到 retrofit 來進行串接 API 以及 Moshi 來解析資料,在實作之前會先來講講什麼是 retrofit,以下如有解釋不清或是描述錯誤的地方還請大家多多指教:

什麼?

| Retrofit

Http 請求的第三方套件,使用 RESTful API 的設計,由 square 開發與維護,最低使用條件為 Java 8+ 和 Android API 21+,在 2.6.0 以前的版本,必須透過 Call Adapter 並搭配 Deferred 的型別來使用 coroutine 像是以下範例,但 2.6.0 以後的版本我們可以直接使用 suspend function(下面實作會提到):

...
@GET("path")
fun getHomeList(): Deferred<HotsProperty>
...

// retrofit 
private val retrofit = Retrofit.Builder()
    .addConverterFactory(MoshiConverterFactory.create(moshi))
    .addCallAdapterFactory(CoroutineCallAdapterFactory())
    .baseUrl(BASE_URL)
    .client(client)
    .build()

| Moshi

一樣是由 square 所開發的 Json parser 的 library,目前依舊是 Gson 使用人數較多,星星數也較多,雖然 Moshi 是由 Kotlin 和 Java 撰寫,但還是需要依據專案需求選擇較符合的 parser 或是 custom type adapter。

如何?

| Set up

加入 Retrofit, Moshi, Coroutine 的 library。

implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-moshi:2.9.0'
implementation 'com.squareup.moshi:moshi-kotlin:1.14.0'
implementation 'com.squareup.okhttp3:logging-interceptor:4.10.0'

// coroutine
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4'

在 AndroidManifest 加入 internet 的 permission。

<uses-permission android:name=”android.permission.INTERNET”></uses-permission>

| 創建 Service 與 Retrofit

建立請求 API 的 Service 並創建 Retrofit:

  • Service
interface WeathbyService {
    @GET("forecast.json")
    suspend fun getForecast(
        @Query("key") key: String = KEY,
        @Query("q") query: String,
        @Query("days") days: Int = 7,
        @Query("aqi") airQuality: String = "no"
    ): Response<ForecastResponse>

    @GET("search.json")
    suspend fun getForecastSearch(
        @Query("key") key: String = KEY,
        @Query("q") query: String
    ): Response<ForecastResponse>
}
  • Retrofit
object WeathbyRetrofit {
    private const val BASE_URL = "https://api.weatherapi.com/v1/"

    private val moshi = Moshi.Builder()
        .add(KotlinJsonAdapterFactory())
        .build()

    private val client = OkHttpClient.Builder()
        .addInterceptor(HttpLoggingInterceptor().apply { 
            level = HttpLoggingInterceptor.Level.BODY 
        }).build()

    fun makeRetrofitService(): WeathbyService {
        return Retrofit.Builder()
            .addConverterFactory(MoshiConverterFactory.create(moshi))
			.baseUrl(BASE_URL)
            .client(client)
            .build().create(WeathbyService::class.java)
    }
}

| 加入 @Json

data class ForecastResponse(
    @Json(name = "location") val location: Location,
    @Json(name = "current") val current: CurrentForecast,
    @Json(name = "forecast") val forecast: Forecast
)

| 執行

先在 MainActivity 執行,等到介紹 ViewModel 時會將打資料邏輯放到 ViewModel 中:

fun getCurrentForecast() {
    val service = WeathbyRetrofit.makeRetrofitService()
    CoroutineScope(Dispatchers.IO).launch {
         withContext(Dispatchers.Main) {
            runCatching {
                service.getForecast(query = "London")
            }.onSuccess {
                Log.i("success", "onCreate: $it")
            }.onFailure {
                Log.i("fail", "onCreate: $it")
            }
        }
    }
}

| Run

build 完 app 就可以在 logcat 上看到 API request 和 response 的狀態了:
https://ithelp.ithome.com.tw/upload/images/20220924/201511451I88t4tpwv.png

Reference

Kotlin Coroutines and Retrofit
Retrofit with Kotlin Coroutine in Android


上一篇
Day 10.【Corountines】Coroutines Basic
下一篇
Day 12. Android Jetpack 是什麼 ?
系列文
【Kotlin Notes And JetPack】Build an App30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言