下载回调换一种写法
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
})