先引入依賴
//這個是google官方擴展的ViewModel庫支持協(xié)程操作
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.1.0'
//kotlin協(xié)程依賴
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.1'
//retrofit2.6以上
implementation 'com.squareup.retrofit2:retrofit:2.6.2'
implementation 'com.squareup.retrofit2:converter-gson:2.6.1'
implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2'
初始化網(wǎng)絡設置
object RetrofitClient {
val BASE_URL = "https://wanandroid.com"
val api by lazy {
val retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(CoroutineCallAdapterFactory.invoke())
.build()
return@lazy retrofit.create(RequestService::class.java)
}
}
interface RequestService {
@GET("wxarticle/chapters/json")
suspend fun getData(): ArticleData
}
data class ArticleData(
val `data`: List<Data>?,
val errorCode: Int,
val errorMsg: String?
)
data class Data(
val courseId: Int,
val id: Int,
val name: String,
val order: Int,
val parentChapterId: Int,
val userControlSetTop: Boolean,
val visible: Int
)
class CommViewModel : ViewModel() {
fun getData() {
viewModelScope.launch {
val data = RetrofitClient.api.getData1()
Log.i(TAG, ": ${data.data}")
}
}
override fun onCleared() {
super.onCleared()
//ViewModel銷毀的時候拇泛,取消所有的協(xié)程
viewModelScope.coroutineContext.cancelChildren()
}
companion object {
val TAG: String = CommViewModel::class.java.simpleName
}
}
在網(wǎng)上看了很多的博客滨巴,大部分都是如上這樣子介紹一些比較簡單的使用,但是如果要深入一點俺叭,比如網(wǎng)絡請求的onFailure判斷,在網(wǎng)上翻閱到的資料并不是太滿意泰偿,最后還是自己封裝一個熄守。
1.新建一個ApiResponse類,主要用來包裝網(wǎng)絡請求返回的onResponse、onFailure數(shù)據(jù)
class ApiResponse<T> {
var code = SUCCESS_CODE
var body: T? = null
var msg: String? = null
constructor(response: Response<T>) {
body = response.body()
}
constructor(t: T) {
body = t
}
constructor(throwable: Throwable) {
body = null
code = ERROR_CODE
//對異常進行判斷耗跛,這個是我隨便寫的一點裕照,可以寫一個工具類給封裝起來
msg = when (throwable) {
is SocketTimeoutException -> "超時"
is HttpException -> {
when (throwable.code()) {
404 -> "沒有找到合適的資源"
500 -> "服務器內部錯誤"
else -> throwable.message()
}
}
is JSONException -> "json解析異常"
is UnknownHostException -> "網(wǎng)絡異常"
else -> throwable.message
}
}
companion object {
private const val TAG = "ApiResponse"
const val ERROR_CODE = 99999
const val SUCCESS_CODE = 200
fun error(throwable: Throwable): ApiResponse<*> {
return ApiResponse<Any?>(throwable)
}
}
}
2.再使用kotlin的擴展函數(shù)對ViewModel進行擴展 ,讓所有的ViewModel類都能使用 call() 方法调塌,主要是進行異常的邏輯處理
suspend fun <T> ViewModel.call(job: suspend () -> T): ApiResponse<T> {
return try {
ApiResponse(job())
} catch (e: java.lang.Exception) {
ApiResponse(e)
}
}
請求最后會變成如下這樣
fun getData() {
viewModelScope.launch {
val data = call {
RetrofitClient.api.getData1()
}
//表示有異常
if (data.code == ApiResponse.ERROR_CODE) {
Log.i(TAG, ": ${data.msg}")
return@launch
}
//取出我們后臺接口返回的數(shù)據(jù)
val body = data.body
body?.let {
if (it.errorCode == ApiResponse.SUCCESS_CODE) {
Log.i(TAG, ": ${it.data}")
}
}
}
}