接著,這篇文章將介紹使用Retrofit與Coroutines來做網路API的處理。
https://github.com/scobin/Android_WeatherApp/tree/feature/weatherData
為了加入Coroutines與Retrofit工具庫,請先開啟app資料夾下的build.gradle文件,並將以下的程式碼添入dependencies內。 (請小心注意版本號,以免程式執行中出現錯誤!)
dependencies {
...
// Coroutines
def coroutines_version = '1.3.0'
implementation "org.jetbrains.kotlinx:kotlinx-outins-core:$coroutines_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"
// Retrofit2
implementation 'com.squareup.retrofit2:retrofit:2.6.0'
implementation 'com.squareup.retrofit2:converter-gson:2.6.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.8.1'
}
<manifest ...>
<uses-permission android:name="android.permission.INTERNET"/>
<application ...>
...
</application>
</manifest>
手動生成WeatherAPIService.kt文件,內容如下方程式所示。 設置Retrofit工具,並定義了getForecast函數來取得網路資料。
為了方便觀察網路通訊的狀況,okHttpClient的設定中使用logging-interceptor。
const val BASE_URL = "https://api.openweathermap.org/"
interface WeatherAPIService {
@GET("data/2.5/forecast")
suspend fun loadWeather(cityId: String): WeatherResponse? {
return runCatching { weatherAPIService.getForecast(cityId) }.fold(
onSuccess = {
if (it.isSuccessful) {
var body = it.body()
if (body == null || body.cod != "200") {
return null
}
return body
} else {
return null
}
},
onFailure = { null }
)
}
companion object {
operator fun invoke(): WeatherAPIService {
val requestInterceptor = Interceptor { chain ->
val url = chain.request()
.url()
.newBuilder()
.addQueryParameter("appid", APP_ID)
.addQueryParameter("mode", "json")
.build()
val request = chain.request()
.newBuilder()
.url(url)
.build()
return@Interceptor chain.proceed(request)
}
val okHttpClient = OkHttpClient.Builder()
.addInterceptor(requestInterceptor)
// logging settings
.addInterceptor(HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
})
.build()
return Retrofit.Builder()
.client(okHttpClient)
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(WeatherAPIService::class.java)
}
}
}
參考資料:Kotlin-runCatching
val weatherAPIService = WeatherAPIService()
GlobalScope.launch() {
val response = weatherAPIService.getForecast("7280291")
// 畫面顯示結果
testText.text = response.toString()
}