2012-01-30 17 views
14

हां, मैंने के बारे में अनगिनत प्रश्नों को बहुत ही समस्या के बारे में पढ़ा है।गतिविधि ने खिड़की/संवाद लीक की है (यह फिर से!)

मेरा कोड सरल है: मैं onCreate पर showDialog(int id) का उपयोग करता हूं, और फिर मैं डिवाइस को घुमाता हूं। कोड सिर्फ यही है (परीक्षण केस), और यह समस्या का कारण बनने के लिए पर्याप्त है। यह मेरी समझ थी कि showDialog के तरीकों का ध्यान रखा जाएगा ... संवाद गायब हो जाएगा और फिर onCreate परिवर्तन के बाद बाद में कॉल किया जाएगा और स्पष्ट रूप से संवाद को फिर से दिखाया जाएगा। लेकिन नहीं। इस तर्क के साथ क्या गलत है?

मैं (सोचता हूं) the cause समझता हूं, लेकिन मुझे नहीं पता कि इसे कैसे हल किया जाए। यहां तक ​​कि आईओएसएड विंडो के कार्यान्वयन के साथ आईओएसड ऐप में भी वही समस्या है (यूला संवाद पर अभिविन्यास बदलें और आपको रिसाव मिलती है)। मैंने ऑन-ऑन पर संवाद को खारिज करने के बारे में पढ़ा है, लेकिन 1) जब मैं पहले से नहीं दिखाया गया है तो मुझे खारिज होने का खतरा है, और 2) संवाद को ट्रैक करना बहुत अधिक काम लगता है। एक और मजबूत दृष्टिकोण होना चाहिए।

तो ... इसे संभालने के लिए आवश्यक क्लीनर कोड क्या है?

धन्यवाद।


लॉग त्रुटि उत्पादन:

01-30 00:27:18.615: E/WindowManager(20316): Activity com.test.PreSetupActivity has leaked window [email protected] that was originally added here 
01-30 00:27:18.615: E/WindowManager(20316): android.view.WindowLeaked: Activity com.test.PreSetupActivity has leaked window [email protected] that was originally added here 
01-30 00:27:18.615: E/WindowManager(20316):  at android.view.ViewRootImpl.<init>(ViewRootImpl.java:343) 
01-30 00:27:18.615: E/WindowManager(20316):  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:245) 
01-30 00:27:18.615: E/WindowManager(20316):  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:193) 
01-30 00:27:18.615: E/WindowManager(20316):  at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:118) 
01-30 00:27:18.615: E/WindowManager(20316):  at android.view.Window$LocalWindowManager.addView(Window.java:537) 
01-30 00:27:18.615: E/WindowManager(20316):  at android.app.Dialog.show(Dialog.java:274) 
01-30 00:27:18.615: E/WindowManager(20316):  at com.test.PreSetupActivity.onCreate(PreSetupActivity.java:88) 
01-30 00:27:18.615: E/WindowManager(20316):  at android.app.Activity.performCreate(Activity.java:4465) 
01-30 00:27:18.615: E/WindowManager(20316):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049) 
01-30 00:27:18.615: E/WindowManager(20316):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1919) 
01-30 00:27:18.615: E/WindowManager(20316):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1980) 
01-30 00:27:18.615: E/WindowManager(20316):  at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3347) 
01-30 00:27:18.615: E/WindowManager(20316):  at android.app.ActivityThread.access$700(ActivityThread.java:122) 
01-30 00:27:18.615: E/WindowManager(20316):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1150) 
01-30 00:27:18.615: E/WindowManager(20316):  at android.os.Handler.dispatchMessage(Handler.java:99) 
01-30 00:27:18.615: E/WindowManager(20316):  at android.os.Looper.loop(Looper.java:137) 
01-30 00:27:18.615: E/WindowManager(20316):  at android.app.ActivityThread.main(ActivityThread.java:4340) 
01-30 00:27:18.615: E/WindowManager(20316):  at java.lang.reflect.Method.invokeNative(Native Method) 
01-30 00:27:18.615: E/WindowManager(20316):  at java.lang.reflect.Method.invoke(Method.java:511) 
01-30 00:27:18.615: E/WindowManager(20316):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) 
01-30 00:27:18.615: E/WindowManager(20316):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) 
01-30 00:27:18.615: E/WindowManager(20316):  at dalvik.system.NativeStart.main(Native Method) 
+0

मैं कुछ लोग उन्हें बनाने, खिड़कियां का ट्रैक रख रहे हैं मूल रूप से देखना 'showDialog' विधि के बिना, और जांच कर रहे हैं कि वे प्रदर्शित होते हैं (' isShowing() '), और फिर तदनुसार खारिज कर रहे हैं (ऑनटॉप/ऑन पॉज़ पर)। हालांकि, मुझे विश्वास है कि यह एक सुरक्षित अनुमान है कि स्वचालित तरीका (शोडियलॉग) क्लीनर और आसान होना चाहिए, है ना? – davidcesarino

+0

आप onPostexecute() में संवाद बंद कर सकते हैं, जैसे dialog.dismiss(); – user3114805

+0

मैं इसके बजाय DialogFragment के साथ जाऊंगा। यह स्वचालित रूप से रोटेशन का प्रबंधन करता है और इस प्रकार अधिक सुरुचिपूर्ण है। – WindRider

उत्तर

13

एक आंतरिक वर्ग जो अपने stateholder रूप में कार्य करता है और जो इंगित करता है या नहीं, अपने संवाद दिखाया जा रहा है वहाँ में एक बूलियन क्षेत्र की है। उन्मुखीकरण भर में इस पर नज़र रखें परिवर्तन onRetainNonConfigurationInstance का उपयोग कर और सिर्फ onResume

यहाँ पर संवाद को फिर से दिखाने के है कुछ कोड + छद्म कोड:

public class ProfileActivity extends Activity { 
    private StateHolder mStateHolder; 
    private Dialog dialog; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    Object retained = getLastNonConfigurationInstance(); 
    if (retained != null && retained instanceof StateHolder) { 
     mStateHolder = (StateHolder) retained; 
    } else { 
     mStateHolder = new StateHolder(); 
    } 
    } 

    @Override 
    public Object onRetainNonConfigurationInstance() { 
    return mStateHolder; 
    } 

    @Override 
    public void onPause() { 
    super.onPause(); 
    if(dialog != null && dialog.isShowing()) { 
     dialog.dismiss(); 
    } 
    } 

    @Override 
    public void onResume() { 
    if(mStateHolder.mIsShowingDialog) { 
     dialog.show(); 
    } 
    } 

    private void showDialog() { 
    mStateHolder.mIsShowingDialog = true; 
    dialog.show(); 
    } 

    private static class StateHolder { 
    boolean mIsShowingDialog; 
    public StateHolder() {} 
    } 

} 
+0

हम्म, दुर्भाग्य से मैं खुद को आश्वस्त कर रहा हूं कि 'शोडियलॉग' सिर्फ एक पिटा (माफ करना) है। मैं मैन्युअल संवाद के संबंध में इस समाधान का प्रयास करूंगा और रिपोर्ट करूंगा। धन्यवाद! – davidcesarino

+1

फिर से धन्यवाद। मैं उपर्युक्त अवधारणा का उपयोग कर रहा हूं और यह पूरी तरह से काम कर रहा है! मैंने बार-बार एमुलेटर में बहुत जल्दी Ctrl + F11 दबाया, प्रति सेकंड दो बार अभिविन्यास बदलना, कई बार ... कुछ ऐसा जो कि एक सामान्य फोन में कोई उपयोगकर्ता कभी नहीं करेगा। और मेरी लॉग लाइनें जितनी साफ हो सकती थी उतनी साफ थीं। बहुत बहुत धन्यवाद क्योंकि इसने मुझे कल कुछ समय खो दिया था। – davidcesarino

+0

ग्रेट उत्तर, मैंने 'ऑनपोज़() ' – rahstame

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