您好,登录后才能下订单哦!
这篇文章将为大家详细讲解有关Rxjava中怎么实现断点续传下载功能,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。
具体内容如下
DownloadSubscribe(被观察者)中执行下载存入本地操作
核心还是:addHeader("RANGE", "bytes=" + downloadLength + "-" + contentLength)
DownLoadObserver(观察者)通过onnext(DownloadInfo downloadInfo)方法回调下载进度
下面上主要代码:
/** * 开始下载 * @param url 下载请求的网址 * @param downFileCallback 用来回调的接口 */ public void download(final String url, final DownFileCallback downFileCallback) { if (url == null || downCalls.get(url) != null) { return; } Observable.just(url) .filter(new Predicate<String>() { @Override public boolean test(String s) throws Exception { //过滤条件 若map中存在,则这次不下载 return !downCalls.containsKey(s); } }) .flatMap(new Function<String, ObservableSource<DownloadInfo>>() { @Override public ObservableSource<DownloadInfo> apply(String s) throws Exception { //创建下载实体类 return Observable.just(createDownInfo(s)); } }) .map(new Function<DownloadInfo, DownloadInfo>() { @Override public DownloadInfo apply(DownloadInfo s) throws Exception { //根据本地是否存在此文件,来设置文件名及文件初始下载大小 return getRealFileName(s); } }) .flatMap(new Function<DownloadInfo, ObservableSource<DownloadInfo>>() { @Override public ObservableSource<DownloadInfo> apply(DownloadInfo downloadInfo) throws Exception { //创建被观察者 return Observable.create(new DownloadSubscribe(downloadInfo)); } })//下载 .observeOn(AndroidSchedulers.mainThread())//在主线程回调 .subscribeOn(Schedulers.io())//在子线程执行 .subscribe(new DownLoadObserver() {//添加观察者 @Override public void onNext(DownloadInfo downloadInfo) { super.onNext(downloadInfo); downFileCallback.onProgress(downloadInfo.getTotal(), downloadInfo.getProgress()); } @Override public void onError(Throwable e) { super.onError(e); if (!(e instanceof SocketException)) { downFileCallback.onFail(e.getMessage()); } } @Override public void onComplete() { downFileCallback.onSuccess(url); } }); }
/** * 根据url暂停下载操作 * @param url */ public void cancel(String url) { Call call = downCalls.get(url); if (call != null) { call.cancel();//取消 } downCalls.remove(url); }
/** * 创建被观察者DownloadSubscribe */ private class DownloadSubscribe implements ObservableOnSubscribe<DownloadInfo> { private DownloadInfo downloadInfo; public DownloadSubscribe(DownloadInfo downloadInfo) { this.downloadInfo = downloadInfo; } @Override public void subscribe(ObservableEmitter<DownloadInfo> e) throws Exception { String url = downloadInfo.getUrl(); long downloadLength = downloadInfo.getProgress();//已经下载好的长度 long contentLength = downloadInfo.getTotal();//文件的总长度 //初始进度信息 e.onNext(downloadInfo); Request request = new Request.Builder() //断点续传的核心 .addHeader("RANGE", "bytes=" + downloadLength + "-" + contentLength) .url(url) .build(); Call call = mClient.newCall(request); //根据下载url,把call存放在map中,取消的时候就可以通过call.cancle()来实现 downCalls.put(url, call); Response response = call.execute(); File file = new File(getTemporaryPath(), downloadInfo.getFileName()); InputStream is = null; FileOutputStream fileOutputStream = null; try { is = response.body().byteStream(); fileOutputStream = new FileOutputStream(file, true); byte[] buffer = new byte[2048];//缓冲数组2kB int len; while ((len = is.read(buffer)) != -1) { fileOutputStream.write(buffer, 0, len); downloadLength += len; downloadInfo.setProgress(downloadLength); e.onNext(downloadInfo); } fileOutputStream.flush(); downCalls.remove(url); } finally { //关闭IO流 IOUtil.closeAll(is, fileOutputStream); } e.onComplete();//完成 } }
/** * 从服务器获取文件长度 * * @param downloadUrl * @return */ private long getContentLength(String downloadUrl) { Request request = new Request.Builder() .url(downloadUrl) .build(); try { Response response = mClient.newCall(request).execute(); if (response != null && response.isSuccessful()) { long contentLength = response.body().contentLength(); response.close(); return contentLength == 0 ? DownloadInfo.TOTAL_ERROR : contentLength; } } catch (IOException e) { e.printStackTrace(); } return DownloadInfo.TOTAL_ERROR; }
从服务器获取文件长度的时候注意一下,Android P之后,也就是api 28以上禁止明文网络传输。需要在你的AndroidManifest中的application标签中声明"android:usesCleartextTraffic="true",允许应用进行明文传输。
使用方法:首先要获取sd卡权限
DownloadManager.getInstance().downloadPath(本地存在地址).download(url1, new DownFileCallback() { @Override public void onProgress(long totalSize, long downSize) { progress1.setMax((int) totalSize); progress1.setProgress((int) downSize); } @Override public void onSuccess(String url) { Toast.makeText(MainActivity.this, url1 + "下载完成", Toast.LENGTH_SHORT).show(); } @Override public void onFail(String msg) { Toast.makeText(MainActivity.this, url1 + "下载失败", Toast.LENGTH_SHORT).show(); } });
关于Rxjava中怎么实现断点续传下载功能就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。