2017-09-06 85 views
1

假设我有Android上下面的情况:切换线程中的Rx链多次

1)从网络 2组的请求列表)显示对于每个组的一些用户界面元素 为每个组3)请求项 4)显示UI elemets因为我想做到这一点使用RxJava每个项目

webService.requestGroups() 
     .flatMap(group -> { 
      view.showGroup(group); 
      return webService.requestItems(group); 
     }) 
     .toList() 
     .subscribeOn(Schedulers.io()) 
     .observeOn(AndroidSchedulers.mainThread()) 

     .subscribe(items -> view.showItems(items)); 

正如你可以看到我有2呼吁视图对象,每个都必须在主线程上执行。另外2个调用webService,它必须在后台线程上执行。

这段代码的问题:第一次调用view会在Android RuntimeException的背景上执行(只有原始线程可能会触及视图或其他东西)如果我将.observeOn转移到链的开头 - 第二次webService调用将会在主线程中执行(

因此,这里的问题 - 怎样才能“游”,通过螺纹多次在RxJava链??

回答

2

Rx doc for SubscribeOn

的SubscribeOn操作人员指定哪个线程Ť无论操作员被调用的运营商链中的哪个点,他都将开始操作Observable。另一方面,Observable会影响Observable会在该操作符出现的地方使用的线程。因此,您可以在Observable运算符链中的多个时间点多次调用ObserveOn,以便更改某些操作符在哪些线程上运行。

SubscribeOn运算符只能应用一次并设置启动线程。 ObserveOn可用于在流中的任意点从一个线程转到另一个线程。所以我认为以下应该做你想要的:

webService.requestGroups() 
    .subscribeOn(Schedulers.io()) 
    .observeOn(AndroidSchedulers.mainThread()) 
    .flatMap(group -> { 
     view.showGroup(group); 
     return webService.requestItems(group) 
         .subscribeOn(Schedulers.io()); 
    }) 
    .toList() 
    .observeOn(AndroidSchedulers.mainThread()) 
    .subscribe(items -> view.showItems(items)); 

但在我看来这太复杂了。我只想订阅第一个观察对象,然后为每个组启动一个新链,如下所示:

webService.requestGroups() 
    .subscribeOn(Schedulers.io()) 
    .observeOn(AndroidSchedulers.mainThread()) 
    .subscribe(group -> { 
     view.showGroup(group); 
     webService.requestItems(group) 
      .subscribeOn(Schedulers.io() 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribe(items -> view.showItems(items)); 
    });