Android RxJava在活动还原后重新订阅事件

Android RxJava在活动还原后重新订阅事件,android,retrofit,rx-java,android-lifecycle,Android,Retrofit,Rx Java,Android Lifecycle,我仍然在研究RxJava,并用它来做一些改型2的网络工作。我们已经尝试了几天,代码看起来更可读了,但是遇到了一个问题,我似乎想不出解决的办法 我试图执行一个登录(返回一个API令牌),然后使用这个令牌获取同一链中的一些初始数据,这样链的输出就是令牌+数据。为此,我使用 apiClient .login() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .flatMa

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

我试图执行一个登录(返回一个API令牌),然后使用这个令牌获取同一链中的一些初始数据,这样链的输出就是令牌+数据。为此,我使用

apiClient
    .login()
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .flatMap(token -> getData(token))
    .subscribe(new Subscrber<Bundle>() {...});
apiClient
.login()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.flatMap(令牌->获取数据(令牌))
.subscribe(新子服务器(){…});
这看起来不错,但我还想在启动和停止链时显示一个进度条。因此,我也在这上面添加了一个
.doOnSubscribe()
和一个
.doOnSubscribe()
。然而,我注意到,在方向改变之后,我试图隐藏进度条的片段总是空的


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

您需要确保订阅从
.cache()
返回的相同的可观察实例。通常,您会将此实例存储在一个单例(如应用程序类)、一个保留片段或一个Android服务中的某个位置

您不必使用任何架构模式来实现这一点。尽管任何MVP/MVC对于关注点分离、测试等都是不错的选择,但将控制器/Presenter/DAO设置为应用程序范围的单例(在整个应用程序生命周期中保持内存)并不是一个好主意

下面是一个使用保留片段实例和RxJava的示例项目-

这里的主要思想是使用名为setRetainInstance(true)的Fragment,它可以保护它在方向改变时不被破坏,并将您的可观测数据存储在其中。下面是在Activity/Fragment onCreate中处理该问题的方法


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

您能做的最好的事情是拆分逻辑并实现
MVP
模式。之后,您将处理所有网络,并在屏幕旋转后保持视图重建。实际上,有一个非常简洁的库,允许使用基于rxJava的
MVP
模式(它非常小)。即使你不想使用它,你也可以知道如何实现它。。好吧,我想在开始RxJava之前,我也需要仔细阅读一个好的MVP实现…
MVP
可以让你的代码更干净,并且可以解决这个问题,但也许这不是你想要的解决方案(将整个应用程序架构切换到MVP并不是那么容易)(这就是为什么我没有把它作为答案发布的原因)。我相信你有一种方法可以做到这一点,而不必使用第三方库或一些很好的模式
MVP
,但我没有任何干净的解决方案。将我的上述评论视为“其他人是如何处理类似问题的”。另一件事你可能想看看:
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(...);
}