因为在工作中使用的是Retrofit+Rxjava发起网络请求,Rxjava很好很强大,美中不足的是代码量太大,如下:
RetrofitUtil.getInstance().createService(BaseService.class)
.doSomeThing(new Object())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.compose(getView().bindToLifecycleDestroy())
.subscribe(new ResultObserver<Object>() {
@Override
public void onLoading(Disposable d) {
}
@Override
public void onSuccess(Result<Object> result, Object object) {
}
@Override
public void onApiError(Result<Object> result, int code, String msg) {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onLoaded() {
}
});
Rxjava很多操作符Kotlin+协程完全能完美替代,例如:
.map((mapper) -> { return Object(); })
.let { Any() }
切换线程
.observeOn(AndroidSchedulers.mainThread())
CoroutineScope(Dispatchers.MAIN).launch {}
秉着一字千金的宗旨,在尽量精简代码的前提下,我将Retrofit+协程+ViewModel封装成一个便捷、精简的网络库,调用代码如下:
launch<ResponseResult<Any>> {
invoke {
buildService<Test>().getSomething(mapOf("key" to "xxx"))
}.onSuccess {
_result use result.toString()
}.onApiError(Dispatchers.IO) {
LogUtils.e("业务错误")
}.onError {
LogUtils.e("请求错误")
}.onComplete {
LogUtils.e("请求结束")
}
}
继承BaseVM,就能直接launch发起网络请求
class MainViewModel : BaseVM() {
private val _result = MutableLiveData<String>()
val result: LiveData<String> = _result
fun getResult() {
launch<ResponseResult<Any>> {
invoke {
buildService<Test>().getSomething(mapOf("key" to "xxx"))
}.onSuccess {
_result use result.toString()
}.onApiError {
LogUtils.e("业务错误")
}.onError {
LogUtils.e("请求错误")
LogUtils.e(message)
}.onComplete {
LogUtils.e("请求结束")
}
}
}
@JvmSuppressWildcards
interface Test {
@FormUrlEncoded
@POST("toutiao/index")
suspend fun getSomething(@FieldMap map: Map<String, Any>): ResponseResult<Any>
}
}
Speedy.instance.launch<ResponseResult<Any>> {
invoke {
buildService<MainViewModel.Test>().getSomething(mapOf("key" to "xxx"))
}.onSuccess(Dispatchers.Main) {
}
}
代码非常精简,每个状态方法都是可插拔的,需要则实现对应的方法
.onSuccess {
_result use result.toString()
}.onApiError(Dispatchers.IO) {
LogUtils.e("业务错误")
}.onError {
LogUtils.e("请求错误")
LogUtils.e(message)
}.onComplete {
LogUtils.e("请求结束")
}.onErrorMessag {
LogUtils.e("请求失败")
}.onSuccessMessage {
LogUtils.e("请求成功包含业务失败")
}
每个状态方法都可以入参CoroutineDispatcher对象,lambda函数就会切换到对应的线程,不传则默认是主线程
.onSuccess(Dispatchers.MAIN) {
}.onApiError(Dispatchers.IO) {}
当前网络超时或者链接错误会toast提示,可通过以下方法关闭
Speedy.NETWORK_ERROR_TOAST = false // 全局关闭
launch<ResponseResult<Any>>(false) { // 当前请求关闭
}
Speedy.instance.showToast = {
ToastUtils.showShort(it)
}
项目不同对Retrofit的配置肯定不一样,可以通过以下方法配置
Speedy.instance.init(this) {
baseUrl("http://v.juhe.cn/")
addConverterFactory(GsonConverterFactory.create())
client(OkHttpClient.Builder().build())
}
或者直接用自定义Retrofit
Speedy.instance.init(this, mRetrofit)
implementation 'io.github.conerjoy:Speedy:1.0.5'
Speedy.instance.init(this) {
baseUrl("http://v.juhe.cn/")
addConverterFactory(GsonConverterFactory.create())
}
// Speedy.instance.init(this, mRetrofit)
Speedy.instance.showToast = {
ToastUtils.showShort(it)
}
Speedy.NETWORK_ERROR_TOAST = true // 全局生效
open class ResponseResult<T> : SpeedyBean<T> {
var reason: String = ""
var result: T? = null
var error_code: Int = -1
override fun isSuccess() : Boolean = error_code == 0
override fun message(): String = reason
}
class MainViewModel : BaseVM() {
private val _result = MutableLiveData<String>()
val result: LiveData<String> = _result
fun getResult() {
launch<ResponseResult<Any>> {
invoke {
buildService<Test>().getSomething(mapOf("key" to "xxxx"))
}.onSuccess {
_result use result.toString()
}.onApiError {
LogUtils.e("业务错误")
}.onError {
LogUtils.e("请求错误")
LogUtils.e(message)
}.onComplete {
LogUtils.e("请求结束")
}
}
}
@JvmSuppressWildcards
interface Test {
@FormUrlEncoded
@POST("toutiao/index")
suspend fun getSomething(@FieldMap map: Map<String, Any>): ResponseResult<Any>
}
}