簡介
新增 Retrofit 依附元件
開啟模組層級 Gradle 檔案 build.gradle (Module: MarsPhots.app)。
在 dependencies 區段中,為 Retrofit 程式庫新增以下幾行:
// Retrofit
implementation "com.squareup.retrofit2:retrofit:2.9.0"
// Retrofit with Scalar Converter
implementation "com.squareup.retrofit2:converter-scalars:2.9.0"
若要搭配 Moshi 將 JSON 字串轉為 Kotlin 物件,則將上述改為:
// Moshi
implementation 'com.squareup.moshi:moshi-kotlin:1.13.0'
用例
使用 Scalars (將網路服務資料視為 String)
在 MarsApiService.kt 中:
private const val BASE_URL = "https://android-kotlin-fun-mars-server.appspot.com/" //網路服務基準URI
private val retrofit = Retrofit.Builder() //新增 Retrofit 建構工具
.addConverterFactory(ScalarsConverterFactory.create()) //添加支援字串和其他原始類型的轉換工廠 (注意此處使用的是Scalars,需搭配其依附元件使用)
.baseUrl(BASE_URL) //新增網路服務的基準 URI
.build() //建立 Retrofit 物件
interface MarsApiService {
@GET("photos") //向 Retrofit 表明此為 GET 要求,並指定該網路服務方法的端點/photos
suspend fun getPhotos(): String
}
object MarsApi {
// 使用 retrofit.create() 方法初始化 retrofitService 變數
val retrofitService: MarsApiService by lazy { retrofit.create(MarsApiService::class.java) }
}
在 OverviewViewModel.kt 的 class OverviewViewModel 中 :
private fun getMarsPhotos() {
_status.value = "Set the Mars API status response here!"
viewModelScope.launch {
try{
val listResult = MarsApi.retrofitService.getPhotos()
_status.value = listResult //顯示收到的後端伺服器結果
} catch (e: Exception) {
_status.value = "Failure: ${e.message}"
}
}
}
使用 Moshi (將 JSON 轉為 Kotlin 物件)
在 MarsPhoto .kt 中:
/*
Moshi 剖析 JSON 時,會根據名稱比對鍵,並在資料物件中填入適當的值。
*/
data class MarsPhoto (
val id: String,
@Json(name = "img_src") val imgSrcUrl: String
)
在 MarsApiService.kt 中:
private const val BASE_URL = "https://android-kotlin-fun-mars-server.appspot.com/" //網路服務基準URI
private val moshi = Moshi.Builder()
.add(KotlinJsonAdapterFactory())
.build()
private val retrofit = Retrofit.Builder() //新增 Retrofit 建構工具
.addConverterFactory(MoshiConverterFactory.create(moshi)) //添加支援字串和其他原始類型的轉換工廠
.baseUrl(BASE_URL) //新增網路服務的基準 URI
.build() //建立 Retrofit 物件
interface MarsApiService {
@GET("photos") //向 Retrofit 表明此為 GET 要求,並指定該網路服務方法的端點/photos
suspend fun getPhotos(): List<MarsPhoto>
}
object MarsApi {
// 使用 retrofit.create() 方法初始化 retrofitService 變數
val retrofitService: MarsApiService by lazy { retrofit.create(MarsApiService::class.java) }
}
關於最後一句:
- lazy : 預先指定值的 lateinit (參考 Kotlin lateinit vs lazy. 如果不想一開始就初始化property,有兩個修飾可以使用。 | by Chris Evans | Medium ),可傳入一 lambda,限用於 val。
- ::class.java : ChatGPT 說 「在 Kotlin 中,::class 語法用於獲取 Kotlin 類(class)的參考。然而,當你使用 Retrofit 這樣的庫時,它通常期望你提供 Java 類的參考,而不是 Kotlin 類的參考。 在 Kotlin 中,::class 返回的是 Kotlin KClass 對象,而不是 Java 的 Class 對象。為了取得 Java 的 Class 對象,你需要使用 .java 屬性。」
在 OverviewViewModel.kt 的 class OverviewViewModel 中 :
class OverviewViewModel : ViewModel() {
// The internal MutableLiveData that stores the status of the most recent request
private val _status = MutableLiveData<String>()
// The external immutable LiveData for the request status
val status: LiveData<String> = _status
/**
* Call getMarsPhotos() on init so we can display status immediately.
*/
init {
getMarsPhotos()
}
/**
* Gets Mars photos information from the Mars API Retrofit service and updates the
* [MarsPhoto] [List] [LiveData].
*/
private fun getMarsPhotos() {
_status.value = "Set the Mars API status response here!"
viewModelScope.launch {
try{
val listResult = MarsApi.retrofitService.getPhotos()
_status.value = "Success: ${listResult.size} Mars photos retrieved" //顯示收到的後端伺服器結果
} catch (e: Exception) {
_status.value = "Failure: ${e.message}"
}
}
}
}
在 viewmodel 建立後呼叫getMarsPhotos()
0 comments:
張貼留言