Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/228.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、Room和改装实现单一真实源(SSOT)_Android_Retrofit_Rx Java_Room - Fatal编程技术网

Android 使用RxJava、Room和改装实现单一真实源(SSOT)

Android 使用RxJava、Room和改装实现单一真实源(SSOT),android,retrofit,rx-java,room,Android,Retrofit,Rx Java,Room,我使用房间作为数据库,从网络API加载数据并存储在数据库中。我想将数据库用作单一真相来源(SSOT)。我已经创建了一个使用Room和LiveData实现此体系结构的函数 这是我的应用程序场景: 从数据库加载存储的数据(如果存在)并更新UI 从API加载更新的数据 将数据保存到数据库中 当本地数据更新时自动更新UI 在这个函数中,我从本地数据创建一个LiveData实例,并使用emitSource()发出数据。然后,我只需要从网络加载数据并将其保存到数据库中,我的LiveData将自动被UI使用的

我使用房间作为数据库,从网络API加载数据并存储在数据库中。我想将数据库用作单一真相来源(SSOT)。我已经创建了一个使用Room和LiveData实现此体系结构的函数

这是我的应用程序场景:

  • 从数据库加载存储的数据(如果存在)并更新UI
  • 从API加载更新的数据
  • 将数据保存到数据库中
  • 当本地数据更新时自动更新UI
  • 在这个函数中,我从本地数据创建一个LiveData实例,并使用
    emitSource()
    发出数据。然后,我只需要从网络加载数据并将其保存到数据库中,我的LiveData将自动被UI使用的更新数据触发

    这是我的功能

    fun <T, A> resultLiveData(
        databaseQuery: () -> LiveData<T>,
        networkCall: suspend () -> Response<A>,
        saveCallResult: suspend (A) -> Unit
    ): LiveData<Result<T>> = liveData(Dispatchers.IO) {
        // emit Loading status
        emit(Result.loading<T>())
    
        // emit data from database
        val localSource = databaseQuery.invoke().map { Result.success(it) }
        emitSource(localSource)
    
        // try loading data from network and handle possible network errors
        val response = getResult { networkCall.invoke() }
        if (response.status == Result.Status.SUCCESS) {
            /* save data loaded from network into database. as we are using LiveData
               observers will be automatically triggered on database change */
            saveCallResult(response.data!!)
        } else if (response.status == Result.Status.ERROR) {
            emit(Result.error<T>(response.message, response.error))
        }
    }
    
    我不是RxJava的专业人士,所以请给我一个好的解决方案

    fun <T, A> resultObservable(
        databaseQuery: () -> Observable<T>,
        networkCall: () -> Response<A>,
        saveCallResult: (A) -> Unit
    ): Observable<Result<T>> = Observable.create(ObservableOnSubscribe<Result<T>> { emitter ->
        // emit Loading status
        emitter.onNext(Result.loading<T>())
    
        // emit data from database
        databaseQuery.invoke().doOnNext {
            emitter.onNext(Result.success(it))
        }.subscribe()
    
    
        // try loading data from network and handle possible network errors
        val response = getResult2 { networkCall.invoke() }
        if (response.status == Result.Status.SUCCESS) {
            /* save data loaded from network into database. as we are using LiveDataz
               observers will be automatically triggered on database change */
            saveCallResult(response.data!!)
        } else if (response.status == Result.Status.ERROR) {
    //        emitter.onNext(Result.error<T>(response.message, response.error))
            emitter.onError(response.error)
        }
    
    }).subscribeOn(Schedulers.io())