【问题标题】:How to make volley calls synchronous如何使截击呼叫同步
【发布时间】:2017-06-17 18:33:28
【问题描述】:

在我的应用程序中,我使用 volley 进行联网。现在后端团队已经对 web 服务调用进行了一些更改,在每次 api 调用之前,我需要再调用一个服务(oauth 服务),它将在JSON 响应中提供访问令牌。然后在我的实际服务(登录服务)调用中使用此访问令牌作为 url 中的查询。意味着我需要打两个电话,一个接一个。

在我的代码中实现了此更改,例如说登录服务: 步骤 1) 调用提供访问令牌的 oauth 服务。 步骤 2) 在 url 中使用此访问令牌作为登录服务的查询。

现在的问题是调用不同步,登录调用后我收到访问令牌作为响应,因此出现错误

登录服务调用:

 public void onClickLogin(View v) {
        // Tag used to cancel the request
        String tagJSONobj = "json_obj_req";

        String url;

            if(Constants.RUN_AUTH_API) {

                authAuthentication = new AuthAuthentication(tinyDB, SignInActivity.this);
                authAuthentication.getAuthToken();
                url = https://abc.xyz.com/Services/api/UserValidation/userValidate.do?access_token= + tinyDB.getString(Constants.MY_SHARED_PREF_AUTH_TOKEN);
            }else
            {
                url = Constants.SIGNIN_URL;
            }


            showDialog();

            JSONObject object = new JSONObject();
            try {
                object.put("userName", name);
                object.put("password", password);
                object.put("appType", "MOB APP");

            } catch (JSONException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }


            JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.POST, url, object,
                    new Response.Listener<JSONObject>() {
                        @Override
                        public void onResponse(JSONObject response) {

                            hidePDialog();

                        }
                    }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    VolleyLog.d(TAG, "Error: " + error.getMessage());
                    hidePDialog();
                    System.out.print("error is" + error.getMessage());
                    error.printStackTrace();
                    Toast.makeText(SignInActivity.this, getResources().getString(R.string.login_service_error_message), Toast.LENGTH_SHORT).show();

                }

            }) ;

            // Adding request to request queue
            AppController.getInstance().addToRequestQueue(jsonObjReq, tagJSONobj);
        }
    }

OAuth 服务调用:

public class AuthAuthentication {
private static final String TAG = AuthAuthentication.class.getSimpleName();
private TinyDB tinyDB;
private Context context;

public AuthAuthentication(TinyDB tinyDB, Context context){
    this.tinyDB = tinyDB;
    this.context = context;
}

public void getAuthToken() {

    String tag_json_obj = "json_obj_req";
    String url = https://abc.xyz.com/Services/oauth/token?grant_type=password&client_id=restapp&client_secret=restapp&username=admin&password=admin";


    JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.GET,
            url, "",
            new Response.Listener<JSONObject>() {

                @Override
                public void onResponse(JSONObject response) {

                    try {
                        Log.d(TAG, " Response" + response.toString());
                        tinyDB.putString(Constants.MY_SHARED_PREF_AUTH_TOKEN, "" + response.getString(AppTags.TAG_AUTH_TOKEN));

                    } catch (JSONException e) {
                        e.printStackTrace();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }, new Response.ErrorListener() {

        @Override
        public void onErrorResponse(VolleyError error) {

            VolleyLog.d(TAG, "Error: " + error.getMessage());
            Toast.makeText(context, context.getResources().getString(R.string.unable_to_process), Toast.LENGTH_SHORT).show();
        }
    });

    // Adding request to request queue
    AppController.getInstance().addToRequestQueue(jsonObjReq, tag_json_obj);

}

}

【问题讨论】:

  • 它非常简单...只需调用第一个 req 的第二个 volley onResponse 方法
  • 能否分享一些代码
  • onclick 登录 coll oAuth 方法... oAuth 方法 OnReponse 调用登录方法

标签: android web-services oauth android-volley


【解决方案1】:

首先在登录按钮单击和 OnResponse 方法调用登录 Api 时调用 OAuthsevice

OAuth 服务调用:

public class AuthAuthentication {
private static final String TAG = AuthAuthentication.class.getSimpleName();
private TinyDB tinyDB;
private Context context;

public AuthAuthentication(TinyDB tinyDB, Context context){
this.tinyDB = tinyDB;
this.context = context;
}

public void getAuthToken() {

String tag_json_obj = "json_obj_req";
String url = https://abc.xyz.com/Services/oauth/token?grant_type=password&client_id=restapp&client_secret=restapp&username=admin&password=admin";


JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.GET,
        url, "",
        new Response.Listener<JSONObject>() {

            @Override
            public void onResponse(JSONObject response) {

                try {
                    Log.d(TAG, " Response" + response.toString());
                    tinyDB.putString(Constants.MY_SHARED_PREF_AUTH_TOKEN, "" + response.getString(AppTags.TAG_AUTH_TOKEN));
                    onClickLogin();/// here to peform login

                } catch (JSONException e) {
                    e.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }, new Response.ErrorListener() {

    @Override
    public void onErrorResponse(VolleyError error) {

        VolleyLog.d(TAG, "Error: " + error.getMessage());
        Toast.makeText(context, context.getResources().getString(R.string.unable_to_process), Toast.LENGTH_SHORT).show();
    }
});

// Adding request to request queue
AppController.getInstance().addToRequestQueue(jsonObjReq, tag_json_obj);

}

更新

如果 OAUTH 会调用多次,我们需要的是不同 API 的 OAUTH 密钥...

在实用程序文件夹中创建此类

public interface VolleyResponse {
   void processFinish(String output);
}

像这样改变你的类构造函数..

public class AuthAuthentication {
private static final String TAG = AuthAuthentication.class.getSimpleName();
private TinyDB tinyDB;
private Context context;
private VolleyResponse delegate;

public AuthAuthentication(TinyDB tinyDB, Context context,VolleyResponse delegate){
  this.tinyDB = tinyDB;
  this.context = context;
  this.delegate= delegate;
}
 --------
 -------
}

在 AuthAuthentication 类的 OnResponse 方法中

@Override
        public void onResponse(JSONObject response) {

            try {
                Log.d(TAG, " Response" + response.toString());
                tinyDB.putString(Constants.MY_SHARED_PREF_AUTH_TOKEN, "" + response.getString(AppTags.TAG_AUTH_TOKEN));
                //send response of volley 
                delegate.processFinish(tinyDB); //it will broadcast your response

            } catch (JSONException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

并根据需要使用它。假设您必须在登录点击中使用

login.setOnClickListerner(new View.OnClickListenr(){
     @Override
     public void onClick(View view){
         AuthAuthentication auth= new AuthAuthentication(tinyDB,mContext,new VolleyResponse() {
                @Override
                public void processFinish(String output) {
                       //output conatins response
                       loginApicall();
                }

             }.getAuthToken(); ///if not work then auth.getAuthToken                  

    }
});

【讨论】:

  • 还有其他方法吗,因为我有很多 api 调用,我不能在 getAuthToken() 中写太多 if 语句
  • 为什么不勾选我的答案..?
猜你喜欢
  • 2014-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多