Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android, Volley Request, the response is blocking main thread

Something bad is happening when using Volley to treat a large response:

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);

this code block the main thread, freezing the application.

Additionally, I set some header values to allow gzip response and a code to handle the data. But it is not the piece that make the undesired behavior. The application freeze only when onResponse(String response) starts.

What can I do to avoid this?

like image 713
zerokol Avatar asked Jul 25 '16 12:07

zerokol


People also ask

What is the difference between a requestqueue and a volley?

The RequestQueue manages worker threads for running the network operations, reading from and writing to the cache, and parsing responses. Requests do the parsing of raw responses and Volley takes care of dispatching the parsed response back to the main thread for delivery.

What can be done with networking in Android using volley?

All the tasks that need to be done with Networking in Android, can be done with the help of Volley. Automatic scheduling of network requests. Multiple concurrent network connections. Canceling request API. Request prioritization. Volley provides debugging and tracing tools.

How to make synchronous HTTP request using volley in Java?

We are going to make synchronous HTTP Request using volley. To make synchronous HTTP request make a RequestFuture object. And make JsonObjectRequest pass this parameter RequestMethod, URL, pass object of type Json and pass RequestFuture instance. RequestFuture<JSONObject> requestFuture=RequestFuture.newFuture();

How do I use a volley in Java?

At a high level, you use Volley by creating a RequestQueue and passing it Request objects. The RequestQueue manages worker threads for running the network operations, reading from and writing to the cache, and parsing responses.


1 Answers

onResponse and onErrorResponse is called on UI thread hence any heavy operation done inside these methods will make you application less responsive. I guess you are trying to parse the response in onResponse() which is incorrect.

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

like image 85
Arpit Ratan Avatar answered Sep 29 '22 23:09

Arpit Ratan