如何在原生Android项目中调用KMM共享模块的Reaktive SingleWrapper?
解决方案
错误原因分析
编译错误的核心是Android模块未引入Reaktive核心依赖,SingleWrapper是Reaktive库的类型,Android端classpath中缺少该库的相关类,导致无法识别其超类Source和Single。
方案1:直接让Android依赖Reaktive(快速解决)
如果团队可以接受Android端使用Reaktive库,只需在Android模块的build.gradle中添加与Shared模块版本一致的Reaktive依赖:
// Android模块build.gradle dependencies { // 版本号需与Shared模块中使用的Reaktive版本保持一致 implementation "com.badoo.reaktive:reaktive:1.2.3" implementation "com.badoo.reaktive:single:1.2.3" }
添加后,Android端即可直接调用SingleWrapper的subscribe()方法,与Shared模块的实现保持一致:
val assignedBooks = SharedBookRepository().getAssignedBooks() assignedBooks.subscribe( onSuccess = { books -> /* 处理成功逻辑 */ }, onError = { error -> /* 处理错误逻辑 */ } )
方案2:用RxJava2-Interop实现平台适配(符合Android原生习惯)
若Android团队更倾向于使用RxJava2而非Reaktive,可通过rxjava2-interop库将Reaktive的Single转换为RxJava2的Single,同时通过KMM的expect/actual机制实现跨平台类型适配:
步骤1:定义跨平台通用类型
在Shared模块的commonMain中定义平台无关的BookSingle接口:
// commonMain/kotlin/.../BookSingle.kt expect class BookSingle<T> { fun subscribe( onSuccess: (T) -> Unit, onError: (Throwable) -> Unit ) }
步骤2:实现Android端适配(RxJava2)
在Shared模块的androidMain中,使用rxjava2-interop将Reaktive Single转换为RxJava2 Single,并实现BookSingle:
// androidMain/kotlin/.../BookSingle.kt import com.badoo.reaktive.rxjava2interop.asRxJava2Single import io.reactivex.Single actual class BookSingle<T> actual constructor(private val rxSingle: Single<T>) { actual fun subscribe(onSuccess: (T) -> Unit, onError: (Throwable) -> Unit) { rxSingle.subscribe(onSuccess, onError) } } // 同时修改getAssignedBooks方法 fun getAssignedBooks(): BookSingle<List<String>> { val reaktiveSingle = singleFromCoroutine { callAssignedBooks() } .subscribeOn(ioScheduler) .observeOn(mainScheduler) return BookSingle(reaktiveSingle.asRxJava2Single()) }
步骤3:实现iOS端适配(SingleWrapper)
在Shared模块的iosMain中,直接包装Reaktive的SingleWrapper实现BookSingle:
// iosMain/kotlin/.../BookSingle.kt import com.badoo.reaktive.single.SingleWrapper actual class BookSingle<T> actual constructor(private val singleWrapper: SingleWrapper<T>) { actual fun subscribe(onSuccess: (T) -> Unit, onError: (Throwable) -> Unit) { singleWrapper.subscribe( onSuccess = onSuccess, onError = onError ) } } // 修改getAssignedBooks方法 fun getAssignedBooks(): BookSingle<List<String>> { val reaktiveSingle = singleFromCoroutine { callAssignedBooks() } .subscribeOn(ioScheduler) .observeOn(mainScheduler) .wrap() return BookSingle(reaktiveSingle) }
步骤4:添加依赖
在Shared模块和Android模块的build.gradle中添加interop依赖:
// Shared模块build.gradle dependencies { implementation "com.badoo.reaktive:rxjava2-interop:1.2.3" } // Android模块build.gradle dependencies { implementation "io.reactivex.rxjava2:rxjava:2.2.21" // 若未引入RxJava2需添加 }
步骤5:原生端调用
- Android端:拿到的是适配后的RxJava2风格的
BookSingle,可直接按RxJava2习惯调用:SharedBookRepository().getAssignedBooks().subscribe( onSuccess = { books -> /* 处理书籍列表 */ }, onError = { e -> /* 处理异常 */ } ) - iOS端:
BookSingle会被映射为Swift可调用的类型,直接使用即可:SharedBookRepository().getAssignedBooks().subscribe( onSuccess: { books in /* 处理逻辑 */ }, onError: { error in /* 处理错误 */ } )
内容的提问来源于stack exchange,提问作者AndreiBogdan
相关产品推荐
相关产品推荐

