Ok+Rxjava 기반 인 터 럽 트 다운로드

본 고 는 정지점 속전 다운 로드 를 실현 하 는 구체 적 인 코드 를 공유 하여 여러분 께 참고 하 시기 바 랍 니 다.구체 적 인 내용 은 다음 과 같 습 니 다.
1.Ok+Rxjava 기반 인 터 럽 트 다운로드
2.Ok+Rxjava+Retrofit 기반 인 터 럽 트 다운로드
최근 에 배 웠 던 기능 과 사용 한 기능 을 정리 하고 정리 했다Ok+Rxjava 기반 인 터 럽 트 다운 로드 를 위 한 demo사용 효 과 를 먼저 보 여 드 리 겠 습 니 다.
 
제 대체적인 생각 을 말씀 드 리 겠 습 니 다.파일 다운로드 url 에 따라 자신 이 정의 한 규칙 에 따라 파일 이름 을 만 들 고 로 컬 같은 경로 에서 이 파일 이 존재 하 는 지 판단 합 니 다.존재 한다 면 파일 크기 가 서버 에서 가 져 온 파일 크기 와 일치 하 는 경우 새로운 파일 이름 을 생 성하 여 다시 다운로드 합 니 다.서버 에서 가 져 온 파일 보다 파일 크기 가 작 으 면 정지점 다운 로드 를 실행 하고 로 컬 파일 길이 부터 다운로드 합 니 다.파일 이 존재 하지 않 으 면 0 바이트 부터 다운로드 합 니 다.
DownloadSubscribe(피 관찰자)에서 다운 로드 를 실행 하여 로 컬 작업 에 저장 합 니 다.
핵심 은:addHeader("RANGE","bytes="+downloadLength+"-"+contentLength)
DownloadObserver(관찰자)는 onnext(DownloadInfo download Info)방법 으로 다운로드 진 도 를 되 돌 립 니 다.
아래 위의 주요 코드:

/**
 *     
 * @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 이상 은 명문 네트워크 전송 을 금지 합 니 다.Android Manifest 의 application 태그 에"android:uses CleartextTraffic="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();
  }
 });
자,오늘 은 여기까지 입 니 다.여러분 에 게 도움 이 되 었 으 면 좋 겠 습 니 다.이것 은 저 에 게 도 깊 은 인상 을 주 는 노트 입 니 다.
다운로드 주소
git 주소:demo 환영 스타
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기