如何确保数据库操作完成后再跳转至其他Fragment
解决方案
核心思路就是把数据库操作的回调切换到主线程执行,这样就能安全在操作完成后做Fragment跳转了,具体实现可以按下面几步来:
1. 调整Room DAO方法返回RxJava类型
把你的Room DAO中更新用户的方法改成返回Completable(更新操作不需要返回数据,只需要确认执行完成),示例代码:
@Dao interface UserDao { @Update fun updateUser(user: User): Completable }
2. 用RxJava线程调度控制回调线程
在登录Fragment调用数据库操作时,通过subscribeOn指定操作在后台线程执行,再用observeOn(AndroidSchedulers.mainThread())把回调(包括onComplete())切换到主线程,这样就能在onComplete()里安全执行Fragment跳转:
// 用CompositeDisposable管理订阅,避免内存泄漏 private val disposables = CompositeDisposable() fun handleLoginSuccess(user: User, token: String) { // 给用户对象设置token后更新到数据库 user.token = token userDao.updateUser(user) .subscribeOn(Schedulers.io()) // 数据库操作放在IO线程执行 .observeOn(AndroidSchedulers.mainThread()) // 把回调切换到主线程 .subscribe( { // onComplete回调:数据库操作完成后跳转页面 findNavController().navigate(R.id.action_loginFragment_to_accountFragment) }, { error -> // 处理更新失败的情况,比如弹出提示 Toast.makeText(requireContext(), "用户信息更新失败: ${error.message}", Toast.LENGTH_SHORT).show() } ).let { disposables.add(it) } } // 在Fragment销毁时清理订阅,防止内存泄漏 override fun onDestroyView() { super.onDestroyView() disposables.clear() }
3. 额外注意点
- 如果之前的Room DAO方法返回的是
Unit或非RxJava类型,必须改成Completable/Single这类RxJava类型,才能利用其线程调度能力。 - 务必用
CompositeDisposable管理所有RxJava订阅,在Fragment生命周期结束时清理,避免内存泄漏。
内容的提问来源于stack exchange,提问作者JustSightseeing
相关产品推荐
相关产品推荐

