kotlin 协程+retrofit2 网络封装(无 hilt
2022-04-15 本文已影响0人
tantanxiqi
前言
需要掌握kotlin 协程基础概念和用法
先看使用情况 在viewmodel 中
fun login() {
val map = hashMapOf( // 传参
"username" to (username.value ?: ""),
"password" to (passwrod.value ?: "")
)
loadHttp(
request = { ApiClient.userApi.login(map) }, // 请求
resp = { loginResult.postValue(it) }, // 响应回调
)
}
如果不想在viewmodel中使用,http请求可在组件中直接使用
bind.tvLogin3.onClick {
val usename = bind.etUser.text.toString().trim()
val pwd = bind.etPwd.text.toString().trim()
lifecycleScope.loadHttp(
request = { ApiClient.userApi.login(usename,pwd) }, // 请求
resp = { loginOk(it) } // 响应
)
}
如果是在子线程中执行网络任务
class TaskTask1() : Runnable {
override fun run() {
val data = runBlocking { //阻塞当前线程
ApiClient.appApi.getBanner()
}
//线程继续执行
if (data.code== 0) {
}
}
}
OkHttp 和 Retrofit 的DC单例封装
object RetrofitClient {
//---------------------------------OkHttp-------------------------------
@JvmStatic
val okClient by lazy(LazyThreadSafetyMode.SYNCHRONIZED){
OkHttpClient.Builder()
.addInterceptor(BaseUrlInterceptor())
.addInterceptor(RequestInterceptor())
.addInterceptor(ResponseInterceptor())
.addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
.build()
}
//-------------------------------Retrofit-----------------------------------
@JvmStatic
val retrofitClient by lazy(LazyThreadSafetyMode.SYNCHRONIZED){
Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(AppConfig.BASE_URL)
.client(okClient)
.build()
}
}
Refrofit Api (方法前需要添加suspend关键字)
interface UserApi {
/**
* 登录
*/
@POST("api/login")
suspend fun login(@Body map: HashMap<String, String>): Res<LoginModel?>
}
interface AppApi{
@GET("/article/list/{page}/json")
suspend fun getPageList(@Path("page")page:String): Res<PageList<InfoModel>>
@GET("banner/list")
suspend fun getBanner(): Res<MutableList<BannerDataModel>>
}
Refrofit Api 的DC单例
object ApiClient {
//api 可自行扩展
@JvmStatic
val appApi by lazy(LazyThreadSafetyMode.SYNCHRONIZED){
retrofitClient.create(AppApi::class.java)
}
@JvmStatic
val userApi by lazy(LazyThreadSafetyMode.SYNCHRONIZED){
retrofitClient.create(UserApi::class.java)
}
}
BaseViewModel 中的封装
fun <T> loadHttp(
request: suspend CoroutineScope.() -> Res<T>, // 请求
resp: (T?) -> Unit, // 相应
err: (String) -> Unit = { }, // 错误处理
end: () -> Unit = {}, // 最后执行方法
isShowToast: Boolean = true, // 是否toast
isShowDialog: Boolean = true, // 是否显示加载框
) {
viewModelScope.launch {
try {
showDialog(isShowDialog)
val data = request() // 请求+响应数据
if (data.code == ResCode.OK.getCode()) { //业务响应成功
resp(data.data) // 响应回调
} else {
showToast(isShowDialog, data.msg)
err(data.msg) // 业务失败处理
}
} catch (e: Exception) {
err(e.message ?: "") //可根据具体异常显示具体错误提示 异常处理
showToast(isShowToast, e.message ?: "")
} finally {
end()
dismissDialog(isShowDialog)
}
}
}
协程的http请求扩展
fun <T> CoroutineScope.loadHttp(
start: () -> Unit = {},
request: suspend CoroutineScope.() -> Res<T>,
resp: (T?) -> Unit,
err: (String) -> Unit = {},
end: () -> Unit = {}
) {
launch {
try {
start()
val data = request()
if (data.code == ResCode.OK.getCode()) {
resp(data.data)
} else {
err(data.msg)
}
} catch (e: Exception) {
err(e.message ?: "") //可根据具体异常显示具体错误提示
Log.e("HttpClient", "异常:" + e.message)
} finally {
end()
}
}
}
结尾
代码已开源
https://github.com/ruirui1128/jetpack-hilt-flow-mvvm.git