这看起来很奇怪,但我最终陷入了这种境地。异步使用Retrofit实现Restful API调用。现在有一个突然的需求变化,并且必须一个接一个地调用API(一次一个),所以在第二个API调用中我必须发送从前一个响应接收的会话令牌。一种方法是将每个API调用都设置为同步,但实现此更改需要时间。
我试过了 :
setExecutor(Executors.newSingleThreadExecutor(),new
MainThreadExecutor)
用于RestAdapter.Builder
。这不起作用,因为API调用是异步的,并且在获得对先前API调用的响应之前进行第二次调用。因此第二个请求具有无效的会话令牌。Executors.newSingleThreadExecutor()
,这也是出于同样的原因。
有人可以建议如何通过最小的改变来解决这个问题。
Webservice Manager如下所示,这是部分的,还有更多的api像登录:public class WebServiceManager {
private static final String ROOT_PATH = Urls.REST_ROOT_URL;
RestAdapter restAdapter;
WebServiceInterface webServiceInterface;
private String requestKey;
private String sessionId;
private Context context;
public WebServiceManager(Context context) {
this.context = context;
initializeWebServiceAdapter();
}
private void initializeWebServiceAdapter() {
restAdapter = new RestAdapter.Builder()
.setEndpoint(ROOT_PATH)
.setLogLevel(RestAdapter.LogLevel.FULL)
.build();
webServiceInterface = restAdapter.create(WebServiceInterface.class);
}
private void setHeaderValues(BaseModel model) {
SessionManager sm= context.getApplicationContext().getSessionManager();
model.getRequestHeader().setRequestKey(sm.getRequestKey());
model.getRequestHeader().setSessionId(sm.getSessionId());
}
public void login(String emailID, String passwd, final WebServiceCallback loginModelWebServiceCallback) {
LoginModel model = RestRequest.getLoginModel(emailID, passwd);
setHeaderValues(model);
webServiceInterface.login(model, new Callback() {
@Override
public void success(LoginModel loginModel, Response response) {
if (loginModelWebServiceCallback != null)
{
SessionManager sm= context.getApplicationContext().getSessionManager();
sm.setSessionDetails(response.getRequestKey(),response.getSessionId());
loginModelWebServiceCallback.success(loginModel);
}
}
@Override
public void failure(RetrofitError error) {
if (loginModelWebServiceCallback != null)
loginModelWebServiceCallback.failure(error);
}
});
}
}
Executor并不重要,因为你总是使用Callback参数调用Retrofit服务,这使它成为异步。如果您希望您的Retrofit调用是同步的,那么服务调用方法需要返回类型,而不是void。您可以在文档中阅读此内容。
一旦你的API调用同步并按你想要的顺序排列,就可以将它们包装在Runnable中,让Executor为你处理线程。
当第二个api调用需要某个参数时,可以在第一个API本身的响应中进行请求。看看样本:
public void login(String emailID, String passwd, final WebServiceCallback loginModelWebServiceCallback) {
LoginModel model = RestRequest.getLoginModel(emailID, passwd);
setHeaderValues(model);
webServiceInterface.login(model, new Callback() {
@Override
public void success(LoginModel loginModel, Response response) {
if (loginModelWebServiceCallback != null) {
makeSecondAPIcall();
}
}
@Override
public void failure(RetrofitError error) {
if (loginModelWebServiceCallback != null)
loginModelWebServiceCallback.failure(error);
}
});
}