其实原来一直使用Rxjava进行的网络请求,蛮强大的,本文只是学习及实践,不对之处望请指教。
1、添加依赖,在这之前最好将项目迁移到AndroidX,很简单(Refactor->Migrate To AndroidX),若有错误,按提示修改即可。
implementation "androidx.lifecycle:lifecycle-extensions:2.0.0"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.0.0"
2、编写ViewModel类,我这里以版本更新为例。
class MainModel : ViewModel(){
val TAG = "MainModel"
val apiService = RetrofitManager.serviceApiLive
var versionUpdateL = MediatorLiveData<BaseBeanOfObject<UpdateBean>>()
/**
*获取版本更新
*/
fun getNetDataOfObject() {
val tem = apiService.versionUpdateL()
versionUpdateL.addSource(tem) {
versionUpdateL.removeSource(tem)
versionUpdateL.value = tem.value
}
}
override fun onCleared() {
Logger.t(TAG).e("onclear")
super.onCleared()
}
}
代码相对来说比较简单。
3、调用
class MainActivity : BaseActivity(), View.OnClickListener { ... val mainModel by lazy { ViewModelProviders.of(this).get(MainModel::class.java) } val updateObserve = UpdateObserve(this) override fun initView(savedInstanceState: Bundle?) { setContentView(R.layout.activity_main) getUpdate() } private fun getUpdate() { // getNetDataOfObject(RetrofitManager.serviceApi.versionUpdate(), HttpMethod.VERSION_UPDATE) // mainModel.versionUpdateL?.observe(this, Observer<BaseBeanOfObject<UpdateBean>> { // Logger.t("liulu").e("res:${it}") // }) mainModel.getNetDataOfObject() mainModel.versionUpdateL.observe(this, updateObserve) } }
这里重写了下Observe,做了一些更新的处理。同时在Base中把一些网络返回值base层的异常情况做了一些简单处理。
class UpdateObserve(val context: Context) : BaseObserve<UpdateBean>(true) {
override fun onChanged(data: BaseBeanOfObject<UpdateBean>?) {
super.onChanged(data)
... // 做一些下载或者提示等等更新相关的处理
}
}
open class BaseObserve<T>(val isShowRErrorMsg: Boolean, val setData: (T) -> Unit = {}) : Observer<BaseBeanOfObject<UpdateBean>> { override fun onChanged(data: BaseBeanOfObject<UpdateBean>?) { when ("200".equals(data?.code)) { true -> setData(data?.data as T) false -> { // 接口异常时如果有弹出错误信息的需求,弹出错误信息 Logger.t("base_error").e("msg==" + data?.message) if (isShowRErrorMsg) { data?.message?.toast() } } } } }
Retrofit处代码
object RetrofitManager { var serviceApiLive: LipstickServce = getRetrofit().create(LipstickServce::class.java) fun getRetrofit(): Retrofit { // 检查网络 val activity = App.instance if (!NetUtils.isNetworkAvailable(activity)) { ToastUtil.showCustemToast("主人,请检查您的网络状态") } ...//省略代码 var builder = Retrofit.Builder() .baseUrl(HttpMethod.ROOT_API_URL) .client(client) .addCallAdapterFactory(LiveDataCallAdapterFactory()) // 这里是一个需要注意的点,使用LiveDataCallAdapterFactory替换RxJava2CallAdapterFactory return builder!!.addConverterFactory(GsonConverterFactory.create()).build() } .... }
class LiveDataCallAdapterFactory : Factory() { override fun get(returnType: Type, annotations: Array<Annotation>, retrofit: Retrofit): CallAdapter<*, *>? { if (getRawType(returnType) != LiveData::class.java) return null //获取第一个泛型类型 val observableType = getParameterUpperBound(0, returnType as ParameterizedType) val rawType = getRawType(observableType) if (rawType != BaseBeanOfObject::class.java) { throw IllegalArgumentException("type must be BaseBeanOfObject") } if (observableType !is ParameterizedType) { throw IllegalArgumentException("resource must be parameterized") } return LiveDataCallAdapter<Any>(observableType) } }
class LiveDataCallAdapter<T>(private val responseType: Type) : CallAdapter<T, LiveData<T>> { override fun adapt(call: Call<T>): LiveData<T> { return object : LiveData<T>() { private val started = AtomicBoolean(false) override fun onActive() { super.onActive() if (started.compareAndSet(false, true)) {//确保执行一次 call.enqueue(object : Callback<T> { override fun onFailure(call: Call<T>, t: Throwable) { val value = BaseBeanOfObject<T>() as T postValue(value) } override fun onResponse(call: Call<T>, response: Response<T>) { postValue(response.body()) } }) } } } } override fun responseType() = responseType }
如果对你有帮助,欢迎老铁互粉哦!