我有以下代码,我尝试使用Retrofit2 + RxJava2实现多个连续的api调用
@Override
public void onClick(View v) {
count++;
request.setName("rober");
request.setVarryingValue(count);
mApiService.apiService()
.getAccessToken(<params>)
.subscribeOn(Schedulers.newThread())
.flatMap(new Function<Auth, ObservableSource<?>>() {
@Override
public ObservableSource<?> apply(Auth authentication) throws Exception {
Observable<Void> postObservable = mApiService.apiService().postCall(request, authentication.getAuth())
.subscribeOn(Schedulers.io());
postObservable.subscribe(new Observer<Void>() {
@Override
public void onSubscribe(Disposable d) {}
@Override
public void onNext(Void value) {
Log.e("Thread", " Thread : " + Thread.currentThread());
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
}
@Override
public void onComplete() {}
});
return postObservable;
}
}).subscribe(new Observer<Object>() {
@Override
public void onSubscribe(Disposable d) {}
@Override
public void onNext(Object value) {}
@Override
public void onError(Throwable e) {}
@Override
public void onComplete() {}
});
}
});
我的期望是,每次点击,都会调用一个新的/不同的线程来执行特定的api POST调用,但我从内部api调用中获取这些post值
{"name ":"rober"," some_varrying_number ":"4"}
04-03 07:23:08.319 27225-27378/edu.rx.test D/OkHttp: --> END POST (1679-byte
body)
04-03 07:23:08.322 27225-27380/edu.rx.test D/OkHttp: --> POST
http://mydomain.test.post.server http/1.1
{"name ":"rober"," some_varrying_number ":"4"}
04-03 07:23:08.319 27225-27378/edu.rx.test D/OkHttp: --> END POST (1679-byte
body)
04-03 07:23:08.322 27225-27380/edu.rx.test D/OkHttp: --> POST
http://mydomain.test.post.server http/1.1
{"name ":"rober"," some_varrying_number ":"4"}
04-03 07:23:08.319 27225-27378/edu.rx.test D/OkHttp: --> END POST (1679-byte
body)
04-03 07:23:08.322 27225-27380/edu.rx.test D/OkHttp: --> POST
http://mydomain.test.post.server http/1.1
{"name ":"rober"," some_varrying_number ":"4"}
04-03 07:23:08.319 27225-27378/edu.rx.test D/OkHttp: --> END POST (1679-byte
body)
04-03 07:23:08.322 27225-27380/edu.rx.test D/OkHttp: --> POST
http://mydomain.test.post.server http/1.1
似乎它只执行最后一次通话,我已经知道没有确切的&#34;并行&#34;在Rx中打电话,因为如果确实如此,它将违反所有被动原则,但是他们说的很多解决方法,现在我试图实现那个&#34;并行&#34;用我发布的代码打电话,但没有运气:(,我需要一些帮助,
非常感谢任何帮助。谢谢!
编辑:过程就像这样 1.首先获取身份验证令牌 2.成功的身份验证令牌后,进入api POST呼叫数字2取决于数字1
1&amp; 2将始终在点击事件上执行。
修改:发布图片以清楚说明
答案 0 :(得分:2)
当您发送第一个POST请求时,request
的变化值已经是4.那是因为在您单击4次之后,第一个POST请求将会那时的request
(有4个),而不是设置其变化值时的request
。
解决方案是使request
对象在onClick()
方法
public void onClick(View v) {
RequestClass request = new RequestClass();
request.setName("rober");
request.setVarryingValue(count);
//Your code
}
或者将count
值分配给临时变量,并在发送POST请求之前将其设置为request
,但要注意线程安全性
public void onClick(View v) {
//Saving the value
int temp = count++;
request.setName("rober");
mApiService.apiService()
.getAccessToken(<params>)
.subscribeOn(Schedulers.newThread())
.flatMap(new Function<Auth, ObservableSource<?>>() {
@Override
public ObservableSource<?> apply(Auth authentication) throws Exception {
//Set it to the request
//BE CAREFUL because the `request` object is now being accessed from multiple threads
request.setVarryingValue(temp);
Observable<Void> postObservable =
mApiService
.apiService()
.postCall(request, authentication.getAuth())
.subscribeOn(Schedulers.io())
.subscribe();
return postObservable;
}
})
.subscribe();
}
答案 1 :(得分:1)
我不太清楚为什么所有的帖子请求都是同时完成的,包含onClick()
时间和getAccessToken()
请求的完整日志,以及{{1}排放可能会有所帮助。
您的代码似乎正确,您将为每个请求打开一个新线程
但是,无论如何,由于您在日志上有4个打印件,但所有打印件都相同,问题可能是因为onNext()
参数是一个字段,因此在 {之后共享和访问 {1}}发出一个项目,因此你基本上做了4个请求但是具有相同的数据
您应该为每个新创建的request
分配一个专用的计数变量。
除此之外,订阅getAccessToken()
运算符中的flatMap()
是错误的,您应该只返回它,然后流将订阅它并将其合并为{{1}排放。
使用您的代码,您执行每个帖子请求两次,一个由您明确执行,另一个由postObservable
运算符执行(这也可能解释了同一请求的多个日志,但是如果没有看到日志中的所有数据,很难说清楚。)
答案 2 :(得分:0)
根据您建议的两个答案,我想出了以下代码,
将其链接在外部可观察
的onNext上@Override
public void onClick(View v) {
count++;
Request request = new Request();
request.setName("rober");
request.setVarryingValue(count);
mApiService.apiService()
.getAccessToken(<params>)
.subscribeOn(Schedulers.io())
.flatMap(new Function<Auth, ObservableSource<Void>>() {
@Override
public ObservableSource<Void> apply(Auth authentication) throws Exception {
return mApiService.apiService().postCall(request, authentication.getAuth());
}
})
.subscribe(new Observer<ObservableSource<Void>>() {
@Override
public void onSubscribe(Disposable d) {}
@Override
public void onNext(ObservableSource<Void> sourceFromFlatMap) {
sourceFromFlatMap.subscribe(new Observer<Void>() {
@Override
public void onSubscribe(Disposable d) {}
@Override
public void onNext(Void value) {
}
@Override
public void onError(Throwable e) {}
@Override
public void onComplete() {}
});
}
@Override
public void onError(Throwable e) {}
@Override
public void onComplete() {}
});
});
虽然我还不确定我是否以正确的方式使用Rx