Skip to content

不需要断点续传的单文件下载场景,可使用以下替代方案试一试 #507

Description

@wxw-9527

项目实现版本更新功能时,测试发现系统提供的DownloadManager API部分机型在内网环境下无法获取文件长度,返回值始终为-1,导致文件下载失败。集成OkDownload后,发现多线程下载时合并文件偶发性失败,部分设备偶发下载进度卡在100%,taskEnd方法不回调。

鉴于需求比较简单,决定放弃集成OkDownload,采用OkHttp+Retrofit+okio实现简单的文件下载场景,其他有类似需求的可以参考一下。

1、创建Service
interface DownloadService {

        @Streaming
        @GET
        fun downloadFile(@Url fileUrl: String): Observable<ResponseBody>
}

2、下载文件
val disposable = mRetrofit?.create<DownloadService>()
            ?.downloadFile(url)
            ?.compose(schedulersTransformer())
            ?.subscribe(
                { responseBody ->
                    // 创建一个文件
                    val file = File(PATH + fileName)
                    val writtenToDisk = writeResponseBodyToDisk(responseBody, file)
                    Timber.tag("DownloadUtil").d("File download was a success? $writtenToDisk")
                    if (writtenToDisk && file.isFile && file.exists()) {
                        // TODO: 文件下载成功
                    }
                },
                { e ->
                    Timber.tag("DownloadUtil").e(e)
                }
            )

3、将文件写入本地
private fun writeResponseBodyToDisk(body: ResponseBody, file: File): Boolean {
        return try {
            // 使用OKio的sink和buffer方法来写文件
            file.sink().buffer().use { sink ->
                sink.writeAll(body.source())
            }
            true
        } catch (e: Exception) {
            Timber.tag("DownloadUtil").e(e)
            false
        }
    }

大致就是以上的代码,Retrofit实例一般项目中应该都有现成的单例对象,可以直接拿来用。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions