中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

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

如何進行基于Ok+Rxjava+retrofit實現斷點續傳下載

發布時間:2021-10-13 16:26:39 來源:億速云 閱讀:133 作者:柒染 欄目:編程語言

如何進行基于Ok+Rxjava+retrofit實現斷點續傳下載,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。

為大家分享了實現斷點續傳下載的具體代碼,供大家參考,具體內容如下

1、基于Ok+Rxjava實現斷點續傳下載

2、基于Ok+Rxjava+Retrofit實現斷點續傳下載

上一篇博客中介紹了基于Ok+Rxjava實現斷點續傳下載,這一篇給大家介紹下基于Ok+Rxjava+Retrofit實現斷點續傳下載,demo下載地址,效果圖跟上一篇圖片一樣,哈哈

說下我的大致思路吧(跟上一篇略有不同):根據文件下載url按照自己定義的規則生成文件名,判斷本地同路徑下是否存在此文件,如果存在,文件大小與服務器上獲取的文件大小一致的情況下,則覆蓋本地文件重新下載;如果文件比服務器獲取的文件大小小,則執行斷點下載,從本地文件長度處開始下載。如果文件不存在,則從0字節開始下載。

還有的不同是,這里需要重新ResponseBody的source()方法,在這里監聽文件下載的進度,然后通過我么自定義的Downloadinterceptor把我們重新的DownloadResponseBody給設置進去,從而完成我們的進度監聽工作。

下面還是上主要代碼:

首先重寫ResponseBody

public class DownloadResponseBody extends ResponseBody { private ResponseBody responseBody;  //進度回調接口 private DownFileCallback downFileCallback;  private BufferedSource bufferedSource; private String downUrl;   public DownloadResponseBody(ResponseBody responseBody, DownFileCallback downFileCallback, String downUrl) { this.responseBody = responseBody; this.downFileCallback = downFileCallback; this.downUrl = downUrl; }  @Override public MediaType contentType() { return responseBody.contentType(); }  @Override public long contentLength() { return responseBody.contentLength(); }  @Override public BufferedSource source() { if (bufferedSource == null) { bufferedSource = Okio.buffer(source(responseBody.source())); } return bufferedSource; }  private Source source(Source source) { return new ForwardingSource(source) { long totalBytesRead = 0L; File file = new File(DownloadManager.getInstance().getTemporaryName(downUrl));  @Override public long read(Buffer sink, long byteCount) throws IOException { long bytesRead = super.read(sink, byteCount); totalBytesRead += bytesRead != -1 ? bytesRead : 0; if (null != downFileCallback) { if (bytesRead != -1) { long loacalSize = file.length();//本地已下載的長度 long trueTotal = loacalSize + responseBody.contentLength() - totalBytesRead;//文件真實長度 downFileCallback.onProgress(trueTotal,loacalSize); } else {  }  } return bytesRead; } };  }}

重寫Interceptor

public class Downloadinterceptor implements Interceptor {  private DownFileCallback downFileCallback;  private String downUrl;  public Downloadinterceptor(DownFileCallback listener,String downUrl) { this.downFileCallback = listener; this.downUrl = downUrl; }  @Override public Response intercept(Chain chain) throws IOException { Response response = chain.proceed(chain.request());  return response.newBuilder() .body(new DownloadResponseBody(response.body(), downFileCallback,downUrl)) .build(); }}

然后我們的service

public interface HttpService {  /*大文件需要加入Streaming這個判斷,防止下載過程中寫入到內存中,造成oom*/ @Streaming @GET Observable<ResponseBody> download(@Header("range") String start, @Url String url);}

接下來我們的DownloadManager中download方法

/** * 開始下載 * @param url 下載地址 * @param downFileCallback 進度回調接口 */ public void download(final String url, final DownFileCallback downFileCallback) { /*正在下載不處理*/ if (url == null || submap.get(url) != null) { return; }  Downloadinterceptor interceptor = new Downloadinterceptor(downFileCallback, url); okHttpClient = new OkHttpClient.Builder() .addInterceptor(interceptor) .build(); Retrofit retrofit = new Retrofit.Builder() .client(okHttpClient) .baseUrl("http://imtt.dd.qq.com") .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .build(); final HttpService httpservice = retrofit.create(HttpService.class);  ProgressDownSubscriber subscriber = Observable.just(url) .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, Observable<ResponseBody>>() { @Override public Observable<ResponseBody> apply(DownloadInfo downInfo) throws Exception { return httpservice.download("bytes=" + downInfo.getProgress() + "-", downInfo.getUrl()); } })//下載 .map(new Function<ResponseBody, DownloadInfo>() { @Override public DownloadInfo apply(ResponseBody responsebody) { try { return writecache(responsebody, url); } catch (IOException e) { //*失敗拋出異常*// e.printStackTrace(); } return null; } }) .observeOn(AndroidSchedulers.mainThread())//在主線程回調 .subscribeOn(Schedulers.io())//在子線程執行 .subscribeWith(new ProgressDownSubscriber<DownloadInfo>() { @Override public void onNext(DownloadInfo downInfo) { downFileCallback.onSuccess(downInfo); submap.remove(downInfo.getUrl()); }  @Override public void onError(Throwable t) { downFileCallback.onFail(t.getMessage()); submap.remove(url); } });   submap.put(url, subscriber); }

然后暫停操作:

/** * 暫停下載 */ public void stop(String url) { if (url == null) return; if (submap.containsKey(url)) { ProgressDownSubscriber subscriber = submap.get(url); subscriber.dispose(); submap.remove(url); } }

從服務器獲取文件長度

/** * 從服務器獲取文件長度 * * @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 onSuccess(DownloadInfo info) {  Toast.makeText(MainActivity.this, url1 + "下載完成", Toast.LENGTH_SHORT).show(); }  @Override public void onFail(String msg) { Toast.makeText(MainActivity.this, url1 + "下載失敗", Toast.LENGTH_SHORT).show(); }  @Override public void onProgress(final long totalSize, final long downSize) { // 需要注意的是,如果文件總大小為50M,已下載的大小為10M, // 再次下載時onProgress返回的totalSize是文件總長度 // 減去 已下載大小 10M, 即40M,downSize為本次下載的已下載量 // 好消息是,我已經在內部做過處理,放心使用吧,但是這個問題大家還是要知道的  runOnUiThread(new Runnable() { @Override public void run() { int progress = (int) (downSize * 100 / totalSize); progress1.setProgress(progress); } }); } });

好了今天就到這里,希望能幫到大家,這對我來說也是一種加深印象的筆記。

看完上述內容,你們掌握如何進行基于Ok+Rxjava+retrofit實現斷點續傳下載的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

铜梁县| 凌源市| 抚顺市| 五莲县| 都昌县| 黄梅县| 贡山| 禹州市| 乌拉特前旗| 张家川| 永和县| 旺苍县| 十堰市| 广西| 滨州市| 子洲县| 长阳| 肇庆市| 阿坝县| 林芝县| 凉山| 乌拉特前旗| 建德市| 汝州市| 灵宝市| 建瓯市| 许昌县| 福鼎市| 承德市| 洛川县| 富源县| 竹溪县| 宿迁市| 陇南市| 沐川县| 龙口市| 镇原县| 浦城县| 康马县| 虎林市| 盈江县|