retofit + rxjava + kotlin 下载进度回调(721)

下载回调换一种写法

DownLoadListener

先写好监听接口

interface MyDownloadListener {

    fun onStartDownload()

    fun onProgress(progress: Int)

    fun onFinishDownload()

    fun onFail(errorInfo: String)
}

DownloadInterceptor

封装拦截器

class DownloadInterceptor(private val downloadListener: MyDownloadListener) : Interceptor {

    @Throws(IOException::class)
    override fun intercept(chain: Interceptor.Chain): Response {

        val response = chain.proceed(chain.request())

        return response.newBuilder()
            .body(DownloadResponseBody(response.body(), downloadListener))
            .build()
    }
}

DownloadManager

主要逻辑都在manager内

class MyDownloadManager {

    private val tag = "DownloadUtils"

    private val DEFAULT_TIMEOUT = 15

    private lateinit var retrofit: Retrofit

    private lateinit var listener: MyDownloadListener

    private lateinit var baseUrl: String

    private val downloadUrl: String? = null

    constructor(baseUrl: String, listener: MyDownloadListener) {

        this.baseUrl = baseUrl
        this.listener = listener

        val mInterceptor = DownloadInterceptor(listener)

        val httpClient = OkHttpClient.Builder()
            .addInterceptor(mInterceptor)
            .retryOnConnectionFailure(true)
            .connectTimeout(DEFAULT_TIMEOUT.toLong(), TimeUnit.SECONDS)
            .build()

        retrofit = Retrofit.Builder()
            .baseUrl(baseUrl)
            .client(httpClient)
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .build()
    }

    /**
     * 开始下载
     * @param url
     * @param filePath
     * @param subscriber 下载完成之后的操作
     */
    fun download(url: String, filePath: String, fileName: String, subscriber: Consumer<ResponseBody>) {

        listener.onStartDownload()

        retrofit.create(JsBridgeService::class.java)
            .downloadApk(url)
            .subscribeOn(Schedulers.io())
            .unsubscribeOn(Schedulers.io())
            .observeOn(Schedulers.computation()) // 用于计算任务
            .doOnNext {
                writeFile(it.byteStream(), it.contentLength(), filePath, fileName)
            }
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(subscriber)
    }

    /**
     * 将输入流写入文件
     * @param inputString
     * @param filePath
     */
    private fun writeFile(inputString: InputStream, total: Long, filePath: String, fileName: String) {

        val file = File(filePath, fileName)
        if (file.exists()) {
            Log.e(tag, "file exists!")
            file.delete()
        }

        try {
            val fos = FileOutputStream(file)

            val b = ByteArray(1024 * 4)

            var sum = 0L
            var len = 0
            val off = 0
            while (inputString.read(b).apply { len = this } > 0) {
                fos.write(b, off, len)
                sum += len.toLong()
                val progress = (sum * 1.0f / total * 100).toInt()
                // 在这里回调进度
                listener.onProgress(progress)
            }
            inputString.close()
            fos.flush()
            fos.close()
            listener.onFinishDownload()

        } catch (e: FileNotFoundException) {
            listener.onFail("FileNotFoundException")
        } catch (e: IOException) {
            listener.onFail("IOException")
        }
    }
}

调用示例

// 一个参数是baseUrl,因为是下载,所以传什么不重要
MyDownloadManager("", object : MyDownloadListener {
    override fun onStartDownload() {
        Log.e("download", "manager start")
    }

    override fun onProgress(progress: Int) {
        Log.e("download", progress.toString())
    }

    override fun onFinishDownload() {
        Log.e("download", "manager finish")
    }

    override fun onFail(errorInfo: String) {
        Log.e("download", "manager error")
    }
})
    .download(url, path, name, Consumer {

        // do something
    })
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,148评论 1 32
  • iOS网络架构讨论梳理整理中。。。 其实如果没有APIManager这一层是没法使用delegate的,毕竟多个单...
    yhtang阅读 5,282评论 1 23
  • “你是至尊宝吗?” “不,我的名字叫齐天大圣。” 今天是《速8》上映的第一天,各个城市的各大影院的首映场几乎都是爆...
    叭乐叭乐阅读 382评论 0 0
  • 来源:天使的语音 有一个巨商,为躲避动荡,把所有的家财置换成金银票,特制了一把油纸伞,将金银票小心地藏进伞柄之内,...
    月儿明_0311阅读 526评论 0 0
  • 外公生于1910年,经历过旧中国的社会动荡,到了新社会,能吃饱穿暖,过上安稳的生活,他感到很满足。 他一生勤勤恳恳...
    南风鱼儿阅读 766评论 4 8