Volley slow and causing memory leak

匿名 (未验证) 提交于 2019-12-03 01:49:02

问题:

In my project, I am using volley to download a JSON stream which I parse and show in a listview. I use the following method to load my data:

private void loadEventData(int year, final int month) {      // get volley request queue     requestQueue = cpcApplication.getRequestQueue(getActivity());      String url = "****************?year=" + year             + "&month=" + month;      pd = ProgressDialog.show(getActivity(), "Loading Events", "Retrieving Data from Server");     pd.setCancelable(true);      JsonObjectRequest jr = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener() {          @Override         public void onResponse(JSONObject response) {              Log.i(TAG, response.toString());              // parse the incoming response             parseJson(response, month);              // notify the listview that the data set has changed             adapter.notifyDataSetChanged();              // set the listview at the top position             listView.setSelection(current.get(Calendar.DAY_OF_MONTH));              // dismiss the ProgressDialog             pd.dismiss();          }         }, new Response.ErrorListener() {          @Override         public void onErrorResponse(VolleyError error) {              error.printStackTrace();              // cancel the progress dialog             pd.dismiss();              // let the user know that a network connection is not available             Toast.makeText(getActivity(), "Cannot communicate with server.  Check network connection.", Toast.LENGTH_LONG).show();         }      });      // add the network request to the queue     requestQueue.add(jr);  } 

The first call to this method works beautifully. In the second call, I get a timeout error. When I use the following command:

jr.setRetryPolicy(new DefaultRetryPolicy(             2500, DefaultRetryPolicy.DEFAULT_TIMEOUT_MS, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)); 

to increase the amount of time for the request, the request takes over 30 seconds and produces the following log output:

10-19 20:53:19.746: D/Volley(17523): [2786] BasicNetwork.logSlowRequests: HTTP response for request= [lifetime=41769], [size=5467846], [rc=200], [retryCount=2] 10-19 20:53:19.796: D/dalvikvm(17523): GC_CONCURRENT freed 7462K, 26% free 24424K/33000K, paused 6ms+4ms, total 56ms 10-19 20:53:19.796: D/dalvikvm(17523): WAIT_FOR_CONCURRENT_GC blocked 51ms 10-19 20:53:19.826: I/dalvikvm-heap(17523): Grow heap (frag case) to 35.123MB for 10935708-byte allocation 10-19 20:53:19.857: D/dalvikvm(17523): GC_FOR_ALLOC freed 3K, 20% free 35100K/43680K, paused 23ms, total 28ms 10-19 20:53:19.917: D/dalvikvm(17523): GC_CONCURRENT freed 2018K, 19% free 35816K/43680K, paused 3ms+4ms, total 60ms 10-19 20:53:20.007: D/dalvikvm(17523): GC_CONCURRENT freed 4874K, 15% free 37226K/43680K, paused 2ms+3ms, total 27ms 10-19 20:53:20.007: D/dalvikvm(17523): WAIT_FOR_CONCURRENT_GC blocked 24ms 10-19 20:53:20.067: D/dalvikvm(17523): GC_FOR_ALLOC freed 5037K, 15% free 38601K/44900K, paused 19ms, total 19ms 10-19 20:53:20.117: D/dalvikvm(17523): GC_FOR_ALLOC freed 4680K, 14% free 40045K/46564K, paused 20ms, total 20ms 10-19 20:53:20.177: D/dalvikvm(17523): GC_FOR_ALLOC freed 5576K, 14% free 41572K/48272K, paused 20ms, total 20ms 10-19 20:53:20.227: D/dalvikvm(17523): GC_FOR_ALLOC freed 6133K, 15% free 43406K/50548K, paused 20ms, total 20ms 10-19 20:53:20.287: D/dalvikvm(17523): GC_CONCURRENT freed 6486K, 15% free 45029K/52428K, paused 2ms+2ms, total 24ms 10-19 20:53:20.287: D/dalvikvm(17523): WAIT_FOR_CONCURRENT_GC blocked 11ms 10-19 20:53:20.407: D/Volley(17523): [1] Request.finish: 42553 ms: [ ] http://****** 0x63ea5535 NORMAL 1 

When I perform the same request in a browser, it takes only several seconds. Why the delay and incredible memory consumption?

回答1:

Every call to the method you create a new RequestQueue which is not a recommended approach. You should create one RequestQueue, probably a publicly visible singleton that is initialized once when the app is created.

Try moving the RequestQueue outside and see if it solves your problem.



回答2:

i have some problem with:

Volley.newRequestQueue(getApplicationContext()); 

it caused the first request at startup to take awfully long time in some phones. i changed it to:

Cache cache = new DiskBasedCache(getCacheDir(), 1024 * 1024); Network network = new BasicNetwork(new HurlStack()); mRequestQueue = new RequestQueue(cache, network); mRequestQueue.start(); 

That solved my issue.



回答3:

I'm trying explain with few code (already Itai is explained in brief)

Below code explains how to use the global request queue for Volley with a singleton instance of the application class for easy access in other places and make the code more memory efficient!.

public class ApplicationController extends Application {

/**  * Log or request TAG  */ public static final String TAG = "VolleyPatterns";  /**  * Global request queue for Volley  */ private RequestQueue mRequestQueue;  /**  * A singleton instance of the application class for easy access in other places  */ private static ApplicationController sInstance;  @Override public void onCreate() {     super.onCreate();      // initialize the singleton     sInstance = this; }  /**  * @return ApplicationController singleton instance  */ public static synchronized ApplicationController getInstance() {     return sInstance; }  /**  * @return The Volley Request queue, the queue will be created if it is null  */ public RequestQueue getRequestQueue() {     // lazy initialize the request queue, the queue instance will be     // created when it is accessed for the first time     if (mRequestQueue == null) {         mRequestQueue = Volley.newRequestQueue(getApplicationContext());     }      return mRequestQueue; }  /**  * Adds the specified request to the global queue, if tag is specified  * then it is used else Default TAG is used.  *   * @param req  * @param tag  */ public  void addToRequestQueue(Request req, String tag) {     // set the default tag if tag is empty     req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);      VolleyLog.d("Adding request to queue: %s", req.getUrl());      getRequestQueue().add(req); }  /**  * Adds the specified request to the global queue using the Default TAG.  *   * @param req  * @param tag  */ public  void addToRequestQueue(Request req) {     // set the default tag if tag is empty     req.setTag(TAG);      getRequestQueue().add(req); }  /**  * Cancels all pending requests by the specified TAG, it is important  * to specify a TAG so that the pending/ongoing requests can be cancelled.  *   * @param tag  */ public void cancelPendingRequests(Object tag) {     if (mRequestQueue != null) {         mRequestQueue.cancelAll(tag);     } } } 

for the complete implementation ref this blog

Credits: Arnab Chakraborty



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!