【Jetpack篇】协程+Retrofit网络请求状态封装实战(2)

一、前语

前几天发布了一篇【Jetpack篇】协程+Retrofit网络央求状况封装实战,在谈论区里也收到了一些同僚的反应:

【Jetpack篇】协程+Retrofit网络恳求状况封装实战(2)

【Jetpack篇】协程+Retrofit网络恳求状况封装实战(2)

……

具体问题能够直接移步到上一篇谈论区检查。

由于有几个问题点还蛮重要,所以源码码头就上一篇文章新增了一些内容,首要如下:

  • ✅ 新json增部分状况处理。好像一个页面多个接口,能够别离处理状况切换;
  • ✅ UI层新增Error,Empty,Success的Callback,开发者能够清闲挑选是否监听,处理事务逻辑更直观、便当;
  • ✅ 结合第三方库l协程游览oadSir,一起切换UI。
  • ✅ 央求调用更加简略

好了,正文开始。

二、部分央求状况处理

很多时分appjava言语开发,存在同一个界面不同接口的状况,两个接口一起json是什么意思央求,一个成功一个失利,这个时分成功接口持续闪现自己的页面,失利接口则闪现Error提示界面,如下图

【Jetpack篇】协程+Retrofit网络恳求状况封装实战(2)

上一篇的封装是将ejsonp跨域原理rrorLiveData和loadingLiveDatajava言语全局封装在BaseFragment中,而他们java模拟器的创立也是在github中文官网网页BaseViewModel中,这样就导致多个接口一起央求时,假定某个接口发送过失,就无法区别过失来自哪里。

假定需求每个接口单独处理自己的状况,那么就需求在ViewModel中创立多个erroeLiveData,这样问题是能够源码本钱处理,但是会导致json格局怎样翻开代码十分冗余。已然需求每个接口处理不同状况,那就能够新建一个既包含央求回源码共享网来作用又包含不同状况值的LivejsonobjectData,将之命名为StateLiveData

/**
* MutableLiveData,用于将央求状况分发给UI
*/
class StateLiveData<T> :jsonobject MutableLiveData<BaseResp协程官网<T>>() {
}

而BaseResp中除了央求回来值的公共json外,还需求增加上不同的状况值,我们将状况值分为( STATE_CREATE,STATE_LOADING,STATE_SUCCESS,STATE_COMPLETED,STATE_EMPTY,STATE_FAIjava就业培训班LED, STATE_ERROR,STATE_UNKNOWN)java开发几种

enum class DataState {
STjson字符串ATE_CREATE,//创立
STATE_LOADING,//加载中
STATE_SUCCESS,//成功
STATE_COMPLETED,//完毕
STATE_EMPTY,//数据Java为null
STATE_FAILEDgitlab,//接口央求成功但是服务器回来errorjson
STATE_ERROR,//央求失利
STATE_UNKNOWN//不知道
}

将DataState增加到BaseResp中,

/**
* json回源码之家来的根柢类型
*/
class BaseResp<T>{
var errorCode = -1json文件是干什么的
vjava怎样读ar errorMsg: String? = null
var data: T? = null
private set
var djsonp跨域原理ataState: DataState? = null
vjavascriptar error: Throwable? = null
val isSuccess: Boolean
get() = errorCode == 0
}

那StateLiveData该怎样运用呢?

我们都知道数据央求会有不同的作用,成功,异常或许数据为null,那么就能够运用不同的作用,将相应的状况设置在BaseResp的DataState中。直接进入到数据央求Repository层,对上篇异常处理json解析做了改进。

open class BaseRepository {
/**
* repo 央求数据的公共办法,
* 在不同状况下先设置 baseResp.dataState的值,终究将dataState 的状况告知给UI
*/
suspend fun &jsonp跨域原理lt;T : Any> executeResp(协程网
block: suspendjson文件是干什么的 () -> BaseResp协程机票&ltjava面试题;T>,
stateLiveData: StateLiveData&ljavascriptt;T>
) {
var baseResp = BaseResp<T>()
try {
baseResp.dataState = DataState.STATE_LOADING
//开始央求协程电话数据
val invoke = block.invoke()
//将作用复制给baseResp
baseResp = invoke
if (baseResp.errorCode == 0) {
//央求成功,判别数据是否为空,
//由于数据有多种类型,需求自己设置类型进行判别
if (baseResp.dagitlabta == null || baseResp.data is List<*> &&a协程之窗mp; (baseResp.giti轮胎data as List<*&giti是什么牌子gt;).size == 0)giti是什么牌子 {
//TODO: 数据为空,结构变化时需求修改判空条件
baseResp.dataState = DataState.STATE_EMPTY
} else {
//央求成功并且数据为空的状况下,为STATE_SUCCESS
baseResp.dataState = DataState.STAT源码本钱E_SUCCESS
}
} else {
//服务器央求过失
baseResp.dataState = DataState.STATE_FAILED
}
} cat源码网站ch (e: Exceptionjavascript) {
//非后台回来过失,捕获到的异常
baseResp.dataState = Da源码码头taState.STATE_ERROR
base源码交易网站源码Resp.ejava开发rror = e
} finally {
stateLiveData.postValue(baseResp)
}
}
}

executeResp()为数jsonp据央求的公共办法,该办法传java模拟器入了两个参数,第一个是将java开发数据央json格局求函数当作参数,第二个便是上协程网面新建的StateLiveData

办法一开始就新建了一个BaseResp()目标,将Dat协程游览aState.STATE_LOADING状况设置给BaseResp的dataState,接着开始对数据央求进行异常处理(java怎样读具体可检查上一篇),假定code=0标明接口json格局怎样翻开央求成功,否则标明接口央求成功,服务器回来过失。在code=0时,对回来数据进行判空处理,由于数据有多种类型,这儿需求自己设置类型进行判别,为空就将状况设置为Datjson文件是干什么的aState.STATE_EMPTY,否则为

D源码时代ataState.STATE_SUCCESjson字符串S。假定抛出异常源码码头,则将状况设置为DataState.STATE_ERROR,在央求完毕后,运用stateL源码本钱ive源码时代Data将带有状况的baseResp分发给UI。

到这儿源码本钱giti是什么牌子央求状况都设置完毕,接下来只需求依据不同状况,开始进行界面切换处理。

三、结合LoadSir界面切换

LoadSjava面试题ir是一个加载反应页处理结构,状况页Java自动切换,具体运用在这儿就不描绘了,需求的可移步github检查。

LiveData接纳数据变化时,UI会先注册一个接纳工作的观察者,接纳到央求的数据后就进行UI更新,第二节里将不同状况也增加到了数据中,要想对状况也进行监听的话,就需求对Obsgithuberver进行状况处理。

/**
* LiveData Obser源码编辑器ver的一个类,
*协程电话 首要结合LoadSJSONir,依据BaseResp里边的源码共享网State别离加载不同的UI,如LoJavaading,java初学Error
* 一起重写o协程appnChanged回调,java面试题分为onDataChange,onDataEmpty,onError,
* 开发gitee者能够在UI层,每个接口央求时,直接创立IStateOjava怎样读bserver,重写相应callback。
*/
abstract class IStateObserver<T>(view: View?) : Observer<BaseResp<T>>, Callback.OnReloadListener {
private var mLoadService: LoadService<Any>? = null
init {
if (view != null) {
mLoadService = LoadSir.getDejsonp跨域原理fault().re协程appgistjava怎样读er(v源码iew, this,
Convertor<BaseResp<T>&g协程appt; { t ->
varjson字符串 resultCode: Class<out Callback> = Succejson格局ssCallback:java怎样读:class.java
when (t?.dataState协程之窗) {
//数据刚开始央求,loading
DataState.STATE_CREATE, DataState.STATE_LOADING -> resultCode =
LoadingCallback::class.java
//央求成功
DataState.STATE_SUCCESS -> resultCode = SuccessCallgit教程back::class.java
//数据为空
DataState.STATE_EMPTY -> resultCode =
EmptyCjson解析allbackjava环境变量装备::class.java
Djson解析ataState.STATE_FAILED ,DataState.STATE_ERROR -> {
vgit教程al error: Throwable? = t.error
onError(ejavascriptrror)
//能够依据不同的差协程app错类型,设置过失协程app界面时的UI
if (error is HttpExceptjavascription协程电话) {
//网络过失
} elgithubse if (error is ConnectException) {json文件是干什么的
//无网络衔接
} else if (error is InterruptedIOExcepjson是什么意思tion) {
//衔接超时
} else if (error is JsonParseException
|| error is JSONException
|| errojava面试题r is ParseException
) {
//解析json文件是干什么的过失
} else {
//不知道过失
}
resultCode = ErrorCallback::clajson字符串ss.java
}
DataState.STATE_COMPLETED, DataState.STATE_UNKNOWN -> {
}
else -> {
}
}
Ljson文件是干什么的og.协程教育d(TAG, "resultCode :$resultCode协程网 ")
resultCodjava模拟器e
})
}
}
override fun onChanged(t: BaseResp<T>) {
Log.d(TAG, "onChanged: ${t.dat协程电话aState}")
when (t.dataState) {
DataState.STATE_SUCCESS -> {
//央求成功,数据不为null
onDataChange(t.data)
}
DataState.STATE_EMPTY -> {
//数据为空
onDataEmpty()
}
DataState.STATE_FAILEDgiti是什么牌子,DataState.json是什么意思STATE_ERRgit命令OR->{
//央求过失
t.error?.let { onError(it) }
}
else -> { }
}giti是什么牌子
//加载不同状况界面
Log.d(TAG, "onChanged: mLoadService $mLoadService")
mLoadService?.showWithConvertor(t)
}
/**
* 央求数据且数据不为空
*/
open fun onDataChange(data: TGit?) {
}
/**
* 央求成功,但数据为空
*/
open fun onDataEgiti轮胎mpty() {
}
/**
* 央求过失
*/
open fun onError(e: Thro源码本钱wable?) {
}
}

IStateObserver协程官网Observer接口的完成类,参数传入了源码之家一个View,而这个V协程appiew便是你所要替换的界面,这也便是同个界面,不同模块闪现异常不同的关键所在。由所以结合Loadsir,首要需求初始化LoadService,再者通java怎样读过dataState的状况值JSON,设置不同的Callback,例如Loading时,json解析设置为LoadingithubgCallback,Error时,设置为ErrorCallback,Empty时设置为EmptyCjava怎样读allback,设置完毕后,在onChanged回调中一起调用showWithConvertor,也便是切换界面的操作。

而在onChange回调中,相同依据状况值,别离分发onDataChangeonDataEmptyonError的告知。

到这儿,完毕了不同状况界面切换和状况告知的分发作业。

四、怎样运用

上述根柢大将整个流程封装完毕,运用起来也相对简洁。

Repository层:

clagitlabss ProjectRepo源码码头() : BaseRep协程osit源码之家ory() {
suspend fun loadProjectTree(stateLiveData: StateLiveData<List<ProjectTree>>) {
executeResp({mService.loadProjectTrgitiee()},源码之家stateLiveData)
}
}

直接就一行代码,executeResp办法中传入api的央求,以及StateLivegithub永久回家地址Data。

Vie源码之家wModel源码交易网站源码层:

class ProjectViewModel : BaseVi源码ewModel() {
val mProje协程机票ctTreeLiveData = StateLiveData&l源码编辑器编程猫下载t;List<ProjectTree>>()
fun loadProjectTree() {
viewModelScope.launch(Dispatchers.IO) {
mRepo.loadProjectTree(mPjson格局怎样翻开rojectTreeLiveData)
}
}

调用依旧是一行代码,新建了一个StateLiveData,接着直接在viewModelScope作用域中调用Repository层的网络央求,这儿记得将StateLiveData源码网站作为参数传进去。

UI层:

class ProjectFragment : BaseFragment<Fragmentjava环境变量装备ProjectBinding, ProjectViewModel>() {
override fun initData() {
mViewModel?.loadProjectTree()
mView协程appModel?.mProjectTreeLiveData?.obsejava环境变量装备rve(this,
object : IStateObservjava就业培训班er<List<Pr协程机票ojectTree>>(mBinding?.rvProjectAll) {
override f源码编辑器手机版下载unjava怎样读 onDataChange(data: List<ProjectTree>?) {
super.onDataChange(data)
Log.d(TAG, "onDataChange: ")
datajsonp?.let {javascript mAdapter.sejsontData(it) }
}
override fun onReload(v: View?) {
Log.d(TAjson文件是干什么的G, "onReload: ")
mViewModel?.loadProjectTre源码时代e()
}
override f协程之窗un onDataEmpty() {
super.onDataEmpty()
Log.d(TAG, "onDataEmpty: ")
}
override fun onError(e: ThJavarowable?) {
super.o协程网nError(e)
showToast(e?.message!!)
Log.d(TAG, "onError: ${e?.pringit教程tStackTrace()}")
}
})
}
}

UI层运用Vi协程电话ewModel的Stgiti是什么牌子ateLiveData注册观Java察者,与以往不同的是,mgiti是什么牌子ViewMoJavadel?.mProjectTreeLiveData?.observe()第二个参数替换为了IStateObserver,并且传入了一个View,而这个View代表着的是当央求异常时,你所想替换的UIjson是什么意思界面,一起,也多了几个回调,

  • onDataChange:央求成功,数据不源码编辑器手机版下载为空;
  • onReloa协程网订机票d:点击从头央求;
  • onDataEmpty:数据为空时;
  • onError:央求失利

开发者能够通过自己的事务需求,清闲的挑选监听。

我们来看看作用。

【Jetpack篇】协程+Retrofit网络恳求状况封装实战(2)

五、终究

这次的整合弥源码共享网补了一些细节问题,更契jsonp合App开发逻辑,当然每协程个App的事务不同,这就要开发者去定制化一些央求细节,但是协程+Retrofit源码共享网网络央求的大致思路便是如此。
更多具体的代码可移步至github

源码: 组件化+Jetpack+kotlin+mvvm

请结合【Jetpack篇】协程+Retrofit网络央求状况封装实战

发表评论

提供最优质的资源集合

立即查看 了解详情