2012-12-28 79 views
15

परिचय:EditText के कारण स्मृति रिसाव

मेरे पास है जो निम्नलिखित संरचना है एक ऐप्लिकेशन: ActionBar ऊपर शीर्ष (ActionBarSherlock) कि नीचे ViewPagerIndicator (टैब के लिए) ViewPager (मेजबान टुकड़े)

मुझे एक समस्या है कि मेरे टुकड़ों में से एक बल्कि बड़ी स्मृति रिसाव पैदा कर रहा है। मैंने समस्या को निम्नलिखित मामले में संकुचित कर दिया:

रिसाव का कारण बनने वाला टुकड़ा कुछ भी नहीं करता है, लेकिन onCreateView विधि में एक लेआउट को बढ़ाता है। यह निम्न तरीके से किया जाता है:

return inflater.inflate(R.layout.filter_auctions_fragment, container, false); 

यहां कुछ असामान्य नहीं है।

लेआउट फ़ाइल केवल एक ScrollView, LinearLayout और दो EditText रों भी शामिल है में यह (अधिक सामान्य रूप से सामान शामिल है, लेकिन मैं सिर्फ इन विचारों के लिए नीचे समस्या संकुचित इसे सरल बनाने के लिए)।

अब कोड जो टुकड़ा जोड़ने के लिए उपयोग किया जाता है: mTabsAdapter.addTab (tabName, ProblematicFragment.class);

mTabsAdapterTabsAdapter का एक उदाहरण है, जो एक वर्ग है जो समर्थन पुस्तकालय के FragmentPagerAdapter को बढ़ाता है। यह मानक है इसलिए मैं इस सवाल को जितना संभव हो सके छोटा रखने के लिए स्रोत शामिल नहीं कर रहा हूं।

अब अजीब हिस्सा:

यह वही ढेर के साथ होता है जब मैं आगे और पीछे कई बार मेरे डिवाइस बारी बारी से है:

12-28 12:26:27.180: D/dalvikvm(18841): GC_CONCURRENT freed 530K, 7% free 10701K/11436K, paused 4ms+7ms, total 58ms 
12-28 12:26:27.180: D/dalvikvm(18841): WAIT_FOR_CONCURRENT_GC blocked 24ms 
12-28 12:26:28.270: D/dalvikvm(18841): GC_CONCURRENT freed 737K, 8% free 11048K/11964K, paused 4ms+5ms, total 53ms 
12-28 12:26:29.510: D/dalvikvm(18841): GC_CONCURRENT freed 789K, 8% free 11464K/12436K, paused 5ms+5ms, total 42ms 
12-28 12:26:30.640: D/dalvikvm(18841): GC_CONCURRENT freed 888K, 9% free 11919K/12984K, paused 4ms+5ms, total 52ms 
12-28 12:26:31.810: D/dalvikvm(18841): GC_CONCURRENT freed 903K, 8% free 12421K/13500K, paused 3ms+8ms, total 58ms 
12-28 12:26:33.800: D/dalvikvm(18841): GC_CONCURRENT freed 1092K, 9% free 13005K/14272K, paused 4ms+6ms, total 59ms 
12-28 12:26:33.800: D/dalvikvm(18841): WAIT_FOR_CONCURRENT_GC blocked 20ms 
12-28 12:26:36.000: D/dalvikvm(18841): GC_CONCURRENT freed 1355K, 11% free 13518K/15048K, paused 3ms+8ms, total 74ms 
12-28 12:26:36.000: D/dalvikvm(18841): WAIT_FOR_CONCURRENT_GC blocked 19ms 
12-28 12:26:38.110: D/dalvikvm(18841): GC_CONCURRENT freed 1450K, 11% free 14106K/15720K, paused 3ms+11ms, total 72ms 
12-28 12:26:40.450: D/dalvikvm(18841): GC_CONCURRENT freed 1530K, 11% free 14807K/16516K, paused 2ms+15ms, total 75ms 
12-28 12:26:40.450: D/dalvikvm(18841): WAIT_FOR_CONCURRENT_GC blocked 29ms 
12-28 12:26:43.030: D/dalvikvm(18841): GC_CONCURRENT freed 1682K, 11% free 15591K/17452K, paused 3ms+10ms, total 66ms 
12-28 12:26:43.030: D/dalvikvm(18841): WAIT_FOR_CONCURRENT_GC blocked 32ms 

जाहिर है, एक स्मृति रिसाव। हां, मुझे पता है कि यह जमीन को जमीन से पुनर्निर्मित करने का कारण बनता है और यही वह है जो मैं चाहता हूं क्योंकि मेरे पास परिदृश्य और चित्र मोड के लिए अलग-अलग लेआउट हैं। फिर भी यह स्मृति रिसाव का कारण नहीं बनना चाहिए।

मुझे इस समस्या का स्रोत मिला है। यह दो EditText है जिसका मैंने पहले उल्लेख किया था। जैसे ही मैं उन्हें लेआउट से हटा देता हूं और वही परीक्षण करता हूं (पीछे और आगे घुमाएं)। ये जीसी संदेश मुझे मिलते हैं:

12-28 12:21:41.270: D/dalvikvm(17934): GC_CONCURRENT freed 534K, 7% free 10853K/11576K, paused 3ms+7ms, total 44ms 
12-28 12:21:42.560: D/dalvikvm(17934): GC_CONCURRENT freed 818K, 9% free 11113K/12108K, paused 11ms+9ms, total 95ms 
12-28 12:21:44.680: D/dalvikvm(17934): GC_CONCURRENT freed 1036K, 10% free 11313K/12528K, paused 3ms+6ms, total 54ms 
12-28 12:21:44.680: D/dalvikvm(17934): WAIT_FOR_CONCURRENT_GC blocked 15ms 
12-28 12:21:47.420: D/dalvikvm(17934): GC_CONCURRENT freed 1089K, 10% free 11510K/12780K, paused 2ms+6ms, total 79ms 
12-28 12:21:47.420: D/dalvikvm(17934): WAIT_FOR_CONCURRENT_GC blocked 39ms 
12-28 12:21:50.200: D/dalvikvm(17934): GC_CONCURRENT freed 1317K, 12% free 11461K/12956K, paused 4ms+13ms, total 84ms 
12-28 12:21:53.210: D/dalvikvm(17934): GC_CONCURRENT freed 1629K, 14% free 11148K/12956K, paused 3ms+7ms, total 47ms 
12-28 12:21:55.580: D/dalvikvm(17934): GC_CONCURRENT freed 1056K, 13% free 11302K/12956K, paused 4ms+7ms, total 59ms 
12-28 12:21:57.280: D/dalvikvm(17934): GC_CONCURRENT freed 1306K, 14% free 11200K/12956K, paused 5ms+5ms, total 82ms 
12-28 12:21:59.420: D/dalvikvm(17934): GC_CONCURRENT freed 1035K, 12% free 11408K/12956K, paused 3ms+7ms, total 55ms 
12-28 12:22:01.990: D/dalvikvm(17934): GC_CONCURRENT freed 1392K, 13% free 11352K/12956K, paused 4ms+9ms, total 54ms 
12-28 12:22:01.990: D/dalvikvm(17934): WAIT_FOR_CONCURRENT_GC blocked 30ms 

अब मैं यही देखना चाहता हूं!

क्यों !?

क्या कोई मुझे बता सकता है कि यह क्यों हो रहा है? मैं यह जोड़ना चाहता हूं कि मैं अपने ऐप में कहीं भी EditText ऑब्जेक्ट का संदर्भ नहीं रख रहा हूं (मैं आमतौर पर करता हूं, लेकिन जब भी मैंने परीक्षण उद्देश्यों के लिए उन सभी को हटा दिया तब भी रिसाव होता है)।

बोनस - रिसाव की मेट स्क्रीनशॉट:

Path to GC Roots (whtout soft/weak refs) for my Activity

Path to GC Roots (whtout soft/weak refs) for my "ProblematicFragment"

जबकि वहाँ केवल एक ही होना चाहिए आप टुकड़ा और गतिविधि के 16 उदाहरणों, देखते हैं देख सकते हैं।

संपादित करें:

मैंने देखा है कि जब मैं स्वयं एक अलग गतिविधि में टुकड़ा जोड़ने (का उपयोग कर FragmentManager.beginTransaction()) रिसाव नहीं होती है !!! मैं अब पूरी तरह से उलझन में हूँ ...

EDIT2:

EditText रों फिक्स इसके बारे में android:id विशेषता निकाल रहा है ... लेकिन अब वे बहुत बेकार हो ...

+1

आपने एमटी डिस्प्ले के 'मूल टेक्स्ट' हिस्से को खोलने के लिए नहीं देखा है, यह देखने के लिए कि आपकी अतिरिक्त प्रतियां कहां से आ रही हैं। अपने स्क्रीनशॉट के नीचे से तीसरी पंक्ति देखें। – CommonsWare

+0

हो सकता है कि यह इतना चर्चा से संबंधित है - http://stackoverflow.com/questions/8497965/why-does-editview-retain-its-activitys-context-in-ice-cream-sandwich –

+1

मैं एक ही है मुद्दा, क्या आपको कोई समाधान मिला है? – MobDev

उत्तर

5

मेरे पास है एक समाधान मिला जो मेरी जरूरतों को फिट करता है।

मैं widget.EditableInputConnection लिए समस्या नीचे ट्रैक किए गए। जो मुझे लगता है कि सुझाव प्रणाली में लुकअप करता है। यह मेरी गतिविधि को पकड़ने के लिए भी जिम्मेदार है, इसलिए स्मृति रिसाव का कारण बनता है।

मुझे सुझावों की आवश्यकता नहीं है इसलिए मैं इसे बंद करना चाहता था। हालांकि यह मुश्किल साबित हुआ है। EditText.setInputType काम नहीं किया, न तो एक्सएमएल और न ही कोड में।

मैं निम्नलिखित कर समाप्त हो गया। जादू onCreateInputConnection() में हो रहा है:

public class MyEditText extends TextView { 
    public MyEditText(Context context) { 
     this(context, null); 
    } 

    public MyEditText(Context context, AttributeSet attrs) { 
     this(context, attrs, android.R.attr.editTextStyle); 
    } 

    public MyEditText(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
    } 

    @Override 
    public InputConnection onCreateInputConnection(EditorInfo outAttrs) { 
     return null; 
    } 

    @Override 
    protected boolean getDefaultEditable() { 
     return true; 
    } 

    @Override 
    protected MovementMethod getDefaultMovementMethod() { 
     return ArrowKeyMovementMethod.getInstance(); 
    } 

    @Override 
    public Editable getText() { 
     return (Editable) super.getText(); 
    } 

    @Override 
    public void setText(CharSequence text, BufferType type) { 
     super.setText(text, BufferType.EDITABLE); 
    } 

    /** 
    * Convenience for {@link Selection#setSelection(Spannable, int, int)}. 
    */ 
    public void setSelection(int start, int stop) { 
     Selection.setSelection(getText(), start, stop); 
    } 

    /** 
    * Convenience for {@link Selection#setSelection(Spannable, int)}. 
    */ 
    public void setSelection(int index) { 
     Selection.setSelection(getText(), index); 
    } 

    /** 
    * Convenience for {@link Selection#selectAll}. 
    */ 
    public void selectAll() { 
     Selection.selectAll(getText()); 
    } 

    /** 
    * Convenience for {@link Selection#extendSelection}. 
    */ 
    public void extendSelection(int index) { 
     Selection.extendSelection(getText(), index); 
    } 

    @Override 
    public void setEllipsize(TextUtils.TruncateAt ellipsis) { 
     if (ellipsis == TextUtils.TruncateAt.MARQUEE) { 
      throw new IllegalArgumentException("EditText cannot use the ellipsize mode " 
        + "TextUtils.TruncateAt.MARQUEE"); 
     } 
     super.setEllipsize(ellipsis); 
    } 
} 

चाल कहाँ InputConnection मना करने के लिए है। यह सुझावों को हटा देता है और स्मृति रिसाव को हटा देता है।

आशा इस मदद करता है आप के लिए ..

+1

जादू! एंड्रॉइड के किस संस्करण ने आपने इसका परीक्षण किया है, कृपया? –

+0

मैं इस पर परीक्षण करने के लिए इसे प्राप्त करने में सक्षम नहीं हूं, अनुकरणकर्ता 17,18,19 और एन 4। – newfivefour

0

मैं ठीक उसी मुद्दे को एक सैमसंग गैलेक्सी एस 3 के साथ सामना करना पड़ रहा था।

solution from @aslakjo मेरे लिए काम किया नहीं था। मैं सुझाव अक्षम कर दिया था पहले से ही

मैं एक्सएमएल लेआउट में EditText के लिए android:tag द्वारा android:id की जगह समाप्त हो गया। अब यह ठीक काम कर रहा है, मेरे टुकड़े जो व्यूपायर में निहित थे, सही ढंग से कचरा इकट्ठा होते हैं जब अब दिखाई नहीं देते हैं, मुझसे मत पूछें क्यों।

यह डिवाइस id की उपस्थिति के आधार पर कुछ पंजीकृत कर सकता है।