java - Android,Volley Request,响应阻塞主线程

标签 java android multithreading android-volley

使用 Volley 处理大型响应时发生了一些不好的事情:

String url = AppHelper.DOMAIN + "/service/pages/profile_update.json";

this.infoTextView.setText(getString(R.string.profile_info_updating));

final StringRequest stringRequest = new StringRequest(Request.Method.POST, url,
        new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                try {
                    JSONObject json = new JSONObject(response);

                    if (json.getBoolean("success")) {
                        // manage JSON object here
                    } else {
                        Toast.makeText(ProfileActivity.this,
                                getString(R.string.connection_problem_server),
                                Toast.LENGTH_LONG).show();
                    }
                } catch (JSONException e) {
                    ProfileActivity.this.infoTextView.setText(
                            getString(R.string.profile_info_updating_error));

                    e.printStackTrace();
                }
            }
        }, new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {
        ProfileActivity.this.infoTextView.setText(
                getString(R.string.profile_info_updating_error));

        if (error.networkResponse != null && error.networkResponse.statusCode == 401) {
            Toast.makeText(ProfileActivity.this,
                    getString(R.string.connection_problem_permission),
                    Toast.LENGTH_LONG).show();
        }

        new android.os.Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                if (ProfileActivity.this.swipeRefreshLayout != null) {
                    ProfileActivity.this.swipeRefreshLayout.setRefreshing(false);
                }
            }
        }, 1000);

        error.printStackTrace();
    }
}) {
    @Override
    protected Map<String, String> getParams() {
        Map<String, String> params = new HashMap<>();
        params.put("auth_token", ProfileActivity.this.defaultUser.getAuthenticationToken());
        return params;
    }

    @Override
    public Map<String, String> getHeaders() throws AuthFailureError {
        Map<String, String> params = new HashMap<>();
        params.putAll(super.getHeaders());
        params.put("Accept-Encoding", "gzip,deflate");
        return params;
    }

    @Override
    protected Response<String> parseNetworkResponse(NetworkResponse response) {
        StringBuilder output = new StringBuilder();
        try {
            GZIPInputStream gStream = new GZIPInputStream(new ByteArrayInputStream(response.data));
            InputStreamReader reader = new InputStreamReader(gStream);
            BufferedReader in = new BufferedReader(reader, 16384);

            String read;

            while ((read = in.readLine()) != null) {
                output.append(read).append("\n");
            }
            reader.close();
            in.close();
            gStream.close();
        } catch (IOException error) {
            error.printStackTrace();
            return Response.error(new ParseError());
        }

        return Response.success(output.toString(), HttpHeaderParser.parseCacheHeaders(response));
    }
};

stringRequest.setRetryPolicy(new RetryPolicy() {
    @Override
    public int getCurrentTimeout() {
        // 40 seconds
        return 40000;
    }

    @Override
    public int getCurrentRetryCount() {
        return DefaultRetryPolicy.DEFAULT_MAX_RETRIES;
    }

    @Override
    public void retry(VolleyError error) throws VolleyError {
        throw error;
    }
});

Volley.newRequestQueue(this).add(stringRequest);

此代码阻塞主线程,卡住应用程序。

此外,我设置了一些 header 值以允许 gzip 响应和处理数据的代码。但这不是造成不良行为的部分。应用程序仅在 onResponse(String response) 启动时卡住。

我该怎么做才能避免这种情况?

最佳答案

onResponse 和 onErrorResponse 是在 UI 线程上调用的,因此在这些方法中进行的任何繁重操作都会降低应用程序的响应速度。我猜您正在尝试解析 onResponse() 中的响应,这是不正确的。

You have to move to parsing logic to parseNetworkResponse since this is the method which is called in background thread. Refer the below link for more details :

https://developer.android.com/training/volley/request-custom.html

关于java - Android,Volley Request,响应阻塞主线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38567604/

相关文章:

java - 有没有像 MaintainJ for IntelliJ 这样的工具

Android ADT 21.0 警告 : Implicitly using the default locale

python - 如何在Python的进程之间共享一个非常大的字典

android - Android中使用Handler发送消息

python - 获取线程变量的参数

java - 如何在后端线程中使用 JpaRepository?

java - 通过 Facebook 分享时出错

java - 从 Java 调用 C、C++ 程序

android - 以编程方式获取当前笔画颜色

android - 将 Java 日历的时区设置为设备时区?