最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于Ok+Rxjava實(shí)現(xiàn)斷點(diǎn)續(xù)傳下載

 更新時(shí)間:2019年06月22日 15:57:37   作者:Super_Ks  
這篇文章主要為大家詳細(xì)介紹了基于Ok+Rxjava實(shí)現(xiàn)斷點(diǎn)續(xù)傳下載,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本文為大家分享了實(shí)現(xiàn)斷點(diǎn)續(xù)傳下載的具體代碼,供大家參考,具體內(nèi)容如下

1、基于Ok+Rxjava實(shí)現(xiàn)斷點(diǎn)續(xù)傳下載

2、基于Ok+Rxjava+Retrofit實(shí)現(xiàn)斷點(diǎn)續(xù)傳下載

最近總結(jié)一下了一下之前學(xué)過(guò)以及用到過(guò)得功能,整理了一個(gè)基于Ok+Rxjava實(shí)現(xiàn)斷點(diǎn)續(xù)傳下載的demo。下面先給大家展示一下使用效果吧。

 

說(shuō)下我的大致思路吧:根據(jù)文件下載url按照自己定義的規(guī)則生成文件名,判斷本地同路徑下是否存在此文件,如果存在,文件大小與服務(wù)器上獲取的文件大小一致的情況下,則生成新的文件名重新下載;如果文件比服務(wù)器獲取的文件大小小,則執(zhí)行斷點(diǎn)下載,從本地文件長(zhǎng)度處開(kāi)始下載。如果文件不存在,則從0字節(jié)開(kāi)始下載。

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

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

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

下面上主要代碼:

/**
 * 開(kāi)始下載
 * @param url 下載請(qǐng)求的網(wǎng)址
 * @param downFileCallback 用來(lái)回調(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 {
  //過(guò)濾條件 若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ù)本地是否存在此文件,來(lái)設(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)下載好的長(zhǎng)度
 long contentLength = downloadInfo.getTotal();//文件的總長(zhǎng)度
 //初始進(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í)候就可以通過(guò)call.cancle()來(lái)實(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ù)器獲取文件長(zhǎng)度
 *
 * @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ù)器獲取文件長(zhǎng)度的時(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();
  }
 });

好了今天就到這里,希望能幫到大家,這對(duì)我來(lái)說(shuō)也是一種加深印象的筆記,

下載地址demo

git地址:DownloadManager 歡迎star

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論

新竹县| 湖南省| 寿阳县| 库车县| 托里县| 沽源县| 丁青县| 绿春县| 沙田区| 呼图壁县| 黎平县| 山西省| 怀来县| 南川市| 姚安县| 三门县| 新昌县| 普兰店市| 五家渠市| 抚州市| 永昌县| 梅州市| 兖州市| 登封市| 荣成市| 南宫市| 嘉善县| 平安县| 嘉禾县| 晋江市| 新乐市| 开江县| 沈丘县| 阿克| 湘乡市| 思茅市| 七台河市| 城步| 拜泉县| 彭州市| 博湖县|