Android 我该如何返回;“可观察/可流动/单一”&引用;onError";在嵌套代码中?
我正在使用“RxJava”、“Room”、“Firebase(Firestore)”和“Kotlin”开发一个Android应用程序。 它基于MVP模式 我是RxJava的新手,所以我需要帮助。。。 这对我来说很难 情况是。。。 1.演示者向DAO请求用户(本地数据库室) 2.DAO返回一个用户 2.1如果用户不存在,演示者将向Firebase(Firestore)请求用户 3.演示者返回要查看的用户 代码如下: [1] 刀Android 我该如何返回;“可观察/可流动/单一”&引用;onError";在嵌套代码中?,android,firebase,kotlin,rx-java,android-room,Android,Firebase,Kotlin,Rx Java,Android Room,我正在使用“RxJava”、“Room”、“Firebase(Firestore)”和“Kotlin”开发一个Android应用程序。 它基于MVP模式 我是RxJava的新手,所以我需要帮助。。。 这对我来说很难 情况是。。。 1.演示者向DAO请求用户(本地数据库室) 2.DAO返回一个用户 2.1如果用户不存在,演示者将向Firebase(Firestore)请求用户 3.演示者返回要查看的用户 代码如下: [1] 刀 @Dao interface PlayersDao { @Qu
@Dao
interface PlayersDao {
@Query("SELECT * FROM player WHERE playerName = :playerName")
fun getPlayerByName(playerName: String): Single<Player>
}
@Dao
接口PlayersDao{
@查询(“从playerName=:playerName的播放器中选择*)
趣味getPlayerByName(playerName:String):单曲
}
[2] 火基
class 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())
}
}
}
}
类FirebaseDataSource{
private val mFirestore=FirebaseFirestore.getInstance()
覆盖有趣的getPlayerByName(playerName:String)=Single.create{emitter->
mFirestore.collection(播放器)
.whereEqualTo(“playerName”,playerName)
.get()
.addOnCompleteListener{
if(it.issusccessful&&!it.result.isEmpty){
emitter.onSuccess(it.result.documents[0].toObject(Player::class.java))
}否则{
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.create{emitter->
playerDao.getPlayerByName(playerName)
杜恩先生{
//当无法从本地获取用户时,应重试Firebase。
//但我不知道我该怎么解释这个逻辑。
Single.create{emitter2->
firebaseDataSource.getPlayerByName(playerName)
杜恩先生{
Log.d(标记“getPlayerByName(firebase)-失败”)
}
杜恩塞斯先生{
发射器。onSuccess(it)
}
}
}
杜恩塞斯先生{
Log.d(标记“getPlayerByName(本地)-成功”)
发射器。onSuccess(it)
}
}
}
我不知道当从本地数据库获取用户失败时,应该如何获取并返回用户
“单身”是正确的吗?
我应该使用“可观察”还是“可流动”
你在找“下一个”接线员。
从文档中:
下一个( ) — 指示可观察对象在遇到错误时发出一系列项
所以它可能看起来像这样:
return playerDao.getPlayerByName(playerName)
.onErrorResumeNext(firebaseDataSource.getPlayerByName(playerName))
这基本上是尝试DAO单,如果遇到错误,它将切换到FirebaseDataSource单
编辑:您可以在中找到其他错误处理运算符
编辑2:至于第二个问题,您可以使用observeOn
切换特定计划程序上的工作,但您也使用了可能有害的subscribeOn
,这就是为什么subscribeOn
只能使用一次,它指定了“观察”的线程可观察的,它通常与AndroidSchedulers.mainThread()
一起使用
我建议通过阅读更多关于这个主题的内容。为了解决这个连续的问题,我自己修改了代码
fun getPlayer(playerName: String): Single<Player> {
return playerDao.getPlayerByName(playerName)
.onErrorResumeNext {
Log.d(TAG, "getPlayerByName(local) - onError: ${it.message}")
playersFirebaseDataSource.getPlayerByName(playerName)
.subscribeOn(Schedulers.io()) // I added this two line
.observeOn(Schedulers.io()) // And it works fine.
.doOnSuccess {
Log.d(TAG, "getPlayerByName(firebase) - success")
playerDao.savePlayer(it) // Now, here is run in the background thread!
}.subscribeOn(Schedulers.io())
}
}
fun getPlayer(playerName:String):单人{
return playerDao.getPlayerByName(playerName)
.下一个{
Log.d(标记“getPlayerByName(本地)-onError:${it.message}”)
playerFireBaseDataSource.getPlayerByName(playerName)
.subscribeOn(Schedulers.io())//我添加了这两行
.observeOn(Schedulers.io())//并且工作正常。
杜恩塞斯先生{
Log.d(标记“getPlayerByName(firebase)-成功”)
playerDao.savePlayer(it)//现在,这里是在后台线程中运行的!
}.subscribeOn(Schedulers.io())
}
}
Ahmed Ashraf G,我修正了它,我还有一个问题。你能回答我吗?@yoonhok是的,当然我在这里添加了额外的问题,你能检查一下吗?你自己想得很好:)我编辑了我的答案,希望它能帮上忙。真的谢谢你:)你的评论对我很有帮助。
fun getPlayer(playerName: String): Single<Player> {
return playerDao.getPlayerByName(playerName)
.onErrorResumeNext {
Log.d(TAG, "getPlayerByName(local) - onError: ${it.message}")
playersFirebaseDataSource.getPlayerByName(playerName)
.subscribeOn(Schedulers.io()) // I added this two line
.observeOn(Schedulers.io()) // And it works fine.
.doOnSuccess {
Log.d(TAG, "getPlayerByName(firebase) - success")
playerDao.savePlayer(it) // Now, here is run in the background thread!
}.subscribeOn(Schedulers.io())
}
}