Android OKHttp3下载实战:断点续传与进度显示

1星 8 下载量 144 浏览量 更新于2024-09-02 收藏 179KB PDF 举报
"详解Android使用OKHttp3实现下载(断点续传、显示进度):本文将介绍如何在Android应用中使用OKHttp3框架进行文件下载,并实现断点续传和下载进度显示功能。" 在Android开发中,OKHttp3是一个高效且广泛使用的网络请求库。它提供了异步和同步的HTTP请求方式,支持HTTP/2协议以及连接池,从而提高了网络请求的性能。断点续传功能允许用户中断下载后从上次停止的地方继续,这对于大文件下载或网络不稳定的情况尤其有用。显示下载进度则可以提供更好的用户体验,让用户了解下载的实时状态。 首先,我们需要在项目中引入OKHttp3和RxJava依赖。在`build.gradle`文件中添加相应的依赖项,例如: ```groovy dependencies { implementation 'com.squareup.okhttp3:okhttp:4.9.1' // 使用最新版本的OKHttp3 implementation 'io.reactivex.rxjava2:rxjava:2.2.21' // 使用最新版本的RxJava } ``` 接下来,我们创建一个下载服务,使用OKHttp3发起请求并处理响应。为了实现断点续传,我们需要在请求头中添加`Range`字段,指定从哪个字节开始下载。这里可以使用`SeekableByteChannel`来获取当前文件已下载的字节数。 ```java public class DownloadService extends Service { private OkHttpClient client; private SeekableByteChannel fileChannel; private Request request; @Override public void onCreate() { super.onCreate(); client = new OkHttpClient.Builder().build(); } public void startDownload(String url, String filePath) { try { File outputFile = new File(filePath); if (outputFile.exists()) { fileChannel = Files.newByteChannel(outputFile.toPath(), StandardOpenOption.WRITE, StandardOpenOption.APPEND); long fileSize = fileChannel.size(); request = new Request.Builder() .url(url) .addHeader("Range", "bytes=" + fileSize + "-") // 设置断点续传范围 .build(); } else { fileChannel = Files.newByteChannel(outputFile.toPath(), StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE); request = new Request.Builder().url(url).build(); } client.newCall(request).enqueue(new Callback() { // 实现Callback接口,处理下载响应 }); } catch (IOException e) { e.printStackTrace(); } } // 在Callback的onResponse方法中,读取响应体的字节流,并写入到文件通道 @Override public void onResponse(Call call, Response response) throws IOException { if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); long contentLength = response.body().contentLength(); InputStream in = response.body().byteStream(); byte[] buffer = new byte[1024]; int read; while ((read = in.read(buffer)) != -1) { fileChannel.write(ByteBuffer.wrap(buffer, 0, read)); // 更新并通知下载进度 } fileChannel.close(); } // 其他Callback方法和Service生命周期方法... } ``` 为了显示下载进度,我们可以使用RxJava将下载操作转换为可观察序列,然后订阅这个序列并在主线程中更新UI。在`onResponse`方法中,你可以计算已下载的字节数,并通过`LocalBroadcastManager`或者自定义事件总线发送广播到Activity中更新进度条。 ```java // 创建可观察序列 Observable.create(new ObservableOnSubscribe<Long>() { @Override public void subscribe(ObservableEmitter<Long> emitter) throws Exception { long downloadedBytes = 0; while ((read = in.read(buffer)) != -1) { downloadedBytes += read; emitter.onNext(downloadedBytes); fileChannel.write(ByteBuffer.wrap(buffer, 0, read)); } emitter.onComplete(); } }) .observeOn(Schedulers.io()) .subscribeOn(Schedulers.io()) .subscribe(bytes -> { // 在主线程中更新进度 updateProgress(bytes, contentLength); }); ``` 最后,别忘了在`AndroidManifest.xml`中声明服务,并在需要的时候启动和停止下载服务。 通过以上步骤,我们就成功地使用OKHttp3实现了Android应用中的断点续传下载,并展示了下载进度。这种方案既保证了下载的可靠性,又提供了良好的用户体验。