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) {

        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
    })

你可能感兴趣的:(retofit + rxjava + kotlin 下载进度回调(721))