ResultCallBack - GateOfTruth/OkSimple GitHub Wiki
ResultCallBack
在Oksimple中,所有的请求回调结果,都是基于ResultCallBack这个抽象类,这个抽象类定义了一系列的抽象方法,并且继承了BaseProgressListener接口实现上传和下载进度监听。不同的请求,需要回调不同的callback。
abstract class ResultCallBack : BaseProgressListener {
/**
* 做文件下载用的
*/
val urlToBeanMap= hashMapOf<String,DownloadBean>()
/**
* 开始网络请求之前调用,在主线程回调,可以用来弹出dialog等
*/
abstract fun start()
/**
* 和okhttp3.Callback.onResponse(call: Call, response: Response) 同步回调,用于获取请求的结果
*/
abstract fun response(call: Call, response: Response)
/**
* 和okhttp3.Callback.onFailure(call: Call, e: IOException) 同步回调,用于接受okhttp本身的各种异常,诸如SocketTimeoutException等,在主线程回调
*/
abstract fun failure(call: Call, e: Exception)
/**
* 当responseBody 为空时回调
*/
abstract fun responseBodyGetNull(call: Call, response: Response)
/**
* 捕获除了okhttp本身的异常外的其他异常,诸如http返回了404,500,其他在处理response过程中发生的异常也可以在这里处理,诸如json解析异常等,在实际使用中,这个和
failure()方法都是必须重写的,不然无法覆盖所有的错误情况
*/
abstract fun otherException(call: Call, response: Response, e: Exception)
}
而BaseProgressListener则没什么好说的了
interface BaseProgressListener {
fun downloadProgress(url:String,total: Long, current: Long)
fun downloadProgressOnMainThread(url:String,total: Long, current: Long)
fun uploadProgress(fileName: String, total: Long, current: Long)
fun uploadProgressOnMainThread(fileName: String, total: Long, current: Long)
}
下载和上传进度重写了RequestBody和ResponseBody,这样做的好处是可以为接入glide监听图片的加载进度,所以默认的上传和下载的进度回调都是在子线程回调,但我们一般展示进度是在主线程,所以我又新增了两个主线程回调的方法。 目前内置了四个callback,涵盖了常用的大部分需求,这四个callback都继承自ResultCallBack,当然,你也可以根据需求重写
- DataCallBack,通常用于get,post,文件上传等。需要获取服务器端返回json的情况都可以使用这个
- FileResultCallBack,用于文件下载,支持断点续传
- GlideCallBack,接入glide,获取glide加载进度
- BitmapResultCallBack,获取bitmap,支持下载进度,通常情况下用不到,因为一般不会直接下载图片,都是接入第三方框架,作为GlideCallBack的父类
DataCallBack
DataCallBack继承自ResultCallBack并新增了三个方法,这个类虽然放在lib里,但其实只是一个忘记删除的示例代码,仅供参考。
abstract class DataCallBack<E>(private val isMainThread: Boolean = true) : ResultCallBack() {
/**
*对传入responseBody.string()进行预处理,例如不想实体类太复杂的话,可以在这里使用JSONObject等对服务器返回的json进行成功或者失败判断的预处理
*/
open fun preProcessBodyString(bodyString:String):String
/**
* 需自己根据需要进行重写,传入preProcessBodyString()返回的数据,返回泛型参数。
*/
abstract fun stringToData(string:String):E
/**
* 最终返回结果,在主线程回调。
*/
abstract fun getData(data: E, rawBodyString: String, call: Call, response: Response)
}
NewDataCallBack
NewDataCallBack继承自ResultCallBack并新增了2个方法, 是我自己实际使用的一个callback,仅供一些不太知道怎么重写callback的人参考。其实这个框架的核心还是在于对ResultCallBack和其他父类的重写,我的一些同事拿到我的这个框架,一开始抱怨怎么还要自己去重写这个,重写这个。但是很多时候,为了提供更灵活,更具备扩展性的框架,把一些东西交给用户去重写是必要的。当你熟悉之后,你会发现非常好用。在我自己用的这个框架中,otherException没有默认实现,因为还有一个往下的封装。我会对otherException里的code做判断,从而得出具体是什么情况,当然处理方式也是多种多样的,具体看业务逻辑。
abstract class NewDataCallBack<E>(private val isMainThread: Boolean = true) : ResultCallBack() {
override fun start() {
}
override fun response(call: Call, response: Response) {
val responseBody = response.body
if (responseBody == null) {
if (isMainThread) {
OkSimple.mainHandler.post {
responseBodyGetNull(call, response)
}
} else {
responseBodyGetNull(call, response)
}
return
}
if (response.code == 200) {
val rawString = responseBody.string()
val data = stringToData(rawString)
if (isMainThread) {
OkSimple.mainHandler.post {
returnTheData(data, rawString, call, response)
}
} else {
returnTheData(data, rawString, call, response)
}
} else {
otherException(call, response, Exception("2000"))
}
}
open fun returnTheData(data: E?, rawString: String, call: Call, response: Response) {
if (data != null) {
getData(data, rawString, call, response)
} else {
otherException(
call,
response,
Exception("2001")
)
}
}
abstract fun stringToData(string: String): E?
abstract fun getData(data: E, rawBodyString: String, call: Call, response: Response)
override fun responseBodyGetNull(call: Call, response: Response) {
}
override fun downloadProgress(url: String, total: Long, current: Long) {
}
override fun downloadProgressOnMainThread(url: String, total: Long, current: Long) {
}
override fun uploadProgress(fileName: String, total: Long, current: Long) {
}
override fun uploadProgressOnMainThread(fileName: String, total: Long, current: Long) {
}
GsonCallBack
GsonCallBack是我以gson为例子,重写了datacalllback,方便大家理解datacalllback的用法,诸如gson,moshi,fastjson等用来序列化和反序列化的对象,建议做单例处理,这里只是作为演示用。重写datacalllback,主要是重写stringToData方法。重写的意义在于把服务器端返回的json数据,转化为泛型定义的实体类,这里你可以使用gson,moshi,fastjson。也可以不像我一样使用getGenericSuperclass方法,而改为直接传入一个class类,都是可以的,看自己的喜好。
abstract class GsonCallBack<E> :DataCallBack<E>() {
private val gson=Gson()
override fun stringToData(string: String): E {
val type=(javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0]
return gson.fromJson(string,type)
}
}
FileResultCallBack
FileResultCallBack通常用做文件下载,它继承自ResultCallBack并新增了finish方法
abstract fun finish(file:File)
finish方法是FileResultCallBack继承ResultCallBack后新增的方法,下载完的文件,会在finish()方法里回调。Oksimple默认支持断点续传,假如你的服务器不支持断点续传,也可照常下载。如果你不想断点续传,想重新下载,请在下载前把存在的文件删除。在okhttp的逻辑里,是没有断点续传的概念的,只有通过tag取消一个请求,然后再次请求的概念。oksimple默认给每一个请求一个和url一样的tag,也可以自定义tag。
BitmapResultCallBack
BitmapResultCallBack通常用做图片下载,它继承自ResultCallBack并新增了finish方法。通常情况下来说,这个callback用的会比较少。他的子类GlideCallBack会用的比较多。因为需要通过它,来完成对glide进度的监听。3.1.4版本及以后的版本,去除了BitmapResultCallBack对图片的进度下载监听,因为实际情况中,直接通过response的stream读取图片的情况很少
abstract fun finish(bitmap: Bitmap)
GlideCallBack
GlideCallBack继承自BitmapResultCallBack。用来完成对glide进度的监听。但它是个空方法。使用方法参考glide图片加载进度监听