Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/180.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用RxJava同时从本地和远程获取数据_Java_Android_Kotlin_Rx Java_Rx Android - Fatal编程技术网

使用RxJava同时从本地和远程获取数据

使用RxJava同时从本地和远程获取数据,java,android,kotlin,rx-java,rx-android,Java,Android,Kotlin,Rx Java,Rx Android,因此,我是RxJava的初学者,但我想实现以下目标: MainViewModel与存储库对话。存储库既有LocalDataStore(与数据库对话)也有RemoteDataStore(改进),两者都是接口数据存储的不同实现 我想要实现的是,通过一次调用从存储库中获取数据,返回一个可观察的但: 它首先从RemoteDataStore获取数据 在获取每一项内容(onNext())后,它将其插入数据库 如果失败,它将从LocalDataStore返回结果 然而,我不知道如何实现这个逻辑。订阅发生在

因此,我是RxJava的初学者,但我想实现以下目标:

MainViewModel与存储库对话。存储库既有LocalDataStore(与数据库对话)也有RemoteDataStore(改进),两者都是接口数据存储的不同实现

我想要实现的是,通过一次调用从存储库中获取数据,返回一个可观察的但:

  • 它首先从RemoteDataStore获取数据
  • 在获取每一项内容(onNext())后,它将其插入数据库
  • 如果失败,它将从LocalDataStore返回结果
然而,我不知道如何实现这个逻辑。订阅发生在ViewModel的一端,但我无法真正将可观测数据从存储库端(?)更改为LocalDataStore。将数据上传到数据库中也会返回一个可观察的(准确地说是单一的)数据,要使其工作,需要订阅

有人能给我解释一下或者给我指出一个好的方向吗

我的代码(存储库注释中的问题):

远程数据存储

 override fun getData(): Observable<SomeData> = api
    .getData(token)
    .flatMapIterable { x -> x }
override fun saveData(data: SomeData): Single<SomeData> {
    return database.upsert(data)
}

谢谢您的时间。

OneRorResumeNext
是您需要的
DoError
调用一个副作用操作,不会用另一个方法替换原来的
Observable

您需要使用其中一个方法。我还建议将流类型从
Observable
更改为
Single
,因为数据的性质似乎是一次性获取数据或抛出错误。这只是一个很好的API设计

在您的特定情况下,我将以以下方式实现存储库:

class RepositoryImpl @Inject constructor(private val localRepository: Repository, private val remoteRepository: Repository) : Repository {
    override fun getData(): Single<Data> = remoteRepository.getData()
        .onErrorResumeNext { throwable ->
            if (throwable is IOException) {
                return localRepository.getData()
            }
            return Single.error(throwable)
        }
}
class RepositoryImpl@Inject构造函数(private val localRepository:Repository,private val remoteRepository:Repository):Repository{
override fun getData():Single=remoteRepository.getData()
.onErrorResumeNext{可丢弃->
if(可丢弃为IOException){
返回localRepository.getData()
}
返回单个。错误(可丢弃)
}
}

您可能会问,为什么只捕获
IOException
?我通常只处理这个异常,以避免遗漏任何重要的网络错误,但只忽略不重要的网络错误。如果您能捕捉到您可能错过的每一个异常,例如,
NullPointerException

谢谢您的回答。我还不确定下一个电话的语法,所以也许你可以帮我。将您的代码与指定的throwable一起使用(所以t:throwable->{…}),我得到一个错误,即那里不允许返回。有没有其他方法可以让我通过调用一个函数来保存东西,该函数同时返回一个可观察的?dabu您是否更改了本地和远程存储库的返回类型?确保是单身。如果没有帮助,那么是否可以创建GitHub gist?好让我看看。谢谢你的帮助。实际上,我已经成功地获得了想要的行为,但是我还不知道为什么它会起作用。下面是代码的要点:我需要添加注释并订阅保存。当然,它还没有完成(我将实现一些错误检查),但它可以工作。我需要用Rx对自己进行更多的教育,以完全理解此代码,但如果我愿意的话tips@dabu我的错。我忘了科特林的行为。看看和。谢谢你的帮助。你当然是对的,我对此表示感谢,但我已将@andrei_zaitcev的回答标记为已接受,因为它使我更清楚地理解了问题。我希望一切都好!干杯@大步你可以自由地接受任何你喜欢的答案;谢谢你的评论。
override fun fetchData() {
repository.getData()
        .observeOn(androidScheduler)
        .subscribeOn(threadScheduler)
        .subscribe(
                { data: SomeData ->
                    dataList.add(data)
                },
                { throwable: Throwable? ->
                    handleError(throwable)
                },
                {
                    //send data to view
                },
                { disposable: Disposable ->
                    compositeDisposable.add(disposable)
                }
        )
}
class RepositoryImpl @Inject constructor(private val localRepository: Repository, private val remoteRepository: Repository) : Repository {
    override fun getData(): Single<Data> = remoteRepository.getData()
        .onErrorResumeNext { throwable ->
            if (throwable is IOException) {
                return localRepository.getData()
            }
            return Single.error(throwable)
        }
}