美文网首页
retrofit2.6+kotlin协程中 onFailure回

retrofit2.6+kotlin协程中 onFailure回

作者: 我家造地球 | 来源:发表于2019-12-26 15:33 被阅读0次

先引入依赖

//这个是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<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销毁的时候,取消所有的协程
        viewModelScope.coroutineContext.cancelChildren()
    }

    companion object {
        val TAG: String = CommViewModel::class.java.simpleName
    }
}

在网上看了很多的博客,大部分都是如上这样子介绍一些比较简单的使用,但是如果要深入一点,比如网络请求的onFailure判断,在网上翻阅到的资料并不是太满意,最后还是自己封装一个。

1.新建一个ApiResponse类,主要用来包装网络请求返回的onResponse、onFailure数据

 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 -> "网络异常"
            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的扩展函数对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
            }
            //取出我们后台接口返回的数据
            val body = data.body
            body?.let {
                if (it.errorCode == ApiResponse.SUCCESS_CODE) {
                    Log.i(TAG, ": ${it.data}")
                }
            }
        }
    }

相关文章

  • retrofit2.6+kotlin协程中 onFailure回

    先引入依赖 初始化网络设置 在网上看了很多的博客,大部分都是如上这样子介绍一些比较简单的使用,但是如果要深入一点,...

  • Tornado入门(三)【协程】

    协程 在Tornado中,协程是推荐使用的异步方式。协程使用yield关键字暂停或者恢复执行,而不是回调链的方式。...

  • 异步,回调

    在回调函数中携带外部信息 用协程来实现

  • 认识协程

    1、协程是什么? 协程基于线程,它是轻量级线程。协程让异步逻辑同步化,杜绝回调地狱。协程最核心的点就是,函数或者一...

  • 协程.md

    协程协程中使用suspend修饰方法,代表该方法可在协程中挂起。但并不是协程方法必须使用suspend修饰协程和线...

  • 4.协程的异常处理(2)

    异常的传播异常传播是指异常在父子协程中的传播,什么是父子协程,在当前协程中又启动一个协程,那么这个新启动的协程就是...

  • 协程网址

    谈谈并发编程中的协程 网络架构库:State Threads State Threads:回调终结者 发现go对协...

  • 破解 Kotlin 协程(8) - Android 篇

    关键词:Kotlin 协程 Android Anko Android 上面使用协程来替代回调或者 RxJava 实...

  • 【白水日记】Coroutines

    在kotlin中,协程是方便而优雅处理长时间运行任务的方案 kotlin协程使得原来基于回调的代码改为了顺序编写,...

  • 协程调度 与 生命周期

    我们可以为协程指定上下文环境 子协程 当一个协程被其它协程在 CoroutineScope 中启动的时候, 它将通...

网友评论

      本文标题:retrofit2.6+kotlin协程中 onFailure回

      本文链接:https://www.haomeiwen.com/subject/xnfhoctx.html