面试题答案
一键面试原理
- Kotlin 协程异常处理:Kotlin 协程通过
try - catch
块来捕获异常,在协程构建器(如launch
、async
)中未处理的异常会导致协程取消。如果是根协程,异常会传播到CoroutineExceptionHandler
。 - RxJava 异常处理:RxJava 通过
onError
方法来处理异常,subscribe
时传入的Observer
或Consumer
可以处理异常。在链式调用中,可以通过onErrorResumeNext
、retry
等操作符来处理异常。 - 统一处理原理:为了统一处理异常,需要在从 Kotlin 协程转到 RxJava 以及转回 Kotlin 协程的过程中,确保异常能够正确传递和处理。在 Kotlin 协程转 RxJava 时,需要将协程的异常转换为 RxJava 的
onError
事件;在 RxJava 转 Kotlin 协程时,需要将 RxJava 的onError
事件转换为协程能够捕获的异常。
代码实现
- Kotlin 协程转 RxJava:
import kotlinx.coroutines.* import io.reactivex.rxjava3.core.Observable import io.reactivex.rxjava3.kotlin.subscribeBy fun main() = runBlocking { val result = try { val data = async { // 模拟可能抛出异常的操作 if (Math.random() < 0.5) { throw RuntimeException("协程内抛出异常") } "协程数据" }.await() Observable.just(data) } catch (e: Exception) { Observable.error(e) } result.subscribeBy( onNext = { println("RxJava 接收到数据: $it") }, onError = { println("RxJava 接收到异常: ${it.message}") } ) }
- RxJava 转 Kotlin 协程:
import kotlinx.coroutines.* import io.reactivex.rxjava3.core.Observable import io.reactivex.rxjava3.kotlin.subscribeBy fun main() = runBlocking { val result = suspendCoroutine<String> { continuation -> Observable.create<String> { emitter -> if (Math.random() < 0.5) { emitter.onError(RuntimeException("RxJava 内抛出异常")) } else { emitter.onNext("RxJava 数据") emitter.onComplete() } }.subscribeBy( onNext = { continuation.resume(it) }, onError = { continuation.resumeWithException(it) } ) } try { println("协程接收到数据: $result") } catch (e: Exception) { println("协程接收到异常: ${e.message}") } }
通过上述代码实现,可以在 Kotlin 协程与 RxJava 混合使用的场景下,较为统一地处理可能出现的异常,保证异步流程的健壮性和稳定性。