微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么当我的 Activity 暂停时,我的 Android ViewModel 的 Room RxJava3 Flowable 没有发布任何结果?

如何解决为什么当我的 Activity 暂停时,我的 Android ViewModel 的 Room RxJava3 Flowable 没有发布任何结果?

我知道这是一个复杂的问题,如果不发布几百行代码就无法得到明确的答案,这就是为什么我要通过一般的想法和指示寻求帮助。

我有一个房间 @Query 返回我在 RxJava 线程 Flowable<List<...>>订阅的 RxJava3 Schedulers.io(),并从 RxJava 线程 {{ 上的活动范围 viewmodel 观察1}}。然后将数据作为 AndroidSchedulers.mainThread() 存储在我的 viewmodel 中,在处理 Android 组件的生命周期方面,它比 RxJava 表现得更好。

这个想法是有一个干净和即时的数据更新模式,不必在每个 Activity 或片段生命周期事件(例如 LiveDataonPaused)上分别处理处置和重新订阅,并且即使我的活动被隐藏,也会在后台更新,以避免在返回我的活动时出现可怕的刷新延迟。我对这种设计模式感到非常惊讶。我仍然是,但我开始怀疑了。

当开始另一个具有相同设计模式的 Activity 时,我确实更改了一个值并立即从另一个 onResumed 获取更新的 List<...>。不同的viewmodel,不同的Activity,相同的设计,相同的数据库表。返回第一个 viewmodel 时,我发现新数据永远不会更新:即使数据集已更改,Room 也没有发出任何更新。我必须重新处理和订阅才能看到新数据。

所以我的问题是:关于我的问题的根源可能在哪里的任何指示?!这个设计模式的核心是不是有什么烂地方?我对所有这些东西应该一起工作的误解?由于某些线程问题,这只是我的错误吗?还是我应该为 Room 填写错误报告?

我尝试从我的第一个 Activityviewmodel 观察另一个非 Room RxJava3 observable,并且在其数据集更新时它确实会得到更新。

顺便说一下,我也使用 Hilt 将所有内容注入为 Activity

感谢您的时间:-)

解决方法

经过一周的头痛,我终于偶然发现了一个解决方案,它恰好是干净优雅的。

问题是 RxJava,我刚刚了解到,它不应该无缝地处理对同一个 Observable 的多个订阅。解决方案应该是使用 publish()connect()refcount() 运算符,或者更好地使用快捷方式 share()。我尝试了所有我能想到的方法,但都没有成功(它实际上使情况变得更糟)。我还尝试从我的存储库 subscribe() 到房间 Flowable 并通过 BehaviorSubject 代理它。

Room 的文档中有这个奇怪的 org.reactivestreams.Publisher,它的附加值我不知道,它的起源甚至不是我熟悉的 io.reactivex.rxjava3。事实证明,这就是解决方案。 编辑:事实证明 Publisher 是一个 Flowable 碰巧实现的接口。

build.gradle

implementation 'android.arch.lifecycle:reactivestreams:+'

Dao.java

@Query("...")
Flowable<List<...>> getFlowable();

ViewModel.java

public liveData;

@Inject
public ViewModel(@NonNull RoomDatabase roomDatabase) {
    liveData = LiveDataReactiveStreams.fromPublisher(roomDatabase.dao().getFlowable());
}

这似乎太容易了,但据我所知,它似乎完美这样更好

编辑: 事实证明,这个问题的根源比我想象的要严重一些。我假设我的依赖注入 @InstallIn(SingletonComponent.class) 中的 @Module 就足够了,但显然每个 @Singleton 方法上还需要一个 @Provides 注释。

@Module
@InstallIn(SingletonComponent.class)
public abstract class DependencyInjection
{
    @Provides
    @NonNull
    @Singleton // do not omit this
    public static DataDao provideDataDao(@NonNull RoomDatabase roomDatabase) {
        return roomDatabase.dataDao();
    }

    @Provides
    @NonNull
    @Singleton // do not omit this
    public static RoomDatabase provideRoomDatabase(@ApplicationContext Context applicationContext) {
        return
                BuildConfig.DEBUG ?
                        Room.databaseBuilder(applicationContext,RoomDatabase.class,"playground.db").fallbackToDestructiveMigration().build() :
                        Room.databaseBuilder(applicationContext,"playground.db").build() ;
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。