美文网首页
Retrofit + 协程 完成简单BasePresenter

Retrofit + 协程 完成简单BasePresenter

作者: XBYoung | 来源:发表于2019-07-11 20:04 被阅读0次
    implementation "com.squareup.retrofit2:retrofit:2.6.0"
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.1'
    implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2'
/**
@author: Young <( ̄︶ ̄)>
Create: 2019-07-03
 */
abstract class CoroutinePresenter<V : BaseView> : BasePresenter(), CoroutineScope by MainScope() {
    lateinit var view: V
    
    fun onCreate(view: V) {
        this.view = view
    }
    
    fun onDestroy() {
        cancel()
    }
    
    /**
     * 单个网络任务+后续耗时操作
     */
    fun <T, R> startSimpleJobWithWork(call: Call<T>, andThen: (T) -> R, complete: (R) -> Unit) {
        coroutineTry {
            view.showLoading()
            val result = withContext(Dispatchers.IO) {
                val source = withContext(Dispatchers.Default) { call.createCallBack() }
                withContext(Dispatchers.Default) { andThen(source) }
            }
            view.hideLoading()
            complete(result)
        }
    }
    
    /**
     * 单个网络任务
     */
    fun <T> startSimpleJob(call: Call<T>, response: (T) -> Unit) {
        coroutineTry {
            view.showLoading()
            val result = withContext(Dispatchers.Default) { call.createCallBack() }
            view.hideLoading()
            response(result)
        }
    }
    
    
    /**
     * 单个网络任务
     */
    fun <T> startSimpleJob(source: Deferred<T>, complete: (T) -> Unit) {
        coroutineTry {
            view.showLoading()
            val result = source.await()
            view.hideLoading()
            complete(result)
        }
    }
    
    
    /**
     * 多个任务
     */
    fun startMultiJob(vararg jobs: suspend () -> Unit) {
        coroutineTry {
            view.showLoading()
            withContext(Dispatchers.IO) {
                jobs.forEach {
                    it()
                }
            }
            view.hideLoading()
        }
        
    }
    
    
    private fun coroutineTry(job: suspend (CoroutineScope) -> Unit) {
        launch {
            try {
                supervisorScope {
                    job(this)
                }
            } catch (e: Exception) {
                val errorResult = when (e) {
                    is ErrorResult -> e
                    is ConnectException -> ErrorResult()
                    is HttpException -> {
                        when (e.code()) {
                            in 500 until Int.MAX_VALUE -> {
                                ErrorResult(e.code().toString(), "服务器内部异常")
                            }
                            in 400 until 500 -> {
                                ErrorResult(e.code().toString(), "请求异常")
                            }
                            else -> null
                        }
                    }
                    is ParseException -> ErrorResult(errorMsg = "数据异常")
                    else -> ErrorResult()
                }
                view.requestError(errorResult)
            }
            view.hideLoading()
        }
        
    }
    
    suspend fun <T> Call<T>.createCallBack() = suspendCoroutine<T> {
        this.enqueue(CoroutineCallback<T>(it))
        
    }
}
 class CoroutineCallback<T>(private val continuation: Continuation<T>) : Callback<T> {
    override fun onFailure(call: Call<T>, throwable: Throwable) {
        continuation.resumeWithException(throwable)
    }
    
    override fun onResponse(call: Call<T>, response: Response<T>) {
        response?.let {
            if (it.errorBody() != null) {
                val string = it.errorBody()?.string()
                string?.let { info ->
                    try {
                        continuation.resumeWithException(Gson().fromJson(info, ErrorResult::class.java))
                    } catch (e: Exception) {
                        continuation.resumeWithException(e)
                    }
                }
            } else {
                it.body()?.let {
                    continuation.resume(it)
                } ?: continuation.resumeWithException(ErrorResult(errorMsg = "数据异常"))
                
            }
        }
    }
}

使用:

    startSimpleJobWithWork(apiWithToken.getBrands(QueryHelper.signQuery(TreeMap())), { 
    //耗时操作
    sortData(it)}) {
            view.solveData(it)
        }


        startSimpleJob(apiWithToken.getBrands(QueryHelper.signQuery(TreeMap()))){
            view.vehicleBrandResponse(it)
        }
  @GET("/api/v0/xxxxxx")
  fun getBrands(@QueryMap map1: MutableMap<String, Any>): Call<CarListResult>

或者

  @GET("/api/v0/xxxxxx")
  fun getBrands(@QueryMap map1: MutableMap<String, Any>): Deferred<CarListResult>

使用第二种方式暂时不知道怎样处理后端返回的自定义异常,有大神知道怎么操作请留言赐教。

相关文章

网友评论

      本文标题:Retrofit + 协程 完成简单BasePresenter

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