Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/204.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
有没有更好的方法在android中用rxjava实现单一真相来源_Android_Rx Java2 - Fatal编程技术网

有没有更好的方法在android中用rxjava实现单一真相来源

有没有更好的方法在android中用rxjava实现单一真相来源,android,rx-java2,Android,Rx Java2,在我的应用程序中,我有使用房间的数据库和使用翻新的网络服务。我有一个要求,如果本地数据库中没有数据,我需要查询网络并显示进度条。如果网络返回空数据,那么我需要显示一个空视图。其中一个问题是,我需要忽略来自房间的空数据,而只考虑服务器的空数据,这样当用户没有任何数据时,他只看到一个加载视图,在服务器返回空数据后,他将看到空视图。 我已经使用发布主题实现了这一点。Lce(加载内容错误)是数据周围的包装对象 val recentPublish = PublishSubject.create<Lc

在我的应用程序中,我有使用房间的数据库和使用翻新的网络服务。我有一个要求,如果本地数据库中没有数据,我需要查询网络并显示进度条。如果网络返回空数据,那么我需要显示一个空视图。其中一个问题是,我需要忽略来自房间的空数据,而只考虑服务器的空数据,这样当用户没有任何数据时,他只看到一个加载视图,在服务器返回空数据后,他将看到空视图。 我已经使用发布主题实现了这一点。Lce(加载内容错误)是数据周围的包装对象

val recentPublish = PublishSubject.create<Lce<List<RecentMessage>>>()

fun loadRecentMessages() {
        loadMessageFromDB()
        loadRecentMessageFromServer()
}
private fun loadMessageFromDB() {
    disposable = recentMessageDao.getRecentMessages() // this is a flowable
        .subscribeOn(Schedulers.io())
        .subscribe({
            Timber.d("recent message from db size ${it.size}")
            handleMessageFromDB(it)
        }, {
            it.printStackTrace()
            Timber.e("error on flowable from db!")
        })
}
protected fun handleMessageFromDB(messages: List<RecentMessage>) {
    // only publish if the data is not empty
    if (messages.isNotEmpty()) {
        recentPublish.onNext(Lce.Content(messages))
    }
}

private fun loadRecentMessageFromServer() {
    recentPublish.onNext(Lce.Loading())
    networkService.getLatestMessage() // this is a single
        .subscribe({
            val parsedMessages =
                DtoConverter.convertRecentPrivateMessageResponse(it, user.id!!)
            handleMessageFromServer(parsedMessages)
        }, {
            it.printStackTrace()
            recentPublish.onNext(Lce.Error(it))
            Timber.w("failed to load recent message for private chat from server")
        })
}

private fun handleMessageFromServer(recentMessages: List<RecentMessage>) {
    Timber.i("recent messages from server ${recentMessages.size}")
    if (recentMessages.isEmpty()) {
        recentPublish.onNext(Lce.Content(arrayListOf()))
    } else {
        recentMessageDao.saveAll(recentMessages)
    }
}
val recentPublish=PublishSubject.create()
有趣的loadRecentMessages(){
loadMessageFromDB()
loadRecentMessageFromServer()
}
private fun loadMessageFromDB(){
一次性=recentMessageDao.getRecentMessages()//这是一个可流动的
.subscribeOn(Schedulers.io())
.订阅({
d(“来自db size${it.size}的最新消息”)
handleMessageFromDB(it)
}, {
it.printStackTrace()
Timber.e(“数据库中可流动的错误!”)
})
}
受保护的fun handleMessageFromDB(消息:列表){
//仅在数据不为空时发布
if(messages.isNotEmpty()){
recentPublish.onNext(Lce.Content(messages))
}
}
private fun loadRecentMessageFromServer(){
recentPublish.onNext(Lce.Loading())
networkService.getLatestMessage()//这是一个
.订阅({
val parsedMessages=
DtoConverter.convertRecentPrivateMessageResponse(it,user.id!!)
handleMessageFromServer(解析消息)
}, {
it.printStackTrace()
recentPublish.onNext(Lce.Error(it))
Timber.w(“无法从服务器加载私人聊天的最新消息”)
})
}
private fun handleMessageFromServer(最近消息:列表){
i(“来自服务器${recentMessages.size}的最近消息”)
if(recentMessages.isEmpty()){
recentPublish.onNext(Lce.Content(arrayListOf()))
}否则{
recentMessageDao.saveAll(recentMessages)
}
}

在上面的代码中,我只是从服务器传递空数据,而忽略了房间中的空数据。这个解决方案有效,但我想知道是否有更好的函数方法来解决这个问题。我是Rxjava的初学者,任何帮助都将不胜感激。谢谢。

经过一些研究和@EpicPandaForce的评论,我想出了这个方法。我学到了很多东西,它让我明白了如何正确使用rxjava。这是我的方法,任何评论都将不胜感激

    fun getMessages(): Observable<Lce<List<RecentMessage>>> {
        return Observable.mergeDelayError(getMessagesFromDB(), getMessagesFromNetwork()) // even if network fails, we still want to observe the DB
    }

    private fun getMessagesFromDB(): Observable<Lce.Content<List<RecentMessage>>> {
        return recentMessageDao.getRecentMessages()
            .filter {
                it.isNotEmpty() // only forward the data from db if it's not empty
            }.map {
                Lce.Content(it)
            }
    }

    private fun getMessagesFromNetwork(): Observable<Lce<List<RecentMessage>>> {
        // first show a loading , then request for data
        return Observable.concat(Observable.just(Lce.Loading()), profileService.getLatestMessage()
                .flatMap {
                    processServerResponse(it) // store the data to db
                }.onErrorReturn {
                    Lce.Error(it)
                }.filter {
                    (it as Lce.Content).packet.isEmpty() // only forward data if it's empty
                })
    }


    private fun processServerResponse(response: RecentMessageResponse): Observable<Lce<List<RecentMessage>>> {
        return Observable.create {
            val parsedMessages =
                DtoConverter.convertRecentPrivateMessageResponse(response, user.id!!)
            handleMessageFromServer(parsedMessages)
            it.onComplete() // we use single source of truth so don't return anyting
        }
    }
fun getMessages():可观察{
return Observable.mergeDelayError(getMessagesFromDB(),getMessagesFromNetwork())//即使网络出现故障,我们仍然希望观察数据库
}
private fun getMessagesFromDB():可观察{
返回recentMessageDao.getRecentMessages()
.过滤器{
it.isNotEmpty()//仅当数据不为空时才从db转发数据
}.地图{
Lce.内容(it)
}
}
private fun getMessagesFromNetwork():可观察{
//首先显示加载,然后请求数据
返回Observable.concat(Observable.just(Lce.load()),profileService.getLatestMessage()
.平面图{
processServerResponse(it)//将数据存储到数据库
}A.报税表{
Lce.错误(it)
}.过滤器{
(它作为Lce.Content.packet.isEmpty()//仅在数据为空时转发数据
})
}
private fun processServerResponse(响应:RecentMessageResponse):可观察{
返回可观察的。创建{
val parsedMessages=
DtoConverter.convertRecentPrivateMessageResponse(响应,user.id!!)
handleMessageFromServer(解析消息)
it.onComplete()//我们使用单一的真相来源,因此不返回任何消息
}
}

你使用多个独立订阅来进行顺序操作,这会导致竞争条件,考虑使用<代码>平面图{<代码> >运算符。甚至可以<代码>平面图。{
网络请求,然后
将该响应+以前的DB数据映射成
。感谢您的响应@EpicPandaForce,我是rxjava的初学者,所以我很难想出如何做。如果您有时间,请您提供一些代码来帮助我。
flatMap
谢谢@我想我已经猜到了。我已经发布了我的答案,我认为它很好。