自定义RxJava的调度程序

时间:2018-01-19 20:44:29

标签: android retrofit rx-java

上下文

我现在遇到一个问题,就是我正在复制Retrofit的HTTP请求。

在我的应用程序中,我有一个显示ViewPager FragmentStatePageAdapter的主屏幕。我的应用程序的体系结构这是一个非常常见的MVP,我使用RxJava和Retrofit与RxJavaAdapterFactoryCall转换为rx.Observables

看起来像这样:

enter image description here

Page1Fragment显示多个团队的帖子文章列表。问题是我获取该文章列表的服务器端端点没有提供与每篇文章相关联的团队,它只提供与每篇文章相关联的团队ID。

所以我必须在命中服务器端端点获取文章列表的方法和获取团队列表的服务器端端点之间执行Observable.zip,然后合并它们。

Page3Fragment显示所有用户团队的列表(由我之前使用的相同端点提供)

问题

这里的问题是,一旦打开App,就会实例化3个片段,Page1FragmentPage2Fragment都会到达团队的端点以获取用户的团队列表。

我的问题是;有没有办法实现类似自定义调度程序的东西,将它附加到Retrofit的方法并避免这种东西?做一些验证,例如“好的,如果N个不同的订户试图进入这个Retrofit Observable,返回相同的响应”,而不是N次服务器端API。我目前正在使用Scheduler.io()来传递.subscribeOn方法。

请让我知道是否有一些不太清楚的事情。

2 个答案:

答案 0 :(得分:0)

您不需要一个时间表来管理对端点的访问。对服务器的每个请求都应该产生一个observable,最终会提供结果。

Map<TeamId, Observable<Team>> results = new ConcurrentHashMap<>();

请求被映射到一个observable,最终将为其发出一个值。

Observable<Team> lookUpTeam( TeamId id ) {
  return results.compute( id, (id, res) -> 
        res == null ? makeApiRequest( id ) : res );
}
Observable<Team> makeApiRequest( TeamId id ) {
  BehaviorSubject<Team> team = BehaviorSubject.create();
  teamServer.getTeam( id )
    .subscribe( team );
  return team;
}

团队查找的缓存现在保存在一个包含最后返回值的并发哈希映射中。每个团队ID只会生成一个API请求。

答案 1 :(得分:0)

具有唯一线程的唯一自定义调度程序(与 Schedulers.single() 不同)

class SingleTask : Callable<Scheduler?> {
        @Throws(Exception::class)
        override fun call(): Scheduler {
            return SingleScheduler()
        }
    }


val newCustomScheduler : Scheduler = RxJavaPlugins.initSingleScheduler(SingleTask())

fun f() {
Completable.fromAction {
            // Do an Action here
        }.subscribeOn(newCustomScheduler).subscribe()
}

结果是这样的:

  • 执行 f()
  • 再次执行 f()
  • 再次执行 f()

第一次执行将处理线程 XYZ 上的 Action 第二次执行将处理线程 XYZ 上的操作 第三次执行将处理线程 XYZ 上的 Action

所以所有的都将在同一个线程上执行。

如果您不想使用 Schedulers.single(),这是一种 MainThread 原则,并且是在 Schedulers 类上定义的全局范围。