ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

retrofit2 + 协程封装

2022-02-23 13:34:36  阅读:273  来源: 互联网

标签:retrofit2 val 封装 private import fun 协程 com


package com.base.common

import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import java.util.concurrent.TimeUnit

object RetrofitClient {
    private const val BASE_URL = "https://api.apiopen.top/"
    private val httpInterceptor: HttpInterceptor = HttpInterceptor()
    private val okHttpClient = OkHttpClient.Builder()
        .callTimeout(30, TimeUnit.SECONDS).addInterceptor(httpInterceptor)
        .cache(
            CacheHelper.instance?.cache
        )
        .readTimeout(15, TimeUnit.SECONDS)
        .writeTimeout(15, TimeUnit.SECONDS)
        .retryOnConnectionFailure(true)
        .build()
    private val retrofit = Retrofit.Builder()
        .baseUrl(BASE_URL)
        .addConverterFactory(GsonConverterFactory.create())
        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
        .client(okHttpClient)
        .build()

    fun <T> create(serviceClass: Class<T>): T = retrofit.create(serviceClass)
}
import retrofit2.http.*
import com.test.login.UserBean as UserBean

interface ApiStore {
    // https://blog.csdn.net/c__chao/article/details/78573737 测试接口来自地址
    @GET("getSingleJoke?")
    suspend fun login(@Query ("sid") sid:String): UserBean
}
class ApiService {
    companion object {
        private var TAG: String = "ApiService"
        private var apiService = RetrofitClient.create(ApiStore::class.java)
        suspend fun ktLogin(request: BaseRequestParams): UserBean {
            // 为了测试方便,使用测试接口这里传递的参数并非真正的请求参数
            //NetDataUtils.createJson(request)
            return apiService.login("28654780")
        }
    }

    private suspend fun <T : BaseBean?> Call<T>.await(): T {
        return suspendCancellableCoroutine { continuation ->
            enqueue(object : RetrofitCallBack<T>() {
                override fun success(data: T) {
                    continuation.resumeWith(runCatching {
                        data
                    })
                }

                override fun failed(data: T) {
                    if (continuation.isCancelled) return
                    continuation.resumeWith(runCatching {
                        data
                    })
                }
            })
            continuation.invokeOnCancellation {
                try {
                    cancel()
                } catch (ex: Throwable) {
                    Log.e(TAG, "ApiService continuation invokeOnCancellation cancel Throwable")
                }
            }
        }
    }
}

package com.base.common

import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import java.lang.reflect.ParameterizedType

 open class RetrofitCallBack<T : BaseBean ?>(private val callBack: CallBack<T>) : Callback<T> {
     override fun onResponse(call: Call<T>, response: Response<T>) = if (response.isSuccessful) {
         val body = response.body()
         // 网络请求成功返回的code值
         if (body?.code == ServiceCode.SUCCESS) {
             callBack.success(body)
         } else {
             // 接口调用返回错误码
             callBack.failed(createErrorData(body?.code,body?.message,create()))
         }
    } else {
        // 网络请求失败
        callBack.failed(createErrorData(response.code(),response.message(),create()))
    }

    override fun onFailure(call: Call<T>, t: Throwable) {
        // 网络请求异常
        callBack.failed(createErrorData(ServiceCode.HTTP_ERROR_CODE,t.message,create()))
    }

    private fun createErrorData(code:Int?, message:String?,data : T): T
    {
        data!!.message = message
        data.code = code
        return data
    }

    private fun <T> create(): T
    {
        var mClass: Class<T> =
            (javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0] as Class<T>
        return mClass.newInstance()
    }
}

interface CallBack<T> {
     fun success(data: T)
     fun failed(data: T)
}
```kotlin
package com.base.common

open class BaseBean(
    var code: Int? = 0,
    var message: String? = null,
)
package com.test.login

import com.base.common.BaseBean

open class UserBean: BaseBean() {
    lateinit var result: ResultData
}

class ResultData(
    var sid: String,
    val text: String,
)

view module 调用方式

class UserModel : BaseViewModel() {
    val userBean: MutableLiveData<UserBean> by lazy {
        MutableLiveData<UserBean>()
    }

    fun getData() {
        //使用IO线程? Retrofit已经使用子线程方式,多一次线程切换,是否有必要?
        viewModelScope.launch(Dispatchers.IO) {
            var start = System.currentTimeMillis()
            val clz = LoginRequestParams::class.java
            val request = NetDataUtils.createRequest(clz)
            val userData = ApiService.ktLogin(request)
            var end = System.currentTimeMillis()
            Log.e("UserModel", "UserModel http time" + (end - start))
            // 收到请求的回调可以选择判断处理,然后发送通知给Activity
            userBean.postValue(userData)
        }
    }
}
package com.base.common

class ServiceCode {
    companion object {
         const val SUCCESS = 0
         const val HTTP_ERROR_CODE = Int.MAX_VALUE - 1
    }
}

可能用到的包

api "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
api "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
api (['com.squareup.okhttp3:logging-interceptor:3.9.0',
      'com.squareup.retrofit2:retrofit:2.7.2',
      'com.squareup.retrofit2:converter-gson:2.7.2')
api 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.3'

标签:retrofit2,val,封装,private,import,fun,协程,com
来源: https://blog.csdn.net/a670275845/article/details/123085821

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有