我正在使用Compressor库,我想使用RxJava压缩图像。以下是图书馆文档中的示例。
new Compressor(this)
.compressToFileAsFlowable(actualImage)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<File>() {
@Override
public void accept(File file) {
compressedImage = file;
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) {
throwable.printStackTrace();
showError(throwable.getMessage());
}
});
这非常有效。现在我想压缩一个图像列表,我如何使用这种技术来获取压缩文件路径列表?
我尝试在for循环中添加此方法但返回的列表为空,因为accept方法甚至没有调用一次,代码到达return语句。以下是我的方法
@NonNull
private ArrayList<String> compressFiles(ArrayList<String> files, File directory) {
final ArrayList<String> filesToReturn = new ArrayList<>();
for (final String filepath : files) {
new Compressor(this)
.compressToFileAsFlowable(new File(filepath))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<File>() {
@Override
public void accept(File file) {
filesToReturn.add(file.getAbsolutePath());
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) {
throwable.printStackTrace();
}
});
}
return filesToReturn;
}
如何使用RxJava更改此方法,因此只有在压缩所有文件并填充列表后才会触发accept方法?
我尝试搜索RxJava循环/ Flatmap但我无法弄清楚它们。我是RxJava的新手。任何帮助或指示都将受到高度赞赏。
答案 0 :(得分:0)
在RxJava中,您将使用Observable.fromIterable():
Observable.fromIterable(files)
.flatMapIterable(files -> files)
.flatMap(filepath -> new Compressor(this).compressToFileAsFlowable(new File(filepath)))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<File>() {
@Override
public void accept(File file) {
compressedImage = file;
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) {
throwable.printStackTrace();
showError(throwable.getMessage());
}
});
答案 1 :(得分:0)
以下是两个可能的结果:
处理完所有图像后,将调用Completable
Flowable会在完成处理(荣誉背压)后将结果推送给订阅者
请查看subscribeOn。我使用计算调度程序,因为cpu绑定工作应该在有界线程池上执行。 IO是无限的。
当您订阅Completeable或Flowable时,您必须将observeOn应用于Android-MainUI-Scheduler。
Rember只有在状态改变时才能订阅Flowable / Observable。否则一起组成观察者。
// Will call complete, when all files finish
private Completable compressFiles(ArrayList<String> files) {
return Flowable.fromIterable(files)
.subscribeOn(Schedulers.io())
.map(new Function<String, File>() {
@Override
public File apply(String s) throws Exception {
return Paths.get(s).toFile();
}
})
.flatMapCompletable(new Function<File, CompletableSource>() {
@Override
public CompletableSource apply(File file) throws Exception {
return new Compressor(appContext)
.compressToFileAsFlowable(file)
.singleOrError()
.toCompletable();
}
});
}
// Will push each file to subscriber as one finishes
private Flowable<File> compressFiles2(ArrayList<String> files) {
return Flowable.fromIterable(files)
.subscribeOn(Schedulers.io())
.map(new Function<String, File>() {
@Override
public File apply(String s) throws Exception {
return Paths.get(s).toFile();
}
})
.flatMap(new Function<File, Publisher<? extends File>>() {
@Override
public Publisher<? extends File> apply(File file) throws Exception {
return new Compressor(appContext)
.compressToFileAsFlowable(file)
.subscribeOn(Schedulers.computation());
}
});
}