>  기사  >  Java  >  RxJava2.x 및 ReTrofit2.x 멀티 스레드를 사용하여 파일을 다운로드하는 방법의 예

RxJava2.x 및 ReTrofit2.x 멀티 스레드를 사용하여 파일을 다운로드하는 방법의 예

黄舟
黄舟원래의
2017-09-19 09:52:142433검색

이 글에서는 주로 RxJava2의 샘플 코드를 소개합니다. apk 업그레이드 기능을 만드는 원리는 사실 매우 간단합니다. Baidu에도 많은 예제가 있지만 대부분 프레임워크나 HttpURLConnection을 사용합니다. . 이틀 동안 RxJava2.x+ReTrofit2.x를 시청했는데 이 두 프레임워크가 현재 가장 인기 있는 비동기 요청 프레임워크라고 합니다. 이 기사에서는 RxJava2.x+ReTrofit2.x를 사용하여 멀티스레드 파일 다운로드 기능을 구현합니다.

RxJava2.x+ReTrofit2.x에 대해 잘 모르신다면 관련 문서를 먼저 읽어보시기 바랍니다.

스승님, 이건 무시해주세요.

아이디어 분석:



아이디어는 매우 간결하고 명확하며 주로 다음 네 단계로 나뉩니다.

1. 서버 파일 크기를 가져옵니다.2. .3. 다운로드한 콘텐츠를 전체 파일로 병합합니다.

4. 설치를 호출하고 apk를 설치합니다.

기능이 구현되었습니다.

자, 다음은 즐겨찾는 코드 링크입니다

1. 먼저 참조를 살펴보세요

  compile 'io.reactivex:rxjava:latest.release'
  compile 'io.reactivex:rxandroid:latest.release'
  //network - squareup
  compile 'com.squareup.retrofit2:retrofit:latest.release'
  compile 'com.squareup.retrofit2:adapter-rxjava:latest.release'
  compile 'com.squareup.okhttp3:okhttp:latest.release'
  compile 'com.squareup.okhttp3:logging-interceptor:latest.release'

2 다운로드 인터페이스 DownloadService.class를 구성합니다.

public interface DownloadService {
  @Streaming
  @GET
  //downParam下载参数,传下载区间使用
  //url 下载链接
  Observable<ResponseBody> download(@Header("RANGE") String downParam,@Url String url);
}

3 사용 편의성을 위해 RetrofitHelper.class가 캡슐화되어 있으며 주로 다음 용도로 사용됩니다.

a) OkHttpClient 및 Retrofit을 인스턴스화합니다.


  public RetrofitHelper(String url, DownloadProgressListener listener) {

    DownloadProgressInterceptor interceptor = new DownloadProgressInterceptor(listener);

    OkHttpClient client = new OkHttpClient.Builder()
        .addInterceptor(interceptor)
        .retryOnConnectionFailure(true)
        .connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
        .build();
    retrofit = new Retrofit.Builder()
        .baseUrl(url)
        .client(client)
        .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
        .build();
  }

b) 다운로드 방법을 캡슐화하여 이 다운로드를 사용했습니다. 다운로드 스레드 3개를 동적으로 할당하지 않습니다. 필요에 따라 스레드 수를 동적으로 할당할 수 있습니다.

 public Observable download(@NonNull final long start, @NonNull final long end, @NonNull final String url, final File file, final Subscriber subscriber) {
    String str = "";
    if (end == -1) {
      str = "";
    } else {
      str = end + "";
    }
    return retrofit.create(DownloadService.class).download("bytes=" + start + "-" + str, url).subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io()).map(new Func1<ResponseBody, ResponseBody>() {
      @Override
      public ResponseBody call(ResponseBody responseBody) {
        return responseBody;
      }
    }).observeOn(Schedulers.computation()).doOnNext(new Action1<ResponseBody>() {
      @Override
      public void call(ResponseBody responseBody) {
        //第一次请求全部文件长度
        if (end == -1) {
          try {
            RandomAccessFile randomFile = new RandomAccessFile(file, "rw");
            randomFile.setLength(responseBody.contentLength());
            long one = responseBody.contentLength() / 3;
            download(0, one, url, file, subscriber).mergeWith(download(one, one * 2, url, file, subscriber)).mergeWith(download(one * 2, responseBody.contentLength(), url, file, subscriber)).subscribe(subscriber);

          } catch (IOException e) {
            e.printStackTrace();
          }
        } else {
          FileUtils fileUtils = new FileUtils();
          fileUtils.writeFile(start, end, responseBody.byteStream(), file);
        }

      }
    }).subscribeOn(AndroidSchedulers.mainThread());
  }

4. 다운로드 호출

참고: 호출 다운로드는 MainAcitivity에서 수행됩니다. 이해를 돕기 위해 진행률 표시 구현을 용이하게 하기 위해 진행률 차단 인터셉터를 캡슐화했지만 이 문서에서는 진행률 인터셉터의 구현 프로세스를 설명하지 않습니다. 필요한 경우 메시지를 남길 수 있습니다. .

a) 청취 객체 구현

subscriber = new Subscriber() {
      @Override
      public void onCompleted() {
        Log.e("MainActivity", "onCompleted下下载完成");
//        Toast.makeText(MainActivity.this, "onCompleted下下载完成", Toast.LENGTH_LONG).show();
        installAPK("mnt/sdcard/aaaaaaaaa.apk");
      }

      @Override
      public void onError(Throwable e) {
        e.printStackTrace();
        Log.e("MainActivity", "onError: " + e.getMessage());
      }

      @Override
      public void onNext(Object o) {

      }
    };

b) 캡슐화된 RetrofitHelper를 호출하여 다운로드 구현

 RetrofitHelper RetrofitHelper = new RetrofitHelper("http://gdown.baidu.com/data/wisegame/0904344dee4a2d92/", new DownloadProgressListener() {
      @Override
      public void update(long bytesRead, long contentLength, boolean done) {

        SharedPF.getSharder().setLong("update", bytesRead);
        pro.setProgress((int) ((double) bytesRead / contentLength * 100));
        temp++;
        if (temp <= 1) {
          Log.e("MainActivity", "update" + bytesRead + "");
        }
      }
    });
    RetrofitHelper.download(0, -1, "QQ_718.apk", new File("mnt/sdcard/", "aaaaaaaaa.apk"), subscriber).subscribe(new Subscriber() {
      @Override
      public void onCompleted() {

      }

      @Override
      public void onError(Throwable e) {

      }

      @Override
      public void onNext(Object o) {

      }
    });

  }

참고: 마지막으로 APK 설치 방법 게시

  // 安装APK
  public void installAPK(String filePath) {
    Intent intent = new Intent();
    intent.setAction("android.intent.action.VIEW");
    intent.addCategory("android.intent.category.DEFAULT");
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);// 广播里面操作需要加上这句,存在于一个独立的栈里
    intent.setDataAndType(Uri.fromFile(new File(filePath)), "application/vnd.android.package-archive");
    mainActivity.startActivity(intent);
  }

위 내용은 RxJava2.x 및 ReTrofit2.x 멀티 스레드를 사용하여 파일을 다운로드하는 방법의 예의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.