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并新增了三个方法,这个类虽然放在oksimple里,但说实话只是作为演示用,因为我自己用的时候也会继承自ResultCallBack并重写,原因很简单,不管考虑再周全,也很难覆盖到所有情况。我把我自己使用的一个数据解析的callback放在下面,但是这个我自己项目中使用的callback,我没有放在oksimple里

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,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图片加载进度监听

以上相关的callback就是Oksimple的核心,之后的post,get,文件上传下载进度监听也都是基于这些callback进行操作