2014-10-28 8 views
7

में वॉली के साथ वीक रेफरेंस का उपयोग करना चाहिए this article पढ़ने के बाद, मैंने वॉली के साथ मेमोरी लीक के बारे में सोचना शुरू कर दिया। आमतौर पर, वॉली के साथ लागू श्रोताओं के पास बाहरी वर्ग (गतिविधि) का एक अंतर्निहित या स्पष्ट संदर्भ होता है।क्या मुझे मेमोरी लीक के बारे में चिंता करना चाहिए और एंड्रॉइड

JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.GET, 
     url, null, 
     new Response.Listener<JSONObject>() { 
      @Override 
      public void onResponse(JSONObject response) { 

       updateLayout(); 
      } 
     } 
इस मामले में

वहाँ एक अंतर्निहित संदर्भ है ... या मैं प्रतिक्रिया से निपटने भली के लिए एक कस्टम JsonObjectRequest बनाते हैं, और इसके निर्माता में बुला गतिविधि के लिए एक संदर्भ में पारित करने के लिए की जरूरत है सकते हैं: उदाहरण के लिए ।

अब कहें कि मैं एक वेब अनुरोध शुरू करता हूं, लेकिन प्रतिक्रिया वापस आने से पहले, मैं उस अनुरोध से दूर नेविगेट करता हूं जिसने अनुरोध शुरू किया था। जो मैं समझता हूं उससे JsonObjectRequest ऑब्जेक्ट मेरी गतिविधि का संदर्भ रखेगा और उसे कचरा एकत्र करने से रोक देगा।
- क्या मैं इसे सही ढंग से समझ रहा हूं, क्या यह एक वैध डर है?
-क्या वॉली लाइब्रेरी स्वचालित रूप से इस से निपटती है?
-अगर मैं एक कस्टम JsonObjectRequest बना रहा हूं और "इस" (गतिविधि के संदर्भ में) में गुजर रहा हूं, तो क्या मुझे गतिविधि में कमजोरता बनाने की आवश्यकता है?

+1

[वॉली दस्तावेज़ीकरण] (https://developer.android.com/training/volley/simple.html) पर एक नज़र डालें। ऐसा लगता है कि जब तक आप अपने खंड/गतिविधि के 'ऑनस्टॉप()' विधि में अपने वॉली अनुरोधों पर रद्द करना सुनिश्चित करते हैं, तो हैंडलर को नहीं बुलाया जाएगा। मुझे लगता है कि इसका मतलब यह भी है कि खंड/गतिविधि का संदर्भ भी हटा दिया जाएगा, जिसका अर्थ है कि टुकड़ा/गतिविधि अब लीक नहीं हुई है। –

+0

@tmalseed धन्यवाद, आपको अपनी टिप्पणी को उत्तर के रूप में पोस्ट करना चाहिए, और मैं इसे स्वीकार करूंगा – Siavash

+0

मुझे 100% विश्वास नहीं है कि यह सही या सबसे उचित उत्तर है। मैंने अपनी सलाह का पालन किया और * हो सकता है * अभी भी गतिविधि को लीक कर रहा है .. –

उत्तर

5

वॉली कोड को देखने के आधार पर, कॉलिंग रद्द करना वास्तव में स्मृति रिसाव से बचता नहीं है क्योंकि संदर्भ कभी भी साफ़ नहीं होता है और संदर्भ कमजोर नहीं होता है। कॉलिंग रद्द करने से वॉली को श्रोता को प्रतिक्रिया देने से बचा जाता है।

समस्या का मेरा समाधान क्लोनिंग और पुस्तकालय को संशोधित करना होगा।

  • समाधानों में से एक आधार बेस अनुरोध के अंदर बेस Erroristist संदर्भ बनाने के लिए अनुरोध कर सकता है Request.java कमजोर संदर्भ होने के लिए। और इसी तरह JsonRequest.java के अंदर श्रोता को भी किया जा सकता है।

  • दूसरा समाधान मैन्युअल रूप से कॉल करने के संदर्भ पर संदर्भ को साफ़ करना हो सकता है। रद्द करने के अंदर(), mrrrorListener और mListener को शून्य पर सेट करें। हालांकि इस समाधान के साथ, आपको फील्ड घोषणा से अंतिम संशोधक को हटाना होगा अन्यथा आपको संदर्भ को शून्य सेट करने की अनुमति नहीं दी जाएगी।

उम्मीद है कि इससे मदद मिलती है।

+1

मैंने विकल्प 2 लागू किया है और अब तक इतना अच्छा है । मुझे वॉलीलॉग के कारण एक और रिसाव मिली है लेकिन यह एक अलग विषय है। – Lancelot

+0

वास्तव में वॉली क्लोन करने की कोई ज़रूरत नहीं है। बस उपclass [अनुरोध] (https://android.googlesource.com/platform/frameworks/volley/+/2afdd91aba3a7a5396fe96dfe8f930661e56ea9a/src/com/android/volley/Request.java) या [जेसनआरक्वेट] (https: //android.googlesource .com/platform/frameworks/volley/+/2afdd91aba3a7a5396fe96dfe8f930661e56ea9a/src/com/android/volley/toolbox/JsonRequest.java) और श्रोता को स्वयं को संभालें (रद्द करते समय उन्हें साफ़ करने का हिस्सा जोड़कर) कहा जाता है)। – verybadalloc

2

मैं आपको यहां लिखने के तरीके की तरह वॉली का उपयोग करते समय स्मृति रिसाव का सामना करना पड़ा। हर बार जब मैं एक नया श्रोता नया हूं।

मैंने लीकिंग का पता लगाने के लिए लीककेनरी का उपयोग किया।

जब मैंने आपके आलेख, http://www.androiddesignpatterns.com/2013/01/inner-class-handler-memory-leak.html के बारे में पढ़ा, और गतिविधि और कॉलबैक इंटरफ़ेस (स्वयं अनुकूलित) के लिए वीक रेफरेंस का उपयोग किया, तो हल हो गया।

मैंने वॉली को सिंगलटन के रूप में उपयोग किया।

public interface VolleyCallback { 
    void onSuccess(JSONObject result); 

    void onFailed(String error); 
} 

private static class SListener implements Response.Listener<JSONObject> { 
    private final WeakReference<Activity> activityWeakReference; 
    private final WeakReference<VolleyCallback> callbackWeakReference; 

    public SListener(Activity activity, VolleyCallback callback) { 
     activityWeakReference = new WeakReference<Activity>(activity); 
     callbackWeakReference = new WeakReference<VolleyCallback>(callback); 
    } 

    @Override 
    public void onResponse(JSONObject jsonObject) { 
     Activity act = activityWeakReference.get(); 
     VolleyCallback vc = callbackWeakReference.get(); 
     if (act != null && vc != null) { 
      LogUtil.d(TAG, act.toString() + " " + jsonObject.toString()); 
      something you need to do; 
      vc.onSuccess(jsonObject); 
     } 
    } 

मैं भी इस सवाल का जवाब, How to use WeakReference in Java and Android development?, दूसरा जवाब पढ़ें सिर्फ अपने लेख provide.It की अच्छी तरह एक उदाहरण देता हूँ।

1

मैं शायद इस साल एक पार्टी तक देर से हूं लेकिन मुझे इस मुद्दे को हल करने का एक तरीका पता चला। यहां यह है:

public interface VolleyCallback { 
    void onSuccess(JSONObject result); 

    void onFailed(String error); 
} 

private static class SListener implements VolleyCallback { 
    private final WeakReference<MainActivity> activityWeakReference; 

    public SListener(MainActivity activity, VolleyCallback callback) { 
     activityWeakReference = new WeakReference<>(activity); 
    } 
@Override 
    void onSuccess(JSONObject result){ 
} 
@Override 
    void onFailed(String error){ 
    } 
    } 

यहां आप गतिविधि WeakReference का उपयोग कर सकते हैं।मुख्य एक्टिविटी के सभी यूआई तत्वों तक पहुंचने के लिए() प्राप्त करें। इसे http://www.androiddesignpatterns.com/2013/01/inner-class-handler-memory-leak.html से मिला। इस तरह हमें ऑनस्टॉप() में किसी भी अनुरोध को रद्द करने की आवश्यकता नहीं है। गतिविधि मौजूद नहीं होने पर क्रैश से बचने के लिए activityWeakReference.get().isFinishing & & activityWeakReference.get()!=null का उपयोग करना याद रखें।

+0

हैलो, मुझे एक ही समस्या है और आपका जवाब मिल गया है, क्या आप उपरोक्त कोड को कहां रखना है, इसे कार्यान्वित करने के तरीके को साझा करना चाहते हैं। मेरे ऐप में मेरा नमूना वॉली कार्यान्वयन यहां दिया गया है। https://gist.github.com/arvi/587b2f4cb582ad96c98645212e7b2baf बहुत बहुत धन्यवाद। – Woppi

+0

आपको एक नई स्थिर आंतरिक कक्षा बनाना चाहिए और नए प्रतिक्रिया को लागू करना चाहिए। लिस्टनर <प्रोफाइल मॉडल> ​​और एक कमजोर संदर्भ में पास करें। –

संबंधित मुद्दे

 संबंधित मुद्दे