使用android async http库阻止异步http请求

时间:2016-03-01 11:09:36

标签: java android locking android-async-http

我知道标题听起来像是矛盾,但请听我的意见。

我在Android应用中使用刷新令牌和访问令牌身份验证。 在我的应用程序中,每个请求都通过post()方法进入中央Network.Java类;

我在post()方法中做的第一件事是检查我的令牌是否有效。如果是,则继续请求。

如果不是,我会调用refreshAccessToken()函数。

现在在这个函数中,我使用refreshToken创建一个http请求来获取一个新的accessToken。但是我需要这个请求一次只执行一个实例。

用例,用户恢复应用。然后4个请求都被异步启动。然后他们每个人都看到了,我需要刷新我的令牌,然后他们就这样去了。(这会导致服务器端和本地问题)。我希望第一个执行令牌刷新,其他所有都要阻止(在工作线程上),直到第一个请求解锁它。

这是我的刷新功能(我尝试锁定): 对不起,这很长。

private static synchronized void refreshAccessToken(final Context context,final TokenResponseHandler callBack){

    //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();
        }
    });
}

现在这是我可以阻止UI线程阻止它的唯一方法。我的synchronized减速功能并没有帮助,因为所有功能都会触发同步任务。

但是我担心的是,onStart()onFinnish()是由库在UI线程上执行的。我认为是这样的? (任何人都可以确认)

如何实现一个不会阻止我的UI线程的合适锁?

0 个答案:

没有答案