गतिविधि ने खिड़की को लीक कर दिया है जो मूल रूप से जोड़ा गया था


1160

यह त्रुटि क्या है, और ऐसा क्यों होता है?

05-17 18:24:57.069: ERROR/WindowManager(18850): Activity com.mypkg.myP has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@44c46ff0 that was originally added here
05-17 18:24:57.069: ERROR/WindowManager(18850): android.view.WindowLeaked: Activity ccom.mypkg.myP has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@44c46ff0 that was originally added here
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.view.ViewRoot.<init>(ViewRoot.java:231)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.view.Window$LocalWindowManager.addView(Window.java:424)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.app.Dialog.show(Dialog.java:239)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at com.mypkg.myP$PreparePairingLinkageData.onPreExecute(viewP.java:183)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.os.AsyncTask.execute(AsyncTask.java:391)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at com.mypkg.myP.onCreate(viewP.java:94)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2544)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2621)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.app.ActivityThread.access$2200(ActivityThread.java:126)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1932)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.os.Handler.dispatchMessage(Handler.java:99)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.os.Looper.loop(Looper.java:123)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.app.ActivityThread.main(ActivityThread.java:4595)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at java.lang.reflect.Method.invokeNative(Native Method)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at java.lang.reflect.Method.invoke(Method.java:521)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at dalvik.system.NativeStart.main(Native Method)

6
अन्य क्लासिक है जब अभिविन्यास बदलता है: stackoverflow.com/questions/1111980/…
rds

जवाबों:


1559

गतिविधि से बाहर निकलने के बाद आप एक डायलॉग दिखाने की कोशिश कर रहे हैं।

[संपादित करें]

यह सवाल एंड्रॉइड डेवलपर के लिए Google पर शीर्ष खोज में से एक है, इसलिए टिप्पणियों से कुछ महत्वपूर्ण बिंदुओं को जोड़ना, जो टिप्पणी वार्तालाप की गहराई में जाए बिना भविष्य के अन्वेषक के लिए अधिक सहायक हो सकता है।

उत्तर 1 :

गतिविधि से बाहर निकलने के बाद आप एक डायलॉग दिखाने की कोशिश कर रहे हैं।

उत्तर २

यह त्रुटि कुछ परिस्थितियों में थोड़ी भ्रामक हो सकती है (हालाँकि उत्तर अभी भी पूरी तरह से सही है) - अर्थात मेरे मामले में एक असंशोधित अपवाद को एक AsyncTask में फेंक दिया गया था, जिसके कारण गतिविधि बंद हो गई थी, तब एक खुले प्रगतिशीलता के कारण यह अपवाद हुआ .. तो 'वास्तविक' अपवाद लॉग में थोड़ा पहले था

उत्तर ३

अपनी गतिविधि से बाहर निकलने से पहले आपके द्वारा बनाए गए डायलॉग इंस्टेंस पर कॉल खारिज (), जैसे ऑनपॉज () या ऑनस्टेस्टॉय)


2
@Override सार्वजनिक शून्य onStop () {if (संवाद! = Null) {dialog.dismiss (); संवाद = अशक्त; }}
Md.Tarikul इस्लाम

14
8 साल बाद भी यह प्रासंगिक है! मुझे अपवाद मिला क्योंकि गतिविधि को बंद कर दिया गया था, जबकि यह मेरे अलर्टडॉग (इसलिए उत्तर 2) को प्रदर्शित करने की कोशिश कर रहा था। अंत में मुझे पता चला कि ऐप दृश्य में "अशक्त" ऑब्जेक्ट जोड़ रहा था (ऐसा नहीं होना चाहिए था लेकिन ऐसा किया गया था), लेकिन इसने इसके लिए कोई अतिरिक्त अपवाद नहीं दिया और पूरी चीज़ "लीक" द्वारा मास्क की गई थी इसके बजाय विंडो "अपवाद।
नेफ सिप

क्या सभी खुले संवादों को स्कैन करना और उन सभी को ऑनटॉप () में बंद करना संभव है? मैं आइटम पर क्लिक करते समय एक सूची दृश्य में संवाद उत्पन्न करता हूं। मुझे यकीन नहीं है कि onStop से उनके संदर्भ को कैसे पुनः प्राप्त किया जाए।
मायोच

1
उत्तर 3 सबसे अच्छा समाधान है। मेरे लिए बहुत काम किया। धन्यवाद kaze, एलेक्स !!
अमित बंसोड

अतिरिक्त टिप यदि आप एक लूप में संवाद प्रदर्शित कर रहे हैं, तो सुनिश्चित करें कि गतिविधि समाप्त होने के बाद लूप से बाहर निकले
Thecarisma

404

इसका समाधान यह है कि बाहर निकलने से पहले आपके द्वारा बनाए गए कॉल dismiss()पर , उदाहरण के लिए । सभी एस एंड एस को छोड़ने से पहले बंद कर दिया जाना चाहिए ।DialogviewP.java:183ActivityonPause()WindowDialogActivity


3
तो जब उपयोगकर्ता फोन घुमाता है, तो सभी संवादों को खारिज कर दिया जाना चाहिए ?? यह सही नहीं लगता।
लार्स

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

108

यदि आप उपयोग कर रहे हैं AsyncTask, तो शायद वह लॉग संदेश भ्रामक हो सकता है। यदि आप अपने लॉग में देखते हैं, तो आपको एक और त्रुटि मिल सकती है, शायद आपकी doInBackground()पद्धति में एक है AsyncTask, जो आपके करंट Activityको उड़ा रही है, और इस तरह एक बार AsyncTaskवापस आने पर .. ठीक है, आप बाकी को जानते हैं। कुछ अन्य उपयोगकर्ताओं ने पहले ही समझाया कि यहाँ :-)


22
कभी-कभी उस मामले में मैं वास्तविक अपवाद नहीं देख पा रहा हूं। असली अपवाद को खोजने के लिए बस प्रगति पर टिप्पणी करें ।Dialog.show () और फिर से ऐप चलाएं .. अब आप इसे देखें।
अटक गया

हैलो यारो! जैसा कि ऊपर उल्लेख किया गया है @Stuck मैं वास्तविक अपवाद को भी नहीं देख पा रहा हूँ, मैंने क्या किया? मैंने इसे ब्रेकिंग पॉइंट्स का उपयोग करके ट्रैक किया और मुझे पता चला कि मैं क्लास के तरीके doInBackgroundके अंदर एक एप्लिकेशन क्लास के संदर्भ का उपयोग कर रहा था , AsyncTaskलेकिन इस तरह AndroidManifestसे संपत्ति का उपयोग करके इसे फ़ाइल में घोषित किए बिना :। इसका उपयोग करते समय एक अच्छा अभ्यास हमेशा विधि के अंदर अपने अलर्ट को तत्काल याद रखना और उस पर खारिज करना है । android:nameandroid:name="my.package.MyApplicationClass"AsyncTaskonPreExecuteonPostExecute
GFPF

66

मैं गलती से फोन करके इस त्रुटि को शुरू हो रहा hide()बजाय dismiss()एक पर AlertDialog


4
वास्तव में मेरे साथ क्या हुआ। इसके अलावा, कॉलिंग हाईड () और फिर डायलॉग को अशक्त करने के लिए वैध विकल्प नहीं है।
लुकास तूलियो

मैं वास्तव में इसके पीछे के मुद्दे को जानूंगा। लेकिन कॉल खारिज () ने मेरी मदद की!
कारोली

59

आप इस अपवाद को केवल एक सरल / गूंगा गलती से (उदाहरण के लिए) गलती से कॉल करने के finish()बाद प्रदर्शित कर सकते हैं AlertDialog, यदि आप एक स्विच स्टेटमेंट में ब्रेक कॉल स्टेटमेंट याद करते हैं ...

   @Override
   public void onClick(View v) {
    switch (v.getId()) {
        case R.id.new_button:
            openMyAlertDialog();
            break; <-- If you forget this the finish() method below 
                       will be called while the dialog is showing!
        case R.id.exit_button:
            finish();
            break;
        }
    }

finish()विधि बंद हो जाएगा Activity, लेकिन AlertDialogअभी भी प्रदर्शित कर रहा है!

इसलिए जब आप कोड को जानबूझकर घूर रहे हैं, तो खराब थ्रेडिंग मुद्दों या जटिल कोडिंग की तलाश कर रहे हैं और इस तरह, पेड़ों के लिए जंगल की दृष्टि खोना नहीं है। कभी-कभी यह एक साधारण ब्रेक डंप के रूप में सरल और गूंगा जैसा कुछ हो सकता है। :)


कमोबेश मेरा मुद्दा बिल्कुल यही है। डायलॉग के बाद ऑनएयर में कॉल खत्म, खारिज बटन के लिए ऑनक्लिक में नहीं।
jabass

45

इस प्रश्न के उत्तर सभी सही थे, लेकिन वास्तव में समझने के लिए मेरे लिए थोड़ा भ्रमित करना क्यों था। लगभग 2 घंटे खेलने के बाद इस त्रुटि का कारण (मेरे मामले में) ने मुझे मारा:

आप पहले से ही जानते हैं, अन्य उत्तरों को पढ़ने से, कि X has leaked window DecorView@d9e6131[]त्रुटि का मतलब है कि एक संवाद खुला था जब आपका ऐप बंद हो गया था। लेकिन क्यों?

यह हो सकता है, कि आपका ऐप किसी अन्य कारण से क्रैश हो गया जबकि आपका संवाद खुला था

इससे आपके कोड में कुछ बग के कारण आपका ऐप बंद हो जाता है, जिसके कारण संवाद उसी समय खुला रहता है, जब आपका ऐप दूसरी त्रुटि के कारण बंद हो जाता है।

इसलिए, अपने तार्किक को देखें। पहली त्रुटि को हल करें, और फिर दूसरी त्रुटि स्वयं हल हो जाएगीयहां छवि विवरण दर्ज करें

एक त्रुटि दूसरे का कारण बनती है, जो अन्य का कारण बनती है, जैसे डोमिनोस!


2
विश्वास नहीं किया जा सकता है कि यह केवल एक ही है .. या हम वास्तव में प्रोग्रामिंग हाहा में बहुत खराब हैं, मुझे आपका डोमिनोज़ सादृश्य भी पसंद है
user2161301

पहली त्रुटि को हल करें और दूसरी त्रुटि नहीं होगी । इस उपमा ने मेरी मदद की।
itabdullah

यह पूरी तरह से सही नहीं है, फोन रोटेशन जैसे उदाहरण भी "गतिविधि" रोटेशन होने का कारण बन सकते हैं।
श्रीकांत करुमनघाट

36

गतिविधि से बाहर निकलने के बाद डायलॉग दिखाने का प्रयास करने पर यह समस्या उत्पन्न होती है।

मैंने बस निम्नलिखित कोड लिखकर इस समस्या को हल किया है:

@Override
public void onDestroy(){
    super.onDestroy();
    if ( progressDialog!=null && progressDialog.isShowing() ){
        progressDialog.cancel();
    }
}

मूल रूप से, आपने किस क्लास से प्रगति शुरू की है, ऑनडेस्ट्रो विधि को ओवरराइड करें और इस तरह से करें। यह हल किया "गतिविधि लीक हुई खिड़की है" समस्या।


onDestroy कहलाने की गारंटी नहीं है। उस कोड को ऑनपॉज़ या ऑनटॉप में रखने के लिए बेहतर है
अमृता-

19

मैंने हाल ही में इसी मुद्दे का सामना किया।

इस मुद्दे के पीछे कारण यह है कि संवाद के खारिज होने से पहले बंद होने वाली गतिविधि। उपरोक्त होने के विभिन्न कारण हैं। ऊपर के पदों में उल्लिखित भी सही हैं।

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


16

गतिविधि को नष्ट करने पर संवाद को खारिज करें

@Override
protected void onDestroy()
{
    super.onDestroy();
    if (pDialog!=null && pDialog.isShowing()){
        pDialog.dismiss();
    }
}

यदि pDialog शून्य है, तो यह एक त्रुटि फेंक देगा जैसा कि आप अशक्त संवाद की स्थिति को उद्धृत कर रहे हैं
जोनाथन डन

1
नहीं, यह @JonDunn नहीं होगा, क्योंकि जावा दूसरा बूलियन प्रक्रिया नहीं करेगा यदि पहला झूठ है
मटदेव

13

यह मदद कर सकता है।

if (! isFinishing()) {

    dialog.show();

    }

2
सैकड़ों समान उत्तरों के बीच कोई भी नहीं दिखा रहा है कि कैसे जांचना है कि क्या खिड़कियां मौजूद हैं। इसलिए आप मुझे इसे करने का तरीका खोजने में कुछ समय बचाएं। धन्यवाद।
कोलाजग

11

मेरे पास एक ही अस्पष्ट त्रुटि संदेश था और पता नहीं क्यों था। पिछले उत्तरों के सुरागों को देखते हुए, मैंने अपने गैर-जीयूआई कॉल को mDialog.finish () से mDialog.dismiss () होने के लिए बदल दिया और त्रुटियां गायब हो गईं। यह मेरे विजेट के व्यवहार को प्रभावित नहीं कर रहा था, लेकिन यह निराशाजनक था और अच्छी तरह से एक महत्वपूर्ण मेमोरी लीक को चिह्नित कर सकता था।


ध्यान दिया कि मैं खत्म होने से पहले mDialog.hide () कॉल कर रहा था। इसे बदलकर mDialog.dismiss () किया।
mays

11

मुझे अपने वीडियो प्लेयर एप्लिकेशन में ये लॉग मिल रहे थे। वीडियो प्लेयर बंद होने के दौरान ये संदेश फेंके गए थे। दिलचस्प बात यह है कि मुझे ये लॉग एक बार कुछ रैंडम तरीके से मिलते थे। इसके अलावा मेरा आवेदन किसी में शामिल नहीं है progressdialog। अंत में, मैं नीचे दिए गए कार्यान्वयन के साथ इस मुद्दे पर पहुंच गया।

@Override
protected void onPause()
{
    Log.v("MediaVideo", "onPause");
    super.onPause();
    this.mVideoView.pause();
    this.mVideoView.setVisibility(View.GONE);
}

@Override
protected void onDestroy()
{
    Log.v("MediaVideo", "onDestroy");
    super.onDestroy();
}

@Override
protected void onResume()
{
    Log.v("MediaVideo", "onResume");
    super.onResume();
    this.mVideoView.resume();
}

ओवरराइड OnPauseकरने के लिए कॉल के साथ mVideoView.pause()और सेट visibilityकरने के लिए GONE। इस तरह मैं " Activity has leaked window" लॉग त्रुटि समस्या को हल कर सकता हूं ।


मैं भी एक ही समस्या का सामना कर रहा हूँ। मैंने अपने कोड में अपनी इन पंक्तियों को अपने कोड में जोड़ा, लेकिन यह काम नहीं किया और "android.view.WindowLeaked जो मूल रूप से जोड़ा गया था" त्रुटि देता है और वीडियो भी नहीं
चलाता है

10

मुझे एक ही समस्या हो रही थी और इस पृष्ठ को मिला, और जब मेरी स्थिति अलग थी तब मुझे अलर्ट बॉक्स परिभाषित करने से पहले finishएक ifब्लॉक से बुलाया गया था ।

इसलिए, बस कॉल dismissकरने से काम नहीं चलेगा (जैसा कि इसे अभी तक नहीं बनाया गया है) लेकिन एलेक्स वोलोवॉय के जवाब को पढ़ने और महसूस करने के बाद यह अलर्ट बॉक्स था। मैंने उस ifब्लॉक के अंदर खत्म होने के ठीक बाद रिटर्न स्टेटमेंट जोड़ने की कोशिश की और इस मुद्दे को तय किया।

मैंने सोचा था कि एक बार जब आप खत्म कहते हैं तो यह सब कुछ बंद कर देता है और वहीं समाप्त हो जाता है, लेकिन ऐसा नहीं है। ऐसा लगता है कि यह तब के कोड के ब्लॉक के अंत में जा रहा है।

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

private picked(File aDirectory){
     if(aDirectory.length()==0){
        setResult(RESULT_CANCELED, new Intent()); 
        finish(); 
        return;
    }
     AlertDialog.Builder alert= new AlertDialog.Builder(this); // Start dialog builder
     alert
        .setTitle("Question")
        .setMessage("Do you want to open that file?"+aDirectory.getName());
    alert
        .setPositiveButton("OK", okButtonListener)
        .setNegativeButton("Cancel", cancelButtonListener);
    alert.show();
}

यदि आप मेरे द्वारा समाप्त होने के बाद रिटर्न को सही तरीके से नहीं रखते हैं, तो यह ऐसा कार्य करेगा जैसे आपने इसे कॉल किया है alert.show();और इसलिए यह कहेंगे कि आपके द्वारा डायलॉग प्रस्तुत करने के बाद भी विंडो को फ़िनिश करके लीक किया गया है, हालांकि मामला नहीं है, यह अभी भी लगता है कि यह है।

मैंने सोचा कि मैं इसे यहां जोड़ दूंगा क्योंकि इससे पता चलता है कि फिनिश कमांड ने अलग तरह से काम किया है, फिर मैंने सोचा कि मैंने ऐसा किया है और मुझे लगता है कि अन्य लोग भी हैं जो मुझे लगता है कि इससे पहले कि मैं यह पता चला था।


7

यह सवाल का जवाब नहीं है, लेकिन यह विषय के लिए प्रासंगिक है।

यदि गतिविधि ने मेनिफेस्ट में एक विशेषता को परिभाषित किया है

 android:noHistory="true"

फिर ऑनपॉज़ () निष्पादित करने के बाद, गतिविधि का संदर्भ खो जाता है। इसलिए इस संदर्भ का उपयोग करने वाले सभी दृश्य इस त्रुटि को दे सकते हैं।


आप कुछ भी करने के लिए इसी तरह के संबंधित कर सकते हैं progessdialog.show().. और progressdialog.hide()में asynctaskएक ही गतिविधि के बजाय onPause()से activity?? मेरी समस्या पर एक नज़र है ... stackoverflow.com/questions/39332880/…
Bhuro

1
मेरे लिए पूरी तरह से काम कर रहा है: android: noHistory = "true"
Rana

6

न केवल एक अलर्ट दिखाने की कोशिश करें बल्कि यह तब भी लागू किया जा सकता है जब आप किसी विशेष गतिविधि को पूरा करते हैं और नई गतिविधि / सेवा शुरू करने का प्रयास करते हैं या इसे रोकने की कोशिश करते हैं।

उदाहरण:

OldActivity instance;

    oncreate() {
       instance=this;
    }
    instance.finish();
    instance.startActivity(new Intent(ACTION_MAIN).setClass(instance, NewActivity.class));

6

सामान्यतया यह समस्या प्रगति संवाद के कारण होती है: आप अपनी गतिविधि में निम्न में से किसी एक विधि का उपयोग करके इसे हल कर सकते हैं:

 // 1):
          @Override
                protected void onPause() {
                    super.onPause();
                    if ( yourProgressDialog!=null && yourProgressDialog.isShowing() )
                  {
                        yourProgressDialog.cancel();
                    }
                }

       // 2) :
         @Override
            protected void onDestroy() {
                super.onDestroy();
                if ( yourProgressDialog!=null && yourProgressDialog.isShowing()
               {
                    yourProgressDialog.cancel();
                }
            }

5

समस्या थी जहाँ मैंने एक गतिविधि समाप्त की जब एक ProgressDialog अभी भी दिखाया गया था।

इसलिए पहले डायलॉग छिपाएं और फिर एक्टिविटी खत्म करें।


5

इस कोड को आज़माएं:

public class Sample extends Activity(){
@Override
 public void onCreate(Bundle instance){

}
 @Override
    public void onStop() {
        super.onStop();
      progressdialog.dismiss(); // try this
    }

}

progressdialog.dismiss();यह NullPointerException बना सकता है।
tpk

5

यह तब हो सकता है जब आपको doInBackground()फ़ंक्शन में कोई त्रुटि हो और यह कोड हो।

आखिर में डायलॉग जोड़ने की कोशिश करें। पहले चेक और doInBackground()फ़ंक्शन ठीक करें

protected void onPreExecute() {
     super.onPreExecute();
     pDialog = new ProgressDialog(CreateAccount.this);
     pDialog.setMessage("Creating Product..");
     pDialog.setIndeterminate(false);
     pDialog.setCancelable(true);
     pDialog.show();

 }

 protected String doInBackground(String...args) {
     ERROR CAN BE IS HERE
 }

 protected void onPostExecute(String file_url) {
     // dismiss the dialog once done
     pDialog.dismiss();

5

यह जब मैं उपयोग कर रहा हूँ मुझे क्या हुआ ProgressDialogमें AsyncTask। वास्तव में मैं hide()विधि का उपयोग कर रहा हूँ onPostExecute। @Alex Volovoy के उत्तर के आधार पर मुझे इसे onPostExecute और इसके किए जाने के dismiss()साथ उपयोग करने की आवश्यकता ProgressDialogहै।

progressDialog.hide(); // Don't use it, it gives error

progressDialog.dismiss(); // Use it

यह वास्तव में पूर्ण उत्तर नहीं है। एक संवाद को लीक करने के दो तरीके हैं। 1) यदि आपके पास एक है AsyncTaskऔर आप दिखाते हैं Dialog, तो कुछ ऐसा होता है जो Activityकॉल करता है onPause()(हो सकता है कि आपके AsyncTask में ही कुछ तर्क, एक श्रोता की तरह, तो यह लीक हो जाएगा। 2) जैसा कि ऊपर उल्लेख किया गया है, Dialogजो उस के साथ बनाया गया था Activity Contextवह कभी नहीं है। खारिज कर दिया और आगे Activityबढ़ गया।
ट्रिकोलॉजी

5

" Activity has leaked window that was originally added..." त्रुटि तब होती है जब आप Activityप्रभावी रूप से चेतावनी दिखाने के बाद कोशिश करते हैं finished

आपके पास दो विकल्प हैं AFAIK:

  1. अपने अलर्ट के लॉगिन को रीथिंक करें: dismiss()पर कॉल करेंdialog वास्तव में अपनी गतिविधि बाहर निकलने से पहले।
  2. dialogएक अलग धागे में रखो और उस पर इसे चलाएं thread(वर्तमान से स्वतंत्र activity)।

5

यहाँ एक समाधान है जब आप AlertDialog को खारिज करना चाहते हैं, लेकिन एक संदर्भ नहीं रखना चाहते हैं गतिविधि के अंदर इसका ।

समाधान के लिए आपके पास androidx.lifecycle होना आवश्यक है अपनी परियोजना में निर्भरता की (मुझे विश्वास है कि यह एक सामान्य आवश्यकता है टिप्पणी के क्षण में)

यह आपको बाहरी ऑब्जेक्ट (पर्यवेक्षक) के लिए संवाद को खारिज करने की अनुमति देता है, और आपको इसकी देखभाल करने की आवश्यकता नहीं है, क्योंकि जब गतिविधि मर जाती है तो यह ऑटो-सदस्यता समाप्त हो जाती है। (यहाँ प्रमाण है: https://github.com/googlecodelabs/android-lifecycles/issues/5 )।

इसलिए, पर्यवेक्षक संवाद का संदर्भ रखता है, और गतिविधि पर्यवेक्षक का संदर्भ रखती है। जब "ऑनपॉज" होता है - पर्यवेक्षक संवाद को खारिज कर देता है, और जब "ऑनडेस्ट्रो" होता है - गतिविधि पर्यवेक्षक को हटा देती है, इसलिए कोई रिसाव नहीं होता है (ठीक है, कम से कम मुझे लॉगकैट में त्रुटि नहीं दिखती है)

// observer
class DialogDismissLifecycleObserver( private var dialog: AlertDialog? ) : LifecycleObserver {
    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    fun onPause() {
        dialog?.dismiss()
        dialog = null
    }
}
// activity code
private fun showDialog() {
        if( isDestroyed || isFinishing ) return
        val dialog = AlertDialog
            .Builder(this, R.style.DialogTheme)
            // dialog setup skipped
            .create()
        lifecycle.addObserver( DialogDismissLifecycleObserver( dialog ) )
        dialog.show()
}

4

विंडो लीक अपवादों के दो कारण हैं:

1) जब गतिविधि प्रसंग मौजूद नहीं है तब संवाद दिखाना, इसे हल करने के लिए आपको संवाद दिखाना चाहिए केवल आप सुनिश्चित हैं कि गतिविधि मौजूद है:

if(getActivity()!= null && !getActivity().isFinishing()){
        Dialog.show();
}

2) इस कोड का उपयोग करने के लिए संवाद को उचित रूप से खारिज न करें:

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

4

आपको विधि Progressdialogमें वस्तु बनाना onPreExecuteहै AsyncTaskऔर आपको dismissइसे onPostExecuteविधि पर रखना चाहिए ।


4

बेस्ट सॉल्यूशन अपवाद होने पर डायल कैच और डिसकस डायल में डायलॉग जोड़ना है

बस नीचे दिए गए कोड का उपयोग करें

 try {
        dialog.show();
    } catch (Exception e) {
        dialog.dismiss();
    }

3
क्या संवाद समाप्त होने के बाद अशक्त नहीं होगा?, मुझे लगता है कि dialog.dismiss()त्रुटि भी उत्पन्न होगी
आशु कुमार

3

मेरे मामले में, कारण यह था कि मैं एंड्रॉइड मैनिफ़ेस्ट फ़ाइल में अनुमति शामिल करना भूल गया था।

मुझे कैसे पता चला? ठीक है, जैसे @Bobby स्वीकृत उत्तर के नीचे एक टिप्पणी में कहता है, बस अपने लॉग तक आगे स्क्रॉल करें और आपको पहला कारण या घटना दिखाई देगी जिसने वास्तव में अपवाद को फेंक दिया था। जाहिरा तौर पर, संदेश "गतिविधि लीक हुई खिड़की है जिसे मूल रूप से जोड़ा गया था" केवल एक अपवाद है जो पहले अपवाद के परिणामस्वरूप होता है।


3

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

try {
        if (null != progressDialog && progressDialog.isShowing()) {
            progressDialog.dismiss();
            progressDialog = null;
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

2

सबसे अच्छा समाधान यह दिखाने से पहले रखा जाता है progressbarयाprogressDialog

if (getApplicationContext().getWindow().getDecorView().isShown()) {

  //Show Your Progress Dialog

}

यह मेरे लिए काम नहीं करता है। HTTP कॉल से प्रतिक्रिया के बाद मेरे पास Dialog.show () है और इस बीच मैं स्क्रीन को घुमाता हूं गतिविधि अलग हो गई है, लेकिन ऐसा लगता है कि डायलॉग.शो () से पहले isShown == सही है और फिर डायलॉग इस चेक के बावजूद क्रैश हो जाता है
मिचेल जाइब्रो

1

बस यह सुनिश्चित कर लें कि आपके कोड में कुछ अपवादों के कारण आपकी गतिविधि अप्रत्याशित रूप से बंद नहीं हो रही है। आम तौर पर यह async कार्य में होता है जब गतिविधि doinBackground विधि में बल बंद का सामना करती है और फिर asynctask ऑनपॉस्टसेक्यूट विधि पर वापस लौटती है।


1

मेरे पास इसके लिए एक और उपाय है, और यह जानना चाहूंगा कि क्या यह आपके लिए मान्य है: onDestroy को खारिज करने के बजाय, जो कि प्रमुख समाधान लगता है, मैं ProgressDialog का विस्तार कर रहा हूं ...

public class MyProgressDialog extends ProgressDialog {

  private boolean isDismissed;

  public MyProgressDialog(Context context) {
    super(context);
  }

  @Override
  public void onDetachedFromWindow() {
    super.onDetachedFromWindow();
    dismiss();
  }

  @Override
  public void dismiss() {
    if (isDismissed) {
      return;
    }
    try {
      super.dismiss();
    } catch (IllegalArgumentException e) {
      // ignore
    }
    isDismissed = true;
  }

यह बेहतर है, AFAIC, क्योंकि आपको प्रगति संवाद को एक सदस्य के रूप में रखने की ज़रूरत नहीं है, बस आग (शो) और भूल जाओ

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.