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




memory-leaks dialog (20)

" Activity has leaked window that was originally added... " त्रुटि होती है जब Activity प्रभावी ढंग से finished होने के बाद आप अलर्ट दिखाने का प्रयास करते हैं।

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

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

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

05-17 18:24:57.069: ERROR/WindowManager(18850): Activity com.mypkg.myP has leaked window [email protected] that was originally added here
05-17 18:24:57.069: ERROR/WindowManager(18850): android.view.WindowLeaked: Activity ccom.mypkg.myP has leaked window [email protected] 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)

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

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

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

उत्तर 1 :

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

उत्तर 2

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

उत्तर 3

अपनी गतिविधि से बाहर निकलने से पहले बनाए गए संवाद उदाहरण पर कॉल खारिज () को कॉल करें, उदाहरण के लिए ऑन पॉज़ () या ऑनस्ट्रोय ()


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

 // 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();
                }
            }

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

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

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

}

एक समस्या थी जहां मैंने एक गतिविधि समाप्त की थी जब एक प्रोग्रेसडिअलॉग अभी भी दिखाया गया था।

तो पहले संवाद को छुपाएं और फिर गतिविधि को खत्म करें।


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

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

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

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

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

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

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

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


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


मुझे अपने वीडियो प्लेयर एप्लिकेशन में ये लॉग मिल रहे थे। वीडियो प्लेयर बंद होने पर ये संदेश फेंक दिए गए थे। दिलचस्प बात यह है कि, मैं इन लॉगों को यादृच्छिक तरीके से कुछ रनों में एक बार प्राप्त करता था। इसके अलावा मेरा आवेदन किसी भी 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() कॉल के साथ ओवरराइड करें और सेट करने की mVideoView.pause() visibility को ओवरराइड करें। इस तरह से मैं " Activity has leaked window " लॉग त्रुटि मुद्दा हल कर सकता है।


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

तो, बस dismiss करना कॉल 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(); बाद बुलाया है। alert.show(); और इसलिए यह कहता है कि संवाद करने के ठीक बाद खिड़की लीक हो जाती है, भले ही यह मामला न हो, फिर भी यह सोचता है कि यह है।

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


मुझे हाल ही में एक ही मुद्दे का सामना करना पड़ा।

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

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


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

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


मैं एक वीडियो प्लेयर के त्रुटि पर एक संवाद का उपयोग कर रहा था, और पागल होने की बजाय (मैंने इन सभी समाधानों का परीक्षण किया है)

मैंने DialogFragment http://developer.android.com/reference/android/app/DialogFragment.html चयन किया है।

आप बिल्डर सृजन को एक आंतरिक DialogFragment क्लास में वापस कर सकते हैं, बस DialogFragment ओवरराइड करें


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


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

   @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 अभी भी प्रदर्शित हो रहा है!

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


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

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

progressDialog.dismiss(); // Use it

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

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

 android:noHistory="true"

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


समाधान Activity से बाहर निकलने से पहले viewP.java:183 में बनाए गए Dialog पर dismiss() को कॉल dismiss() , उदाहरण के लिए viewP.java:183 onPause() । एक Activity छोड़ने से पहले सभी Window एस और Dialog बंद होना चाहिए।


सर्वोत्तम समाधान केवल अपवाद होने पर पकड़ने और संवाद को खारिज करने में संवाद जोड़ता है

बस नीचे कोड का प्रयोग करें

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




dialog