我一直在试图弄清楚这一点,这对RXJava来说仍然是新的,但仍然不喜欢它,而是使用Livedata和协程,但无论如何。 我有这个:
Single.just(entity)
.map {
insertDb(it)
return@map it
}
.doOnSubscribe { Timber.d("Updating in database") }
.doOnSuccess { Timber.d("Added row in database") }
.doOnError { Timber.e(it, "Unable to insert object in db") }
fun insertDb(entity: T) {
try {
// basic update or insert database.begingTransaction() and endTransaction()
} catch (e: SQLiteDatabaseLockedException) {}
}
因此,当发生数据库锁定错误时,我想捕获它并使用带有 retryWhen(( 的 Single 重试插入。 我读到的例子非常复杂,不是我想要的。 并且不要担心锁定的数据库内容,这只是我如何捕获数据库错误的一个例子。
您可以使用PublishProcessor
:
val retryProcessor = PublishProcessor.create<Unit>()
Single.just("Entity")
.map { insertDB(it) }
.doOnError { Log.e(TAG, "Error") }
.retryWhen { retryProcessor }
.subscribe { entity -> Log.i(TAG, "Success: $entity") }
插入数据库:
fun insertDB(entity: String): String {
// Insert to DB
return entity
}
每当要执行重试时,请拨打PublishProcessor
上的onNext
:
retryProcessor.onNext(Unit)
如果您只想在流中发生特定异常时重试,则retry(N)
运算符在这里可能会更好。(其中 N 是要重试订阅的最大次数(。
Single.just(entity)
.map {
insertDb(it)
return@map it
}
.retry(1) { e -> e is SQLiteDatabaseLockedException }
您也不想在insertDb()
函数中捕获异常,让它落入错误流中,以便您可以在retry
函数中捕获它。
您可能还需要考虑从insertDb()
返回Single
或Completable
,然后像insertDb(entity).retry(1)...
一样调用它,而不使用返回自身的尴尬map
。
您的insertDb()
函数将变为如下所示:
fun <T> insertDb(entity: T): Completable {
return Completable.fromCallable {
// Insert operation
}
}