2017-10-30 27 views
6

मैं Google की वॉली लाइब्रेरी का उपयोग करता हूं और अब मैं कमजोर लोगों के लिए अपने ऐप्स में मेमोरी लीक से जूझ रहा हूं। मैंने बहुत अधिक शोध किया है और बहुत पहले से ही कोशिश की है लेकिन अब मुझे नहीं पता कि क्या करना है। यह एक नमूना कोड है:एंड्रॉइड वॉली मेमोरी लीक्स

SplashActivity.java

public class SplashActivity extends AppCompatActivity { 

    Context mContext; 
    AuthRequest mAuthRequest; 
    GetTokenOnSuccessListener mGetTokenOnSuccessListener; 
    GetTokenOnErrorListener mGetTokenOnErrorListener; 
    private ConfigTable mConfigTable; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     initialiseViewsAndComponents(); 
    } 

    @Override 
    protected void onStart() { 
     super.onStart(); 
     getAuthToken(); 
    } 

    private void initialiseViewsAndComponents() { 
     mContext = SplashActivity.this; 
     mAuthRequest = new AuthRequest(mContext); 
     mGetTokenOnSuccessListener = new GetTokenOnSuccessListener(mContext); 
     mGetTokenOnErrorListener = new GetTokenOnErrorListener(mContext); 
     mConfigTable = new ConfigTable(mContext); 
    } 

    private void getAuthToken() { 
     if (!mConfigTable.get("INITIALISED").equals("")) { 
      mAuthRequest.guest(mGetTokenOnSuccessListener, mGetTokenOnErrorListener); 
     } else { 
      Intent mainIntent = new Intent(mContext, MainActivity.class); 
      startActivity(mainIntent); 
     } 
    } 

} 

GetTokenOnSuccessListener.java

public class GetTokenOnSuccessListener implements Response.Listener<JSONObject> { 

    //private Activity mActivity; 
    private Context mContext; 
    private ConfigTable mConfigTable; 
    private int mSuccess = 0; 
    private String mMessage = ""; 

    public GetTokenOnSuccessListener(Context context) { 
     //this.mActivity = context; 
     this.mContext = context; 
     this.mConfigTable = new ConfigTable(this.mContext); 
    } 

    @Override 
    public void onResponse(JSONObject response) { 
     try { 
      mSuccess = Integer.parseInt(response.get("success").toString()); 
      mMessage = response.get("message").toString(); 

      if (mSuccess == 1) { 
       mConfigTable.setAuthToken(response.get("message").toString()); 
       Intent mainIntent = new Intent(mContext, MainActivity.class); 
       mContext.startActivity(mainIntent); 
       ((SplashActivity) mContext).finish(); 
      } else { 
       Toast.makeText(mContext, "Lol access denied, could not retrieve token from server.", Toast.LENGTH_SHORT).show(); 
      } 


     } catch (JSONException e) { 
      e.printStackTrace(); 
      Toast.makeText(mContext, "Lol access denied, could not retrieve token from server.", Toast.LENGTH_SHORT).show(); 
     } 
    } 
} 

GetTokenOnErrorListener.java

public class GetTokenOnErrorListener implements Response.ErrorListener { 

    private Context mContext; 

    public GetTokenOnErrorListener(Context context) { 
     this.mContext = context; 
    } 

    @Override 
    public void onErrorResponse(VolleyError error) { 
     Utils.showNetworkResponse(mContext, error); 
    } 
} 

ठीक है अब मैं अपने स्वयं के जवाब श्रोताओं ले जाया गया ऑनलाइन पढ़ते हुए कुछ अलग-अलग वर्गों के आधार पर अलग-अलग कक्षाएं यह सोचती हैं कि यह एल को हल करेगी eak लेकिन नहीं यह नहीं किया। मैंने सभी लंबित अनुरोधों को रद्द करने के लिए कोड जोड़ा ऑनस्ट्रोय() अनुरोध के टैग के आधार पर लेकिन फिर भी मुझे स्मृति रिसाव था।

यह सिर्फ मेरी स्पलैश गतिविधि है और यहां लीक छोटी हैं, मुझे ऐसा लगता है क्योंकि मैं इसे खत्म करता हूं() लेकिन मुझे यह नहीं मिला क्योंकि अनुरोध सफलतापूर्वक पूरा होने के बाद मैं इसे कॉल करता हूं। मेरी सभी अन्य गतिविधियों में समान कोड हैं लेकिन 11mb जितनी अधिक मेमोरी लीक करें।

तो मेरा सवाल है कि किसी ने वॉली लाइब्रेरी के साथ काम किया है? मैं इसका उपयोग कैसे करूं और मेमोरी लीक से बचूं?

इस संस्करण का उपयोग करना:

compile 'com.android.volley:volley:1.0.0' 
+0

https://github.com/google/volley/issues/81 –

+0

मुझे एहसास है कि यह तुरंत सहायक नहीं है, लेकिन मैं अत्यधिक वॉली को स्विच करने की सलाह देता हूं।यह ऐतिहासिक रूप से अनियंत्रित किया गया है। यदि एक ही पुस्तकालय किसी और द्वारा बनाया गया था, तो कोई भी इसका उपयोग नहीं करेगा। आरएक्सजेवा ने खुद को केवल http अनुरोधों के लिए एंड्रॉइड पर बेहतर अबास्ट्रेशन साबित कर दिया है, लेकिन सभी एसिंक्रोनस डेटा, और डेटा के स्टीम से सदस्यता समाप्त करने की क्षमता प्रदान करता है ताकि कोई और मेमोरी लीक न हो। वोल्ले की तुलना में आरएक्सजेवा + रेट्रोफिट एक बेहतर फिट है। मैं अत्यधिक माइग्रेटिंग की सलाह देते हैं। – spierce7

+0

@ spierce7 वह आरएक्स का उपयोग कैसे करेगा, अगर वह नियमित अनुरोधों में भी मूल सिद्धांतों को समझ में नहीं आता है? उपयोग की जाने वाली लाइब्रेरी के बावजूद इस रिसाव से बचा जा सकता है। – Dimezis

उत्तर

-2

आप हमेशा ही नया गतिविधि बना रहे हैं। कृपया इसके बजाय इसे आजमाएं। इसके बारे में यहाँ और अधिक पढ़ें: https://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_CLEAR_TOP

Intent mainIntent = new Intent(mContext, MainActivity.class); 
mainIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
mContext.startActivity(mainIntent); 
+2

इससे कोई फर्क नहीं पड़ता क्योंकि मेनएक्टिविटी स्पलैश स्क्रीन से केवल एक बार दिखाई जाती है। साथ ही, एक ही गतिविधि को कई बार शुरू करने से मेमोरी रिसाव नहीं बन जाता है जब तक कि आपके पास मेमोरी लीक बनाने वाला कोड न हो। –

3

यह पर्याप्त बस "अपनी अलग वर्गों के जवाब श्रोताओं ले जाएँ" करने के लिए नहीं है। आपके श्रोताओं के पास गतिविधि के दौरान एक रिसाव पेश करने, गतिविधि (mContext) के मजबूत संदर्भ हैं। इसका मतलब यह है कि अनुरोध चालू होने पर आपकी गतिविधि कचरा नहीं हो सकती है। यह वास्तव में वॉली की गलती नहीं है, बल्कि चीजों का एक प्राकृतिक तरीका है।

आप अपने मामले में विकल्पों में से जोड़ी:

1) अपने श्रोताओं के लिए एक WeakReference<Context>, बजाय संदर्भ के लिए एक मजबूत संदर्भ दर्रा। इस तरह आप एक रिसाव पेश नहीं करेंगे और यह जांचना होगा कि क्या यह संदर्भ संदर्भ अभी तक शून्य नहीं है, जब आप इसे एक्सेस करने का प्रयास करते हैं। लेकिन मैं दूसरे विकल्प के लिए जाना चाहूंगा।

2) श्रोताओं में null, जब गतिविधि के onDestroy() कहा जाता है के लिए mContext सेट करें। और जब आप श्रोता में संदर्भ के साथ कुछ करने की कोशिश कर रहे हैं, तो भी शून्य जांच करें। तो जैसे ही गतिविधि नष्ट हो जाएगी, आप इसे अन्य मजबूत संदर्भों को हटा देंगे, जिससे जीसी सामान्य रूप से इसे इकट्ठा कर सके।

+0

आपके समय के लिए धन्यवाद, इसे आज़माएं और देखें कि यह मदद करता है या नहीं। – user3718908

+0

हालांकि, एक सवाल यह मानते हुए कि मैं संदर्भ को एक चर में संग्रहीत नहीं करता हूं और इसके बजाय मैं 'MainActivity.this' कहता हूं, तब मैं इसके बारे में क्या करूँ? क्योंकि मैं 'MainActivtiy.this' को शून्य पर सेट नहीं कर सकता। मुझे माफ़ कर दो मैं एंड्रॉइड देव के लिए काफी नया हूँ। – user3718908

+0

@ user3718908 यह प्रभावी रूप से संदर्भ के संदर्भ को संग्रहीत करने जैसा ही है, क्योंकि आपके आंतरिक (या आंतरिक अज्ञात) वर्ग के पास हमेशा इसका एक निहित संदर्भ है। तो ऐसा मत करो – Dimezis

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