이 글에서는 주로 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'
public interface DownloadService { @Streaming @GET //downParam下载参数,传下载区间使用 //url 下载链接 Observable<ResponseBody> download(@Header("RANGE") String downParam,@Url String url); }
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()); }
참고: 호출 다운로드는 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 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!