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'