2015-08-30 11 views
5

Używam biblioteki volley do wysyłania żądań i mam wyciek pamięci. Wykreśliłem to kanalizacją wycieku i wydaje mi się, że to z moich wniosków mLystenerów. Po poszukiwaniach anulować wszystkie moje prośby w moim bieżącej działalności, ale wciąż mam przeciek mogę się pomoc dzięki tutaj jest mój kod do pobrania: (uwaga: Używam Singleton uzyskania żądania wolej kolejkę)Wyciek aktywności podczas korzystania z odtwarzaczy Volley

private void startImageDownloadService(final NEWS selectedNews) { 
     if (selectedNews.getIMG_URL() != null && !selectedNews.getIMG_URL().equals("null")) { 
      ImageRequest imageRequest = new ImageRequest(selectedNews.getIMG_URL(), 
        new Response.Listener<Bitmap>() { 
       @Override 
       public void onResponse(Bitmap bitmap) { 
        newsImage_imageView.setVisibility(View.VISIBLE); 
        newsImage_imageView.setImageBitmap(bitmap); 
        saveImageToFileStarter(bitmap, selectedNews); 
       } 
      }, 200, 200, null, null, new Response.ErrorListener() { 
       @Override 
       public void onErrorResponse(VolleyError volleyError) { 
        Toast.makeText(getApplicationContext(), "Failed to download image", Toast.LENGTH_SHORT).show(); 
       } 
      }); 
      imageRequest.setShouldCache(false); 
      MyVolleySingleton.getInstance(getApplicationContext()).addToRequestQueue(imageRequest, "newsActivityImage"); 
// 
     } 
    } 


private void requestLike(final ImageButton likeButton, final long id) { 
     try { 
      StringRequest jsonRequest = new StringRequest(Request.Method.POST, G.likeURL + id + "/like", 
        new Response.Listener<String>() { 
       @Override 
       public void onResponse(String s) { 
        try { 
         Log.e("requestLikeJson", s); 
         JSONObject likeObject = new JSONObject(s); 
         int likeNumbers = likeObject.getInt("likes"); 
//      Toast.makeText(NewsActivity.this, likeNumbers + "", Toast.LENGTH_LONG) 
//        .show(); 
         if (likeButton.getTag().equals("notliked")) { 
          setLikeChangeInDatabase(false, id, likeNumbers); 
         } 
         else{ 
          setLikeChangeInDatabase(true, id, likeNumbers); 
         } 
//      viewsCount_textView.setText("" + likeNumbers); 
        } catch (JSONException e) { 
         e.printStackTrace(); 
        } 
       } 
      }, new Response.ErrorListener() { 
       @Override 
       public void onErrorResponse(VolleyError volleyError) { 
        Toast.makeText(NewsActivity.this, "No Internet connection", Toast.LENGTH_LONG).show(); 
        try { 
         volleyError.printStackTrace(); 
         Log.e("network error", new String(volleyError.networkResponse.data)); 
        } catch (Exception e) { 
         e.printStackTrace(); 
        } 
        if (likeButton.getTag().equals("notliked")) { 
         likeButton.setTag("liked"); 
         likeButtonImageSetter(); 
        } else { 
         likeButton.setTag("notliked"); 
         likeButtonImageSetter(); 
        } 
        Animation shake = AnimationUtils.loadAnimation(NewsActivity.this, R.anim.actionfeedback); 
        likeButton.startAnimation(shake); 
       } 
      }) { 

       @Override 
       public Priority getPriority() { 
        return Priority.HIGH; 
       } 

       @Override 
       public Map<String, String> getHeaders() throws AuthFailureError { 
        Map<String, String> params = new HashMap<>(); 
        Log.e("sent token", "Token " + G.token); 
        params.put("Authorization", "Token " + G.token); 
        params.put("Accept-Language", "en-US,en;q=0.8,fa;q=0.6,pt;q=0.4,ar;q=0.2,gl;q=0.2"); 

        return params; 
       } 

       @Override 
       protected Response<String> parseNetworkResponse(NetworkResponse response) { 
        String utf8String = null; 
        try { 
         utf8String = new String(response.data, "UTF-8"); 
         return Response.success(utf8String, HttpHeaderParser.parseCacheHeaders(response)); 

        } catch (UnsupportedEncodingException e) { 
         return Response.error(new ParseError(e)); 
        } 

       } 
      }; 
      jsonRequest.setRetryPolicy(new DefaultRetryPolicy(
        G.socketTimeout, 
        0, 
        DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)); 

      MyVolleySingleton.getInstance(getApplicationContext()).addToRequestQueue(jsonRequest, "like"); 
     } catch (Exception e) { 

     } 
    } 

    private void requestView(long id) { 

     try { 
      StringRequest jsonRequest = new StringRequest(Request.Method.GET, G.viewURL + id + "/view", new Response.Listener<String>() { 
       @Override 
       public void onResponse(String s) { 
        try { 
         JSONObject viewObject = new JSONObject(s); 
         Log.e("requestViewJson", s); 

        } catch (JSONException e) { 
         e.printStackTrace(); 

        } 
       } 
      }, new Response.ErrorListener() { 
       @Override 
       public void onErrorResponse(VolleyError volleyError) { 
        try { 
         volleyError.printStackTrace(); 
         Log.e("network error", new String(volleyError.networkResponse.data)); 
        } catch (Exception e) { 
         e.printStackTrace(); 
        } 
       } 
      }) { 

       @Override 
       public Map<String, String> getHeaders() throws AuthFailureError { 
        Map<String, String> params = new HashMap<>(); 
        Log.e("sent token", "Token " + G.token); 
        params.put("Authorization", "Token " + G.token); 
        params.put("Accept-Language", "en-US,en;q=0.8,fa;q=0.6,pt;q=0.4,ar;q=0.2,gl;q=0.2"); 

        return params; 
       } 

       @Override 
       public Priority getPriority() { 
        return Priority.HIGH; 
       } 

       @Override 
       protected Response<String> parseNetworkResponse(NetworkResponse response) { 
        String utf8String = null; 
        try { 
         utf8String = new String(response.data, "UTF-8"); 
         return Response.success(utf8String, HttpHeaderParser.parseCacheHeaders(response)); 

        } catch (UnsupportedEncodingException e) { 
         return Response.error(new ParseError(e)); 
        } 

       } 
      }; 
      jsonRequest.setRetryPolicy(new DefaultRetryPolicy(
        G.socketTimeout, 
        0, 
        DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)); 

      MyVolleySingleton.getInstance(getApplicationContext()).addToRequestQueue(jsonRequest,"view"); 
     } catch (Exception e) { 

     } 
    } 

iw moim OnStop() mam:

@Override 
    protected void onStop() { 
     try {//new change 
      MyVolleySingleton.getInstance(getApplicationContext()).cancelPendingRequests("newsActivityImage"); 
      MyVolleySingleton.getInstance(getApplicationContext()).cancelPendingRequests("view"); 
      MyVolleySingleton.getInstance(getApplicationContext()).cancelPendingRequests("like"); 
      loadImageFromFile.cancel(true); 
      loadImageFromFile=null; 
      }catch (Exception e){} 
     super.onStop(); 

    } 
+0

zobacz ten link: http://stackoverflow.com/a/43723971/5860087 To może rozwiązać swój cel. cześć –

Odpowiedz

3

Po pewnym badania stwierdziliśmy, że słuchacze siatkówki spowodować wyciek aktywności, ponieważ są one tworzone wystąpienia jako anonimowych klas, a zatem posiadać pośrednie odniesienie do ich zewnętrznej klasy (w tym przykładowa aktywność wiadomości), więc stworzyłem oddzielną klasę dla VolleyRequest (tylko po to, aby można było je dostosować do własnych potrzeb naprawdę nie związane z wyciekiem) i wykonany interfejs słuchacza który zaimplementować jako innerclass i zastosować słaby odniesienie do dostępu do działalności

kod

prośba:

public class MyVolleyStringRequest extends com.android.volley.toolbox.StringRequest { 

    StringResponseListener mListener; 

    public MyVolleyStringRequest(int method, String url, final StringResponseListener mListener) { 
     super(method, url, new Response.Listener<String>() { 
      @Override 
      public void onResponse(String s) { 
        mListener.onSuccess(s); 
      } 
     }, new Response.ErrorListener() { 
      @Override 
      public void onErrorResponse(VolleyError volleyError) { 
        mListener.onFailure(volleyError); 
      } 
     }); 
     this.mListener = mListener; 
    } 

    @Override 
    public Map<String, String> getHeaders() throws AuthFailureError { 
     Map<String, String> params = new HashMap<>(); 
     Log.e("sent token", "Token " + G.token); 
     params.put("Authorization", "Token " + G.token); 
     params.put("Accept-Language", "en-US,en;q=0.8,fa;q=0.6,pt;q=0.4,ar;q=0.2,gl;q=0.2"); 

     return params; 
    } 

    @Override 
    protected Response<String> parseNetworkResponse(NetworkResponse response) { 
     try { 
      String utf8String = new String(response.data, "UTF-8"); 
      return Response.success(utf8String, HttpHeaderParser.parseCacheHeaders(response)); 
     } catch (UnsupportedEncodingException e) { 
      return Response.error(new ParseError(e)); 
     } 

    } 


} 

requestLike i requestView Kod:

private void requestLike(final ImageButton likeButton, final long id) { 

      MyVolleyStringRequest likeRequest = new MyVolleyStringRequest(Request.Method.POST, G.likeURL + id + "/like", 
        new RequestLikeStringListener(this)); 
      MyVolleySingleton.getInstance(getApplicationContext()).addToRequestQueue(likeRequest, "like"); 
    } 

    private void requestView(long id) { 
     MyVolleyStringRequest viewRequest = new MyVolleyStringRequest(Request.Method.GET, G.viewURL + id + "/view", 
       new RequestViewStringListener()); 
     MyVolleySingleton.getInstance(getApplicationContext()).addToRequestQueue(viewRequest, "view"); 
    } 

kod interfejsu słuchacz:

public interface StringResponseListener { 
    void onSuccess(String response); 
    void onFailure(VolleyError error); 
} 

ja kod nnerclasses:

public static class RequestLikeStringListener implements StringResponseListener{ 

     WeakReference<NewsActivity> contextWeakReference; 
     RequestLikeStringListener(NewsActivity context){ 
      contextWeakReference = new WeakReference<>(context); 

     } 

     public void onSuccess(String response) { 
      try { 
       NewsActivity context = contextWeakReference.get(); 
       if(context != null) { 
        ImageButton likeButton = (ImageButton) context.findViewById(R.id.likeButton); 
        Log.e("requestLikeJson", response); 
        JSONObject likeObject = new JSONObject(response); 
        int likeNumbers = likeObject.getInt("likes"); 

        if (likeButton.getTag().equals("notliked")) { 
         context.setLikeChangeInDatabase(false, contextWeakReference.get().id, likeNumbers); 
        } else { 
         context.setLikeChangeInDatabase(true, contextWeakReference.get().id, likeNumbers); 
        } 
       } 

      } catch (JSONException e) { 
       e.printStackTrace(); 
      } 
     } 

     public void onFailure(VolleyError error) { 
      NewsActivity context = contextWeakReference.get(); 
      if(context != null) { 
       ImageButton likeButton = (ImageButton) context.findViewById(R.id.likeButton); 
       Toast.makeText(context, "No Internet connection", Toast.LENGTH_LONG).show(); 
       try { 
        error.printStackTrace(); 
        Log.e("network error", new String(error.networkResponse.data)); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
       if (likeButton.getTag().equals("notliked")) { 
        likeButton.setTag("liked"); 
        context.likeButtonImageSetter(); 
       } else { 
        likeButton.setTag("notliked"); 
        context.likeButtonImageSetter(); 
       } 
       Animation shake = AnimationUtils.loadAnimation(context, R.anim.actionfeedback); 
       likeButton.startAnimation(shake); 
      } 
     } 

mam nadzieję, że komuś pomaga!

Powiązane problemy