RxJava在emmited items

时间:2017-12-02 17:59:00

标签: rx-java2

我不确定我是否正确地表达了问题,这就是我正在做的事情:下载图像(如果需要)应用一些效果(模糊)并将其设置为设备壁纸:

data class SetWallpaperIntent(val bitmap : Bitmap?, val url : String)

setWallpaperObservable.switchMap { setWallpaperIntent ->
    if (setWallpaperIntent.bitmap == null) {
        downloader.DownloadWallpaper(setWallpaperIntent.url)
            .flatMap {
                if (it is Result.Download.Success) {
                    Observable.just(setWallpaperIntent.copy(bitmap = it.bitmap))
                                            .compose(::blurWallpaper)
                                            .compose(::setWallpaper)
                                            .startWith(Observable.just(it))
                } else {
                    //Result.Download.Progress / Result.Download.Error events
                    Observable.just(it)
                }
            }
    } else {
        Observable.just(it)
            .compose(::blurWallpaper)
            .compose(::setWallpaper)
    }
}

此代码按预期工作,但我不喜欢这种方法:

  1. 我重复代码.compose(::blurWallpaper).compose(::setWallpaper)
  2. 我创建了很多单项可观察项Observable.just(it)
  3. 所以,我的问题是......是否有更好的方法来实现我想要做的事情。或者我的方法是正确的吗?

    顺便说一句,我还考虑过使用.publish()运算符,代码没有太大改进

1 个答案:

答案 0 :(得分:2)

您可以定义一个返回图像的通用方法,无论它是已存储在本地还是需要下载。它始终是Observable<Image>

Observable<Image> getWallpaper(url) {
    if(imageExists(url)) {
        return Observable.just(getAlreadyDownloadImage(url));
    } else {
        return downloadWallpapaer();
    }
}

downloadWallpapaer有这个签名的地方:

Observable<Image> downloadWallpapaer(String url);

您还可以使用这些签名定义两种方法:

Image blurWallpaper(Image image);

void setWallpaper(Image image);

然后你把所有人放在一起:

getWallpaper(url).map(image -> blurWallpaper(image))
                    .subscribe(image -> setWallpaper(image));

在我看来,在链的末尾应用壁纸是有意义的,因为你正在消耗这些数据,你不仅仅是在改造了。这是我把它放在subscribe部分的方式。