RxJava结合Room插入数据后无法触发subscribe回调问题求助
问题分析与解决方案
核心错误点
andThen用法错误:你在第二个andThen中传入了普通lambda,但andThen要求接收ObservableSource类型(如Completable/Single)。如果uploadUserData不是返回Rx类型的Observable,这个lambda无法生成有效的流,直接导致整个序列卡住,无法触发后续的subscribe回调。- 可变变量传递值不符合Rx设计:用
var rowId保存插入ID是命令式写法,存在线程安全隐患,也违背了Rx响应式数据流的设计原则。 - 流序列逻辑断裂:即使插入操作完成,上传操作的执行没有被纳入Rx流的调度中,导致流无法正常向下传递事件。
修正方案(分场景)
根据uploadUserData的返回类型,选择对应的写法:
场景1:uploadUserData是阻塞方法(返回void)
直接在Single.fromCallable中同步执行插入和上传,最后返回ID:
@Insert(onConflict = OnConflictStrategy.REPLACE) fun saveUserData(date: UserDataDatabaseModel): Long override fun submitUserData(): Single<Long> { return Single.fromCallable { // 执行Room插入,获取ID val rowId = dao.saveUserData(getUserData()) // 阻塞执行上传 uploadUserData(rowId) // 返回ID rowId } }
场景2:uploadUserData返回Completable
用flatMap串联插入和上传操作,上传完成后返回ID:
override fun submitUserData(): Single<Long> { return Single.fromCallable { dao.saveUserData(getUserData()) }.flatMap { rowId -> // 上传完成后,将Completable转为Single并返回ID uploadUserData(rowId).toSingleDefault(rowId) } }
场景3:uploadUserData返回Single<UploadResult>
忽略上传结果,直接映射回插入的ID:
override fun submitUserData(): Single<Long> { return Single.fromCallable { dao.saveUserData(getUserData()) }.flatMap { rowId -> // 执行上传后,映射回插入ID uploadUserData(rowId).map { rowId } } }
调用代码无需修改
你的调用处代码逻辑正确,保持原样即可:
submitUserData() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .doOnError { throwable -> throwable.printStackTrace() } .subscribe({ rowId -> // handle rowId },{ // handle error })
内容的提问来源于stack exchange,提问作者eoinzy
相关产品推荐
相关产品推荐

