RxJava 的方式下载文件带进度,Okio 写入

首先调用是这样的

  String url = "https://mac-installer.github.com/mac/GitHub%20Desktop%20220.zip";
    subscription = api.downloadFile(url, null, new Subscriber() {
      @Override public void onCompleted() {
        L.e(TAG + " down ", Thread.currentThread().getName() + "onCompleted ");
      }

      @Override public void onError(Throwable e) {
        L.e(TAG + " down ", e);
      }

      @Override public void onNext(FileInfo fileInfo) {
        long percent = fileInfo.getCurrentSize() / fileInfo.getFileSize();

        L.e(TAG + " down ", fileInfo);
      }
    });

可以取消订阅,结束下载

 @Override protected void onDestroy() {
    super.onDestroy();
    subscription.unsubscribe();
  }

下面的图是下载的 log


RxJava 的方式下载文件带进度,Okio 写入_第1张图片
下载 log

FileInfo 是这样的

public class FileInfo {
  private String fileName;
  private String fileUrl;
  private String fileType;
  private long fileSize;//单位 byte
  private long currentSize;
    //省略 getter setter
  }

下载代码

  public Subscription downloadFile(String url,String dest, Subscriber subscriber) {
    return Observable.create(new Observable.OnSubscribe() {
      @Override public void call(Subscriber subscriber) {
        if (!subscriber.isUnsubscribed()) {
          try {
            new FileDownLoader().download(url, dest, subscriber);
          } catch (IOException e) {
            e.printStackTrace();
            subscriber.onError(e);
          }
        }
      }
    }).compose(applySchedulers())
    .onBackpressureBuffer()// 一定要调用onBackpressureBuffer()方法,防止下载过快,导致MissingBackpressureException异常
    .subscribe(subscriber);
  }

其中applySchedulers()

  public static final Observable.Transformer schedulersTransformer =
      new Observable.Transformer() {
        @Override public Observable call(Observable observable) {
          return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
        }
      };

  /**
   * 应用 Schedulers .方便 compose() 简化代码
   */
  @SuppressWarnings("unchecked") public static  Observable.Transformer applySchedulers() {
    return (Observable.Transformer) schedulersTransformer;
  }

关键的下载文件FileDownLoader

public class FileDownLoader {
  public static final String APK = "application/vnd.android.package-archive";
  public static final String PDF = "application/pdf";
  public static final String ZIP = "application/zip, application/x-compressed-zip";
  private OkHttpClient mClient;

  public FileDownLoader() {
    mClient = new OkHttpClient.Builder().build();
  }

  public void download(@NonNull String url, @Nullable String dest,
      Subscriber subscriber) throws IOException {
    if (!URLUtil.isNetworkUrl(url)) {
      throw new RuntimeException("invalid url");
    }
    Uri uri = Uri.parse(url);
    String filename = uri.getLastPathSegment();// get fileName
    File root;
    if (!TextUtils.isEmpty(dest)) {
      root = new File(dest);
    } else {
      root = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
    }
    if (!root.exists()) {
      root.mkdirs();
    }
    File output = new File(root, filename);
    if (output.exists()) {
      output.delete();
    }
    Request request = new Request.Builder().url(uri.toString()).build();
    Response response = mClient.newCall(request).execute();

    long contentLength = response.body().contentLength();

    // fill fileInfo
    FileInfo currentFile = new FileInfo();
    currentFile.setFileSize(contentLength);
    currentFile.setFileName(filename);
    currentFile.setFileUrl(url);
    currentFile.setFileType(response.body().contentType().type());

    BufferedSink sink = Okio.buffer(Okio.sink(output));
    Buffer buffer = sink.buffer();

    long total = 0;
    long len;
    int bufferSize = 200 * 1024; //200kb

    BufferedSource source = response.body().source();
    while ((len = source.read(buffer, bufferSize)) != -1) {
      sink.emit();
      total += len;
      currentFile.setCurrentSize(total);
      subscriber.onNext(currentFile);// onNext
    }
    source.close();
    sink.close();
    subscriber.onCompleted();
  }
}

你可能感兴趣的:(RxJava 的方式下载文件带进度,Okio 写入)