Skip to content

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

@wxw-9527

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实例一般项目中应该都有现成的单例对象,可以直接拿来用。

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