我实现了网络调用以验证登录,这是正常的。我只是在登录成功后再次调用获取用户数据时遇到了一些麻烦。
以下是API调用:
RestApi restApi = ServiceRest.createRetrofitService(RestApi.class, UrlServer.URL_SERVER);
Observable<Response<User>> responseObservable = restApi.getUser(user);
responseObservable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.unsubscribeOn(Schedulers.io())
.subscribe(new Subscriber<Response<User>>() {
@Override
public void onCompleted() {
Log.i("LoginActivity", "[onCompleted]");
progressDialog.dismiss();
}
@Override
public void onError(Throwable e) {
progressDialog.dismiss();
Toast.makeText(LoginActivity.this, "Error: " + e.getMessage(), Toast.LENGTH_SHORT).show();
}
@Override
public void onNext(Response<User> userResponse) {
//Do stuff to go to another Activity
}
});
-------------编辑#1 -------------
我实现了@Tassos建议的内容:
responseUser
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.map(new Func1<Response<User>, Observable<Response<Object>>>() {
@Override
public Observable<Response<Object>> call(Response<User> userResponse) {
Log.d("USER", userResponse.body().getName());
return restApi.getData(userResponse.body().getToken());
}
})
.doOnError(new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
Toast.makeText(LoginActivity.this, "Error[doOnError]: " + throwable.toString(), Toast.LENGTH_SHORT).show();
}
})
.subscribe(new Subscriber<Object>() {
@Override
public void onCompleted() {
Log.i("LoginActivity", "[onCompleted]");
}
@Override
public void onError(Throwable e) {
Toast.makeText(LoginActivity.this, "Error: " + e.getMessage(), Toast.LENGTH_SHORT).show();
}
@Override
public void onNext(Object result) {
Log.d("RESPONSE", result.toString());
}
});
在订阅方法上这样做是否正确?我是否需要转换onNext的Object结果?
// ------------------------------------------ --------------------------------- //
我希望在登录成功后,使用通过Response对象User获得的令牌调用另一个url,并将其作为Header的授权发送到另一个api调用(Observable<Response<Object>> getData(@Header("Authorization") String token);
)。
我尝试过使用flatMap和zip,但我无法完成这项任务。
有什么建议吗?这个概念对我来说是新的。
答案 0 :(得分:3)
那么,你真的需要用户解雇对话吗?在进行其他调用之前,您是否绝对需要关闭对话框?
.unsubscribeOn(Schedulers.io())
.map(userResponse -> { /* do the other calls */ }
.subscribe(new Subscriber<?>() {...
答案 1 :(得分:2)
.flatMap
运算符是完成另一个API调用的完美方式。在这里阅读:http://blog.danlew.net/2014/09/22/grokking-rxjava-part-2/&#34;它变得更好&#34;部分。
.flatMap
允许您将一个observable更改为另一个observable,即使用前一个的结果进行新的API调用,实现事件链。如果您这样做,将会要求订阅者从.flatMap
收到可观察的观察结果。
你只需写:
restApi.getUser(user)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.flatMap(userResponse -> restApi.getData(userResponse.getToken()))
.doOnError(e -> Toast.makeText(LoginActivity.this, "Error: " + e.getMessage(), Toast.LENGTH_SHORT).show())
.doOnTerminate(() -> progressDialog.dismiss())
.subscribe(response -> proceedWithLogin())
另外你为什么要使用.unsubscribeOn(Schedulers.io())
?当您使用retrofit observable时,它们通常会生成一个事件,然后完成,并且不需要设置取消订阅调度程序。