我是RxJava的新手,我已经设法使用Retrofit实现RxJava以使用flatMap同时下载多个文件。我已成功收到各个下载的onComplete状态。但是,当我收到所有下载的完成状态时,我无法实现功能。
以下是我用于多次下载的代码:
winrm
我在收到URL信息的地方,在许多for循环中调用private void downloadFile(String url, final File parentFolder) {
final Uri uri = Uri.parse(url);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(url.replace(uri.getLastPathSegment(),""))
.client(new OkHttpClient.Builder().build())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create()).build();
RestApi restApi = retrofit.create(RestApi.class);
restApi.downloadFile(url)
.flatMap(new Func1<Response<ResponseBody>, Observable<File>>() {
@Override
public Observable<File> call(final Response<ResponseBody> responseBodyResponse) {
return Observable.fromCallable(new Callable<File>() {
@Override
public File call() throws Exception {
File file = new File(parentFolder.getAbsoluteFile(), uri.getLastPathSegment());
if (!file.exists()) {
file.createNewFile();
BufferedSink sink = Okio.buffer(Okio.sink(file));
sink.writeAll(responseBodyResponse.body().source());
sink.close();
}
return file;
}
});
}
},3)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<File>() {
@Override
public void onCompleted() {
dManager.logMe(TAG,"file download complete");
}
@Override
public void onError(Throwable e) {
dManager.logMe(TAG,"file download error");
e.printStackTrace();
}
@Override
public void onNext(File file) {
dManager.logMe(TAG,"file download onNext: " + file.getAbsolutePath());
}
});
}
。
在此先感谢。
答案 0 :(得分:0)
假设您有List<String>
个网址:
Observable.from(urls)
.flatMap(url -> restApi.downloadFile(url))
.concatMap(new Func1<Response<ResponseBody>, Observable<File>>() {
@Override
public Observable<File> call(final Response<ResponseBody> responseBodyResponse) {
try {
File file = new File(parentFolder.getAbsoluteFile(), uri.getLastPathSegment());
if (!file.exists()) {
file.createNewFile();
}
BufferedSink sink = Okio.buffer(Okio.sink(file));
sink.writeAll(responseBodyResponse.body().source());
sink.close();
return Observable.just(file);
} catch (Exception e) {
return Observable.error(e);
}
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<File>() {
@Override
public void onCompleted() {
dManager.logMe(TAG, "file download complete");
}
@Override
public void onError(Throwable e) {
dManager.logMe(TAG, "file download error");
e.printStackTrace();
}
@Override
public void onNext(File file) {
dManager.logMe(TAG, "file download onNext: " + file.getAbsolutePath());
}
});
答案 1 :(得分:0)
这是一个临时示例
Observable.from(List <Url>)
.flatMap(Observable.fromCallable(downloadImageHereAndReturnTheFile())
.observeOn(AndroidSchedulers.mainThread())
// Do on next is where you get notified when each url is getting downloaded
.doOnNext(doTheUIOperationHere())
.observeOn(Schedulers.io()) //Switch to background thread if you want, in case if you do some other background task otherwise remove the above this and the following next operator
.doOnNext(DoSomeOtherOperationHere()))
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(new Subscriber<R>() {
@Override
public void onCompleted() {
Log.d(TAG, "The entire process of downloading all the image completed here");
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(R r) {
Log.d(TAG, "You receive the file for each url");
}
});