先引入依赖
//这个是google官方扩展的ViewModel库支持协程操作
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.1.0'
//kotlin协程依赖
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'
初始化网络设置
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?,
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销毁的时候,取消所有的协程
viewModelScope.coroutineContext.cancelChildren()
}
companion object {
val TAG: String = CommViewModel::class.java.simpleName
}
}
在网上看了很多的博客,大部分都是如上这样子介绍一些比较简单的使用,但是如果要深入一点,比如网络请求的onFailure判断,在网上翻阅到的资料并不是太满意,最后还是自己封装一个。
1.新建一个ApiResponse类,主要用来包装网络请求返回的onResponse、onFailure数据
class ApiResponse {
var code = SUCCESS_CODE
var body: T? = null
var msg: String? = null
constructor(response: Response) {
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 -> "网络异常"
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(throwable)
}
}
}
2.再使用kotlin的扩展函数对ViewModel进行扩展 ,让所有的ViewModel类都能使用 call() 方法,主要是进行异常的逻辑处理
suspend fun ViewModel.call(job: suspend () -> T): ApiResponse {
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
}
//取出我们后台接口返回的数据
val body = data.body
body?.let {
if (it.errorCode == ApiResponse.SUCCESS_CODE) {
Log.i(TAG, ": ${it.data}")
}
}
}
}