改进同步调用异步调用

时间:2015-12-18 04:26:12

标签: java android retrofit synchronous

这看起来很奇怪,但我最终陷入了这种境地。异步使用Retrofit实现Restful API调用。现在有一个突然的需求变化,并且必须一个接一个地调用API(一次一个),所以在第二个API调用中我必须发送从前一个响应接收的会话令牌。一种方法是将每个API调用设置为同步,但实现此更改需要时间。

我试过了:

  1. setExecutor(Executors.newSingleThreadExecutor(),new MainThreadExecutor)使用了RestAdapter.Builder。这没有用 因为API调用是异步的,并且在获得响应之前 先前的API调用第二次调用。所以第二个请求有 会话令牌无效。

  2. 在我实现所有Restful Web服务的类中, 使用Executors.newSingleThreadExecutor(),这也没有用 出于同样的原因。

    是否有人建议如何以最小的改变来解决这个问题 Web服务管理器如下,这是部分的,还有更多的api像登录:

  3. 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);
                    }
                });
            } 
    
    }
    

2 个答案:

答案 0 :(得分:0)

Executor并不重要,因为您总是使用Callback参数调用Retrofit服务,这使它成为异步。如果您希望您的Retrofit调用是同步的,那么服务调用方法需要返回类型,而不是void。您可以在文档中阅读。

一旦你的API调用同步并按你想要的顺序排列,就可以将它们包装在Runnable中,让Executor为你处理线程。

答案 1 :(得分:0)

当第二个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);
      }
    });
  }