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?
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.
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.
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();
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With