我的应用中有多个网络电话。我喜欢使用compose运算符在IO线程中运行网络请求:
public static <T> Transformer<T, T> runOnIoThread()
{
return tObservable -> tObservable.subscribeOn( Schedulers.io() )
.observeOn( AndroidSchedulers.mainThread() );
}
只要我只有一个网络电话,这似乎运作良好。但是,如果我按照以下示例链接它们,我将获得Android的NetworkInMainThreadException。
public Observable<String> networkCall1()
{
return <NETWORK_CALL_1()>
.compose( runOnIoThread() );
}
public Observable<String> networkCall2( String input )
{
return <NETWORK_CALL_2(input)>
.compose( runOnIoThread() );
}
public Observable<String> chainedCalls()
{
return networkCall1()
.flatMap( result1 -> networkCall2( result1 ) );
}
我之前的想法是,compose
在调用之前应用于完整的可观察链,而后来的compose
调用将覆盖&#34;覆盖&#34;前一个的行为。但实际上,看起来第一个observeOn
(compose
主线程)的observeOn
调用支配第二个compose
调用(subscribeOn
IO线程) 。一个明显的解决方案是拥有两个版本的networkCall1
- 一个应用调度程序而另一个不适用。但是,这会使我的代码非常冗长。
您知道更好的解决方案吗? 你能解释一下在一个可观察链中应用调度程序两次(使用compose)的行为吗?
编辑:我正在使用RxJava进行网络调用改造。
答案 0 :(得分:8)
每个流只能使用subscribeOn()
一次。如果你再次使用它,它就不会做任何事情。因此,当您将两种方法链接在一起时,运行:
observeOn(AndroidSchedulers.mainThread())
将操作切换到主线程。之后它会停留在那里,因为下一个subscribeOn()
实际上被忽略了。
我建议您实际上使用撰写方法过度复杂化。只需添加
subscribeOn(Schedulers.io())
同时拨打网络电话,然后使用
observeOn(AndroidSchedulers.mainThread())
就在您想要在主线程上处理结果之前。你最终会得到类似的东西:
public Observable<String> networkCall1()
{
return <NETWORK_CALL_1()>
.subscribeOn(Schedulers.io);
}
public Observable<String> networkCall2( String input )
{
return <NETWORK_CALL_2(input)>
.subscribeOn(Schedulers.io);
}
public Observable<String> chainedCalls()
{
return networkCall1()
.flatMap( result1 -> networkCall2( result1 ) )
.observeOn(AndroidSchedulers.mainThread());
}
修改强>
如果确实希望对各个网络呼叫方法进行observeOn()
呼叫,则可以。您必须在observeOn()
方法中添加额外的chainedCalls()
。每个流可以根据需要进行尽可能多的observeOn()
次呼叫。它会是这样的:
public Observable<String> networkCall1()
{
return <NETWORK_CALL_1()>
.subscribeOn(Schedulers.io)
.observeOn(AndroidSchedulers.mainThread());
}
public Observable<String> networkCall2( String input )
{
return <NETWORK_CALL_2(input)>
.subscribeOn(Schedulers.io)
.observeOn(AndroidSchedulers.mainThread());
}
public Observable<String> chainedCalls()
{
return networkCall1()
.observeOn(Schedulers.io)
.flatMap( result1 -> networkCall2( result1 ) )
.observeOn(AndroidSchedulers.mainThread());
}