6

Android入门第56天-在Android里使用OKHttp多线程下载文件并展示其进度

 1 year ago
source link: https://blog.csdn.net/lifetragedy/article/details/128520249
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

OkHttp是一个神器。OkHttp分为异步、同步两种调用。今天我们就会基于OkHttp的异步调用实现一个多线程并行下载文件并以进度条展示总进度的实用例子。当然这不是我们的Android里使用OkHttp的最终目标,我们最终在下一篇中会在今天这一课的基础上加入“断点续传”的功能,从而以这么连续的几篇从易到难的循序渐进的过程,让大家熟悉和掌握Android中使用OkHttp的技巧以便于形成大脑的“肌肉记忆”。

f5977d87e54e4825aedeb307aa47969c.png
  1. 熟悉OkHttp的同步、异步调用;
  2. 实现n个线程并行下载文件;
  3. 使用线程中的回调机制实时传输下载时的进度;
  4. 用进度条辅助显示我们的整体下载进度;

OkHttp的同步调用例子



newCodeMoreWhite.png

这是一个OkHttp的同步调用例子,访问后根据response.code来作出响应并取response.body()的内容做出相应的业务处理。

OkHttp的异步调用例子



newCodeMoreWhite.png

这是一个OkHttp的异步调用例子,我们可以看到它首先以call.enqueue来执行调用,然后至少有2个回调方法:onFailure和onResponse需要自己覆盖来实现业务功能。

各位记得同步、异步的调用还是有很大区别的。比如说有以下调用顺序:

  • OkHttp调用
  • A方法根据OkHttp调用后的结果再执行B

此时你就必须使用同步调用,而不能使用异步。因为如果你用的是异步很有可能B在执行到一半时,第一步OkHttp调用的结果才刚刚到达。

多线程并行下载文件需要解决的几个核心问题

如何从一个远程Http资源得到文件的尺寸

我们通过response.body().contentLength()即可以获得远程资源文件的尺寸了。

如何对一个本地文件进行并行的写

在这儿,我们使用RandomAccessFile来进行并行写操作。因为RandomAccessFile里有一个seek属性。

seek即写文件起始、结束位置。因此我们设每个不同的线程处理自己的start-end的位置就可以做到对文件进行并行写操作了。为此我们需要执行以下这么几步:

创建一个长度=远程资源长度的空的文件

先创建一个空的RandomAccessFile,并把远程资源的长度以如下的API set进去;

file.setLength(fileLength)

为每个线程分配写入的start-end区间段

假设我们有n个线程,每个线程写文件的长度可以用以下公式得到:

当得到了threadLength即每个线程固定写入的长度后我们就可以得到每个线程起始的写文件位置即: startPosition。

int startPosition = threadNo * threadlength;

 每个线程在写入操作时需要先进行:seek(起始位)。

threadFile.seek(startPosition);

然后在写时每个线程不得超过自己被分配的固定长度,到了写入的固定长度后就结束写操作。

如何在子线程里把当前正写入的文件的size传给Android界面以作进度展示

答案就是:回调函数。

我们先设一个接口如下

然后我们在线程实例化时需要转入这个接口

在写文件时我们作如下操作

而在外层调用时如下实现这个onDownload

就可以在多线程的最外层得到当前写文件的“进度”了。

下面就给出全代码。



newCodeMoreWhite.png

DownloadListener

MultiDownloadHelper



newCodeMoreWhite.png

MainActivity



newCodeMoreWhite.png
b2dc68b119354c7da7f679b7370ccd85.png

 此处需要注意的点是

  1. 需要使用异步线程去驱动我们的多线程;
  2. 使用handler技术来处理进度条的界面变化;

结束今天的课程。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK