【问题标题】:Volley: onResponse in JsonObjectRequest delayed requestVolley:JsonObjectRequest 中的 onResponse 延迟请求
【发布时间】:2016-06-11 13:25:06
【问题描述】:

我是 Volley 库的新手,我正在创建一个简单的 Android 应用程序,该应用程序从以 JSON 格式生成的 API 获取数据。经过调试,只有下面提到的这个特定功能fetchAccD在Android Volley上有延迟问题。此 Activity 中的其他功能和暗示 JsonObjectRequest 的其他 Activity 运行良好。

{
    "Account": {
        "remarks": "NIL"
        "uname": "admin"
        "pword": null // value not to be shown
        "key": 1316451
        "name": "msummons sudo"
    }
}

这是我当前的代码

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_dashboard);
    uName = getIntent().getStringExtra("username");
    // reset session
    authidCoDe = 0;

    // invoke session
    Account account = fetchAccD(uName);

    if (account != null) {
        authidCoDe = account.getKey();
        ...


// init user details before loading
private final Account fetchAccD (String userN) {
    final Account account = new Account();
    requestQueue = null;
    requestQueue = Volley.newRequestQueue(this);
    String urlConstruct = *json url*;

    JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, urlConstruct,
            new Response.Listener<JSONObject>() {
                @Override
                public void onResponse(JSONObject response) {
                    try {
                        JSONArray jsonArray = response.getJSONArray("Account");
                        JSONObject jsonObject = jsonArray.getJSONObject(0);
                        account.setUname(jsonObject.optString("uname"));
                     // account.setPword(jsonObject.optString("pword"));
                        account.setKey(jsonObject.optInt("key"));
                        account.setName(jsonObject.optString("name"));
                        account.setRemarks(jsonObject.optString("remarks"));
                        requestQueue.stop();
                    }
                    catch (JSONException e) {
                        Toast.makeText(getApplicationContext(), "Fetch failed!", Toast.LENGTH_SHORT).show();
                        requestQueue.stop();
                    }
                }
            }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            Toast.makeText(getApplicationContext(), "Fetch failed!", Toast.LENGTH_SHORT).show();
            requestQueue.stop();
        }
    });
    requestQueue.add(jsonObjectRequest);
    return account;
}

调用fetchAccD时,代码运行完美

JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, urlConstruct,
        new Response.Listener<JSONObject>()

然后它继续到onCreate,在fetchAccD方法之后运行

if (account != null) {
    authidCoDe = account.getKey();
    ...

在它返回到fetchAccD 方法中的其余部分onResponse 之前。

@Override
public void onResponse(JSONObject response) {
    try {
        JSONArray jsonArray = response.getJSONArray("Account");
        ...

我的大部分函数都使用JsonObjectRequest GET 来获取JSON,这个问题只发生在fetchAccD 函数中。谢谢!

【问题讨论】:

    标签: java android json get android-volley


    【解决方案1】:

    onResponse是异步的,当服务器返回响应时会被调用。

    所以你应该在这样做之前等待响应:

    if (account != null) {
        authidCoDe = account.getKey();
        ...
    }
    

    onCreate 应该这样做:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_dashboard);
        uName = getIntent().getStringExtra("username");
        // reset session
        authidCoDe = 0;
    
        // invoke session
        fetchAccD(uName);
    }
    

    onResponse 你可以这样做:

    public void onResponse(JSONObject response) {
    
        try {
            JSONArray jsonArray = response.getJSONArray("Account");
            JSONObject jsonObject = jsonArray.getJSONObject(0);
            account.setUname(jsonObject.optString("uname"));
         // account.setPword(jsonObject.optString("pword"));
            account.setKey(jsonObject.optInt("key"));
            account.setName(jsonObject.optString("name"));
            account.setRemarks(jsonObject.optString("remarks"));
            useAccount(account);
            requestQueue.stop();
        }
        catch (JSONException e) {
            Toast.makeText(getApplicationContext(), "Fetch failed!", Toast.LENGTH_SHORT).show();
            requestQueue.stop();
        }
    }
    

    定义一个方法useAccount:

    private void useAccount(Account account) {
        if (account != null) {
            authidCoDe = account.getKey();
            ...
        }
    }
    

    fetchAccD不需要返回值,可以设为void

    【讨论】:

    • 谢谢!它确实有效,但这意味着,我的 onCreate 方法只能在 fetchAccD(uName);?或没有? :)
    • fetchAccD后面可以添加更多内容。当我说您的 Activity 应该等待响应时,这并不意味着您不能同时做其他事情。如果对您有用,请将答案标记为已接受,谢谢!
    • 谢谢!非常感谢您的帮助,这是我的认可:)
    猜你喜欢
    • 2013-01-08
    • 1970-01-01
    • 1970-01-01
    • 2017-08-12
    • 2021-01-08
    • 2013-11-17
    • 2019-04-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多