title: Blocking in an async http request with android async http library
body: <p>I know the heading sounds like an oxymoron, however please listen to my case.</p>
  
  <p>I am using refresh token and access token authentication in my android app.
  In my app every request goes to a central  Network.Java class through the  <code>post()</code> method;</p>
  
  <p>first thing I do in the <code>post()</code> method is check if my token is valid. if it is, it proceeds with the request.</p>
  
  <p>if its not, I then call the <code>refreshAccessToken()</code> function.</p>
  
  <p>Now in this function I make a http request with the refreshToken to get a new accessToken. However I need this request to only ever be executed one instance at a time.</p>
  
  <p>Use case, user resumes the app. And then 4 requests are all fired off async. They then each see, aah I need to refresh my token, and they all then go and do so.(This causes issues server side and locally). I want the first one to do the token refresh, and the others all to block (On the worker thread) until the first request unlocks it.</p>
  
  <p>here is my refresh function (With my attempt at a lock): 
  Sorry it is quite long.</p>
  
  <p>private static synchronized void refreshAccessToken(final Context context, final     TokenResponseHandler callBack) {</p>
  
  <pre><code>    //Check if we have a valid refresh token
      if (!refreshToken.isValid(context)) {
          //There is no refresh token, so we have to force the user to login.
          callBack.OnFailed(401, null, null, null);
          //Start the login activity, this also clears all tokens
          startLoginActivity(context);
          //Exit as we can not do anything further
          return;
      }
  
      //Refresh Token Should be valid here
      //Make request to server for new access token
      final RequestParams params = new RequestParams();
      params.add("grant_type", "refresh_token");
      params.add("refresh_token", refreshToken.getToken(context));
      params.add("client_id", "android_app");     
  
      //Make the request
      httpClient.post(BASE_URL + "Token", params, new AsyncHttpResponseHandler() {
          @Override
          public void onStart() {
              //Lock this function down so that only one refresh happens at a time
              tokenLock.lock();
              //Check if the access token has not  been refreshed by another thread since we been waiting
              if (accessToken.isValid(context)) {
                  //tokenLock.unlock();
                  //TODO: end call some how
                  callBack.OnSuccess();
                 //Check if we need to manually call this.onFinnish(), it might be automatically called when we cancel the request
                  this.onFinish();
                  this.sendCancelMessage();
              }
          }
  
          @Override
          public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
              try {
                  if (HandleTokenResponse(context, responseBody)) {          
                      callBack.OnSuccess();
                      //Check if we need to manually call this, it might be automatically called when we cancel it
                      this.onFinish();
                      return;
                  }                
                  Log.e(TAG, "Failed to Obtained Access Token By Logging in with a refresh token");
                  callBack.OnFailed(500, null, null, new Throwable("Token Parse Error"));
              } catch (Exception ex) {  
                  Log.e(TAG, "Error occurred in token success response", ex);
              }
          }
  
          @Override
          public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {                
              Log.e(TAG, "Failed to Obtained Access Token By Logging in with a refresh token");
              if (responseBody != null) {
                  String response = new String(responseBody);
                  Log.e(TAG, response);
              }
              //notify parent that error occurred.
              callBack.OnFailed(statusCode, headers, responseBody, error);
  
              if (statusCode == 400 || statusCode == 401) {
                  //NB: We need to check that another thread / request has not already updated the access token.
                  if (!accessToken.isValid(context)) {
                      //Bad authentication then we need to login again                        
                      startLoginActivity(context);
                  } else {
                      //Continue as normal as the accessToken is ok, was probably updated by another entity                        
                      callBack.OnSuccess();
                  }
              }
          }
  
          @Override
          public void onFinish() {
              tokenLock.unlock();
          }
      });
  }
  </code></pre>
  
  <p>Now this is the only way I could get it to block without blocking the UI thread. My <code>synchronized</code> deceleration on the function doesn't help as all the function does it fire off an sync task.</p>
  
  <p>However my concern is that The <code>onStart()</code> and <code>onFinnish()</code> are executed on the UI thread by the library. Which I think is the case? (can anyone confirm)</p>
  
  <p>How can I implement a suitable lock that will not block my UI thread?</p>