【问题标题】:RxJava resubscribe to event after activity restore活动恢复后 RxJava 重新订阅事件
【发布时间】:2016-01-02 03:01:54
【问题描述】:

我仍在研究 RxJava 并使用它来使用 Retrofit 2 做一些网络工作。我们已经尝试了几天,现在代码看起来更具可读性,但遇到了一个我似乎无法解决的问题想办法解决。

我正在尝试执行登录(它返回一个 API 令牌),然后使用此令牌在同一个链中获取一些初始数据,以便链的输出是令牌 + 数据。为此,我使用

调用我的 API 服务
apiClient
    .login()
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .flatMap(token -> getData(token))
    .subscribe(new Subscrber<Bundle>() {...});

这看起来不错,但我还想在启动和停止链时显示一个进度条。所以我也添加了.doOnSubscribe().doOnUnsubscribe()。但是我注意到,在更改方向后,我试图隐藏进度条的片段始终为空。

所以我搜索并发现了似乎有帮助的 RxLifecycle 库,我现在 .cache() 并取消订阅事件链。但是我不知道在此之后如何在onCreate() 中再次订阅相同的事件?我想我遗漏了一些非常基本的东西,如果有任何帮助,我将不胜感激。

【问题讨论】:

  • 你能做的最好的事情就是拆分你的逻辑并实现MVP 模式。之后,您的 Presenter 类(理想情况下应该是每个视图实例的单例)将处理所有网络并在屏幕旋转后保持视图重建。实际上有一个非常简洁的库允许使用基于 rxJava github.com/konmik/nucleusMVP 模式(它真的很小)。即使你不想使用它,你也可以了解它是如何实现的
  • hmm.. 好的,所以我想我还需要阅读一个好的 MVP 实现,然后再走 RxJava 路线......
  • MVP 可以让你的代码更干净,并且会解决这个问题,但也许这不是你正在寻找的解决方案(将整个应用程序架构切换到 MVP 并不容易)(这就是为什么我没有将其发布为答案)。我相信你有一种方法可以在没有MVP 的情况下使用 3rd 方库或一些不错的模式来做到这一点,但我没有任何干净的解决方案。将我的上述评论视为“其他人如何处理类似问题”。

标签: android retrofit rx-java android-lifecycle


【解决方案1】:

您不一定必须使用任何架构模式来实现这一点。尽管任何 MVP/MVC 对于关注点分离、测试等都是很好的东西,但是让你的 Controller/Presenter/DAO 成为应用程序范围的单例,在整个应用程序的生命周期中保持内存并不是一个好主意。

这是一个使用保留片段实例和 RxJava 的示例项目 - https://github.com/krpiotrek/RetainFragmentSample

这里的主要思想是使用 Fragment 并调用 setRetainInstance(true),以防止它在方向更改时被破坏,并将您的 Observable 存储在那里。这是在 Activity/Fragment onCreate

中处理的方法
protected void onCreate(Bundle savedInstanceState) {
    if (savedInstanceState == null) {
        // first run, create observable
        mInfoObservable = createInfoObservable();
        // set Observable in retained fragment
        RetainFragmentHelper.setObject(this, getSupportFragmentManager(), mInfoObservable);
    } else {
        // following runs, get observable from retained fragment
        mInfoObservable = RetainFragmentHelper.getObjectOrNull(this, getSupportFragmentManager());
    }

    // subscribe 
    mInfoObservable.subscribe(...);
}

请记住,您的 Observable 必须缓存最后一个值,一种方法是 使用 cache() 运算符。

【讨论】:

    【解决方案2】:

    您需要确保订阅了从.cache() 返回的相同 Observable instance。通常,您会将此实例存储在 Singleton(如 Application 类)、保留片段或 Android 服务中的某个位置。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-23
      • 2014-04-17
      • 1970-01-01
      • 1970-01-01
      • 2013-07-30
      • 2016-10-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多