溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Rxjava中怎么實(shí)現(xiàn)斷點(diǎn)續(xù)傳下載功能

發(fā)布時(shí)間:2021-08-09 16:51:17 來源:億速云 閱讀:133 作者:Leah 欄目:編程語言

這篇文章將為大家詳細(xì)講解有關(guān)Rxjava中怎么實(shí)現(xiàn)斷點(diǎn)續(xù)傳下載功能,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對相關(guān)知識有一定的了解。

具體內(nèi)容如下

DownloadSubscribe(被觀察者)中執(zhí)行下載存入本地操作

核心還是:addHeader("RANGE", "bytes=" + downloadLength + "-" + contentLength)

DownLoadObserver(觀察者)通過onnext(DownloadInfo downloadInfo)方法回調(diào)下載進(jìn)度

下面上主要代碼:

/** * 開始下載 * @param url 下載請求的網(wǎng)址 * @param downFileCallback 用來回調(diào)的接口 */ 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 {  //創(chuàng)建下載實(shí)體類  return Observable.just(createDownInfo(s));  } }) .map(new Function<DownloadInfo, DownloadInfo>() {  @Override  public DownloadInfo apply(DownloadInfo s) throws Exception {  //根據(jù)本地是否存在此文件,來設(shè)置文件名及文件初始下載大小  return getRealFileName(s);  } }) .flatMap(new Function<DownloadInfo, ObservableSource<DownloadInfo>>() {  @Override  public ObservableSource<DownloadInfo> apply(DownloadInfo downloadInfo) throws Exception {  //創(chuàng)建被觀察者  return Observable.create(new DownloadSubscribe(downloadInfo));  } })//下載 .observeOn(AndroidSchedulers.mainThread())//在主線程回調(diào) .subscribeOn(Schedulers.io())//在子線程執(zhí)行 .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);  }  }); }

/** * 根據(jù)url暫停下載操作 * @param url */ public void cancel(String url) { Call call = downCalls.get(url); if (call != null) { call.cancel();//取消 } downCalls.remove(url); }

/** * 創(chuàng)建被觀察者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();//已經(jīng)下載好的長度 long contentLength = downloadInfo.getTotal();//文件的總長度 //初始進(jìn)度信息 e.onNext(downloadInfo);  Request request = new Request.Builder()  //斷點(diǎn)續(xù)傳的核心  .addHeader("RANGE", "bytes=" + downloadLength + "-" + contentLength)  .url(url)  .build(); Call call = mClient.newCall(request); //根據(jù)下載url,把call存放在map中,取消的時(shí)候就可以通過call.cancle()來實(shí)現(xiàn) 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];//緩沖數(shù)組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 { //關(guān)閉IO流 IOUtil.closeAll(is, fileOutputStream);  } e.onComplete();//完成 } }

/** * 從服務(wù)器獲取文件長度 * * @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; }

從服務(wù)器獲取文件長度的時(shí)候注意一下,Android P之后,也就是api 28以上禁止明文網(wǎng)絡(luò)傳輸。需要在你的AndroidManifest中的application標(biāo)簽中聲明"android:usesCleartextTraffic="true",允許應(yīng)用進(jìn)行明文傳輸。

使用方法:首先要獲取sd卡權(quán)限

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();  } });

關(guān)于Rxjava中怎么實(shí)現(xiàn)斷點(diǎn)續(xù)傳下載功能就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI