RxJava 2可能带有Observable

时间:2017-06-29 19:03:13

标签: android rx-java rx-android maybe

我有一个简单的案例我试图用rxJava 2但是我被卡住了。

我有一个locationProvider,它返回一个Maybe(某些带有LatLng的模型)。每次用户点击按钮时,我想获取他当前的位置并将位置保存到数据库。

要清楚, RxView.clicks(save_btn)应该在MainThread上,位置和db save应该在异步线程上,响应应该返回到mainThread。

我该怎么做?

 addDisposeable(RxView.clicks(save_btn)
            .flatMap { locationProvider.getLastKnowLocation().toObservable() }
            .map {
                val place = Place(UUID.randomUUID().toString(), "test-address", it.latLng)
                db.placeDao().insertAll(place)
            }
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe({
                Toast.makeText(this@AddPlaceActivity, "saved", Toast.LENGTH_SHORT).show()
            }, { throwable -> Timber.e(throwable) }))

我也尝试将其简化为:

 RxView.clicks(save_btn).share()
                    .flatMap { locationProvider.getLastKnowLocation().toObservable() }
                    .subscribe({
                        val place = Place(UUID.randomUUID().toString(), "test-address", it.latLng)
                        db.placeDao().insertAll(place)
                        Timber.d("place-saved")
                    }, { throwable -> Timber.e(throwable) }))

但是此代码仅在第一次点击时执行,并且不会继续执行。 它是由于Maybe.toObservable()吗?该如何解决? 谢谢你的帮助。

这是locationProvider的代码,我使用RxLocation:

fun getLastKnowLocation(): Maybe<LocationData> {
    return rxLocation.location()
            .lastLocation()
            .map {
                val address = geocoder.getFromLocation(it.latitude, it.longitude, 1).first()
                val latlng = LatLng(it.latitude, it.longitude)
                LocationData(latlng, address)
            }
}

1 个答案:

答案 0 :(得分:0)

不幸的是,将我置于正确路径的用户删除了他的答案:(

这就是我最终的结果

addDisposeable(
            RxView.clicks(save_btn).share()
                    .observeOn(Schedulers.computation())
                    .withLatestFrom(locationProvider.getLastKnowLocation().toObservable(), BiFunction { _:Any, l:LocationData -> l })
                    .map {
                        val place = Place(UUID.randomUUID().toString(), "test-address", it.latLng)
                        db.placeDao().insertAll(place)
                    }
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe({
                        Timber.d("place-saved")
                    }, { throwable -> Timber.e(throwable) }))

如果有人有更好的东西,我找不到'BiFunction'部分更好的方法。 另请注意,您需要为线程切换部件调用observeOn两次。