我有api从服务器下载单个mp3文件,使用下面的RxJava消费。
Observable<ResponseBody> observable = audioService.getFile(fileNameWithExtension);
observable.subscribeOn(Schedulers.newThread())
.observeOn(Schedulers.newThread())
.subscribe(someCallBackClass<ResponseBody>);
这只是下载单个文件,回调将文件保存在磁盘上。 我想下载保存磁盘上每个文件的文件列表,并等到所有下载完成,最多3个调用应该并行执行。 如何使用RXAndroid,我尝试了flatmap但我无法完全理解它。
List<Observable<Response<ResponseBody>>> audioFiles = new ArrayList<>();
for (String fileNameWithExtension : fileNamesWithExtension) {
Observable<Response<ResponseBody>> observable = restFactory.getAudioService().getFile(fileNameWithExtension);
audioFiles.add(observable);
}
Observable.from(audioFiles).flatMap(audioFile -> Observable.fromCallable(() -> {
audioFile.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.toBlocking()
.subscribe(new CallBackWithErrorHandling<>(Downloader.this));
return 0;
}).subscribeOn(Schedulers.io()), MAX_CONCURRENT)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Integer>() {
@Override
public void onCompleted() {
goToMainActivity();
}
@Override
public void onError(Throwable e) {
Log.e(TAG, "Something went wrong , " + Thread.currentThread().getName());
Log.e(TAG, "Something went wrong , " + e.toString());
showToast(R.string.something_went_wrong);
goToMainActivity();
}
@Override
public void onNext(Integer integer) {
}
});
这工作正常,但是当网络中断或互联网连接缓慢时,我正在
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
我无法理解thinkOn()android主线程究竟需要哪个线程。
答案 0 :(得分:3)
您可以使用flatMap实现此目的,限制其并发性,但还需要在执行文件传输的后台调度程序上运行内部Observable:
fileNames
.flatMap(name -> {
return Observable.fromCallable(() -> {
// put your blocking download code here, save the data
return name; // return what you need down below
})
.subscribeOn(Schedulers.io());
}, 3)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(completedFile -> { }, error -> { },
() -> { /* all completed.*/ });
修改强>
由于您使用Observable API进行网络下载,因此您无需阻止:
Observable.from(audioFiles)
.flatMap(audioFile ->
audioFile.subscribeOn(Schedulers.io()), // <-- apply extra transforms here
MAX_CONCURRENT)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(completedFile -> { }, error -> { },
() -> { /* all completed.*/ })
目前还不清楚你对CallBackWithErrorHandling
做了什么。