我正在使用“RxJava”,“Room”,“Firebase(Firestore)”和“Kotlin”开发一个Android应用程序。它基于MVP模式。我是RxJava的新手,所以我需要帮助...对我来说很难情况是...1.演示者请求用户访问DAO(本地数据库- session 室)2. DAO返回一个用户 2.1如果不存在用户,则演示者请求用户使用Firebase(Firestore)3.演示者使用户返回到 View 。代码在这里:[1]@Daointerface PlayersDao { @Query("SELECT * FROM player WHERE playerName = :playerName") fun getPlayerByName(playerName: String): Single<Player>}[2] Firebaseclass FirebaseDataSource { private val mFirestore = FirebaseFirestore.getInstance() override fun getPlayerByName(playerName: String) = Single.create<Player> { emitter -> mFirestore.collection(PLAYERS) .whereEqualTo("playerName", playerName) .get() .addOnCompleteListener { if (it.isSuccessful && !it.result.isEmpty) { emitter.onSuccess(it.result.documents[0].toObject(Player::class.java)) } else { emitter.onError(PlayerNotExistException()) } } }}[3]主持人fun getPlayer(playerName: String): Single<Player> { return Single.create { emitter -> playerDao.getPlayerByName(playerName) .doOnError { // When it failed to get the user from local, it should retry to Firebase. // But I don't know how should I cover this logic. Single.create<Player> { emitter2 -> firebaseDataSource.getPlayerByName(playerName) .doOnError { Log.d(TAG, "getPlayerByName(firebase) - failed") } .doOnSuccess { emitter.onSuccess(it) } } } .doOnSuccess { Log.d(TAG, "getPlayerByName(local) - success") emitter.onSuccess(it) } }}我不知道当无法从本地数据库获取用户时应该如何获取并返回用户。而“单例”是正确的吗?我应该使用“可观察”还是“可流动”?这是一个连续的问题。我固定了如下代码:主持人fun getPlayer(playerName: String): Single<Player> { Log.d(TAG, "getPlayerByName - $playerName") return playerDao.getPlayerByName(playerName) .onErrorResumeNext { Log.d(TAG, "[BS] getPlayerByName(local) - onError: ${it.message}") playersFirebaseDataSource.getPlayerByName(playerName) .doOnSuccess { Log.d(TAG, "getPlayerByName(firebase) - success") playerDao.savePlayer(it) // Here is run in "Main" thread }.subscribeOn(Schedulers.io()) }} playerDao.savePlayer(it)此代码应在后台线程中。但事实并非如此。我该怎么办? (adsbygoogle = window.adsbygoogle || []).push({}); 最佳答案 您正在寻找“onErrorResumeNext”运算符。从文档: onErrorResumeNext( ) — instructs an Observable to emit a sequence of items if it encounters an error.因此可能看起来像这样:return playerDao.getPlayerByName(playerName) .onErrorResumeNext(firebaseDataSource.getPlayerByName(playerName))这基本上是尝试DAO单一文件,如果遇到错误,它将切换到FirebaseDataSource单一文件。编辑:您可以在Here中找到其他错误处理运算符编辑2:关于第二个问题,您使用observeOn是正确的,它将在特定的调度程序上切换工作,但是您还使用了可能有害的subscribeOn,这就是为什么subscribeOn仅打算使用一次,它指定您将在其中“观察”可观察对象的线程,通常与AndroidSchedulers.mainThread()一起使用。我建议通过Here阅读有关该主题的更多信息 (adsbygoogle = window.adsbygoogle || []).push({});
08-26 09:27