2009-05-21 14 views
22

मैं अपने ऐप में प्रगति संवाद दिखाने के लिए showDialog() और dismissDialog() का उपयोग कर रहा हूं। अभिविन्यास बदलते समय राज्य को बचाने के लिए संवाद का निर्माण करने और show() पर कॉल करने से इसे स्थानांतरित किया गया।एंड्रॉइड - dismissDDialog संवाद को खारिज नहीं करता

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

किसी भी कारण से यह इस तरह से व्यवहार करेगा?

संपादित

इस मुद्दे पर काबू पाने के लिए, मैं एक onDestroy() में removeDialog() ताकि संवाद नहीं बनाई गई है/दो बार और अभिविन्यास परिवर्तन से पहले प्रदर्शित, संवाद हटा दिया जाता है जोड़ने की कोशिश की। लॉग बयान जोड़ने और देखो क्या होता

05-21 12:35:14.064: DEBUG/MyClass(193): *************callingShowDialog 
05-21 12:35:14.064: DEBUG/MyClass(193): *************onCreareDialog 

05-21 12:35:15.385: DEBUG/MyClass(193): *************onSaveInstanceState 
05-21 12:35:15.415: DEBUG/MyClass(193): *************onDestroy 

05-21 12:35:15.585: DEBUG/MyClass(193): *************callingShowDialog 
05-21 12:35:15.585: DEBUG/MyClass(193): *************onCreareDialog 
05-21 12:35:15.715: DEBUG/MyClass(193): *************onCreareDialog 
05-21 12:35:17.214: DEBUG/MyClass(193): *************onSaveInstanceState 
05-21 12:35:17.214: DEBUG/MyClass(193): *************onDestroy 

05-21 12:35:17.275: ERROR/WindowManager(193): android.view.WindowLeaked: Activity com.android.MyClass has leaked window [email protected] that was originally added here 

05-21 12:35:17.395: DEBUG/MyClass(193): *************callingShowDialog 
05-21 12:35:17.395: DEBUG/MyClass(193): *************onCreareDialog 
05-21 12:35:17.475: DEBUG/MyClass(193): *************onCreareDialog 

तो हम यहाँ देख की कोशिश की, शुरू में जब गतिविधि प्रदर्शित किया जाता है, onCreateDialog एक बार और अभिविन्यास बदलने पर कहा जाता है, onSaveInstanceState और OnDestroy कहा जाता है।

लेकिन उसके बाद, क्रिएटडिअलॉग को दो बार बुलाया जाता है (एक बार कॉल करने के लिए कॉल करके जिसे मैं करता हूं, लेकिन दूसरी बार क्यों?) और हर बार जब मैं अभिविन्यास बदलता हूं तो ऐसा होता है।

कोई विचार क्यों ऐसा होता है?

धन्यवाद फिर से

+0

के आधार पर किसी कृपया मुझे इस मुद्दे के साथ मदद कर सकते हैं? मैंने इस मुद्दे के बारे में कई पोस्ट और ब्लॉग देखे हैं लेकिन किसी के पास ऐसा समाधान नहीं है जो काम करता है। – lostInTransit

उत्तर

0

दें कि हर बार जब आप (अपने onCreateDialog के माध्यम से Dialog और फलस्वरूप की) बनाया जाता है उन्मुखीकरण अपने Activity का एक नया उदाहरण बदलने के लिए, बारे में पता होना। आप या तो कन्स्ट्रक्टर में लॉग स्टेटमेंट जोड़कर इसे सत्यापित कर सकते हैं।

हालांकि आपके कोड पर नज़र डाले बिना कहना मुश्किल है, मुझे लगता है कि आप को अपने Activity के पुराने उदाहरण पर कॉल कर रहे हैं।

public class Test extends Activity { 

    private Dialog dialog; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState);  
     setContentView(R.layout.test); 
     Button btn = (Button) findViewById(R.id.testButton); 
     btn.setOnClickListener(new OnClickListener() { 
      public void onClick(View v) { 
       new Timer().schedule(new TimerTask() { 
        @Override public void run() { dialog.dismiss(); } 
       }, 10000); 
       Test.this.showDialog(1); 
      } 
     }); 
    } 

    @Override 
    protected Dialog onCreateDialog(int id) { 
     if(id == 1) { 
      if(dialog == null) { dialog = new Dialog(this); } 
      return dialog; 
     } 
     return super.onCreateDialog(id); 
    } 
} 

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

निम्नलिखित Activity कि बस एक खाली Dialog जब एक बटन क्लिक किए जाने से पता चलता है और एक TimerTask शुरू होता है 10 सेकंड के बाद इसे खारिज करने पर विचार करें : यदि - 10 सेकंड के दौरान - अभिविन्यास बदल जाता है, Dialog कभी बर्खास्त नहीं होता है। क्यों? क्योंकि समय TimerTaskrun, Test और Dialog उदाहरणों बनाया गया है की एक पूरी अलग सेट (उन्मुखीकरण परिवर्तन के दौरान) और TimerTask के dialog उदाहरण वैरिएबल संदर्भ एक Test उदाहरण है कि एक है कि वर्तमान में सक्रिय है से अलग है पर स्क्रीन।

private static Dialog dialog;
+0

धन्यवाद जोसेफ। लेकिन जैसा कि आपने कहा था कि फिक्स वास्तव में एक हैक है! मैं इसके बजाए सेवाओं का उपयोग करने की सोच रहा हूं। जब तक सेवा चल रही है, तब तक मैं संवाद दिखाता हूं। क्या यह इस बारे में जाने का सही तरीका है? – lostInTransit

+0

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

4
:

जाहिर है इस मुद्दे (ज्यादातर आपके आवेदन पर निर्भर करता है), एक त्वरित (? गंदा) उपरोक्त कोड ठीक करने के लिए किया जाएगा जिस तरह से निपटने के लिए कई तरीके बस dialog क्षेत्र static बनाने के लिए कर रहे हैं

मैं हाल ही में इस समस्या में भी भाग गया।मेरे पास वैश्विक गतिविधियों (डीबी कनेक्शन, डेटा की सूचियों आदि) तक पहुंचने के लिए आवश्यक कई गतिविधियों के साथ एक आवेदन है और इसलिए मैं एप्लिकेशन क्लास को ओवरराइड करता हूं। इसके लिए, मुझे एहसास हुआ कि मुझे जो भी चाहिए वह मेरे रननेबल में प्रगति संवाद के नवीनतम उदाहरण का संदर्भ था जिसे मैं संवाद को खारिज करने के लिए उपयोग कर रहा था। यह क्या मैं के साथ आया है और यह शान से फोन reorientations बचता:

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    addPreferencesFromResource(R.xml.preferences); 

    mHandler = new Handler(); 
    mApplication = (MyApplication)getApplication(); 

    mFileStorage = (CheckBoxPreference)getPreferenceScreen().findPreference("fileStorage"); 

    mProgressDialog = new ProgressDialog(this); 

    mProgressDialog.setTitle("Location Update"); 
    mProgressDialog.setMessage("Moving databases to new storage location."); 
    mProgressDialog.setIndeterminate(true); 
    mProgressDialog.setCancelable(false); 
    mProgressDialog.setCanceledOnTouchOutside(false); 

    mApplication.setProgressDialog(mProgressDialog); 
} 

@Override 
protected void onResume() { 
    super.onResume(); 

    mPreferences = PreferenceManager.getDefaultSharedPreferences(this); 
    mPreferences.registerOnSharedPreferenceChangeListener(this); 

    if (sUpdateThread != null && sUpdateThread.isAlive()) { 
     mProgressDialog.show(); 
    } 
} 

@Override 
protected void onPause() { 
    super.onPause(); 

    mPreferences.unregisterOnSharedPreferenceChangeListener(this); 

    if (sUpdateThread != null && sUpdateThread.isAlive()) { 
     mProgressDialog.hide(); 
     mApplication.setProgressDialog(null); 
    } 
} 

.... यादृच्छिक सामान यहाँ ....

private Runnable showProgressRunnable = new Runnable() { 
    public void run() { 
     mProgressDialog.show(); 
    } 
}; 

private Runnable hideProgressRunnable = new Runnable() { 
    public void run() { 
     if (mApplication.getProgressDialog() != null) { 
      mApplication.getProgressDialog().dismiss(); 
     } 
    } 
}; 

मेरे धागा एक mHandler.post (showProgressRunnable) करता है जब जब कार्य समाप्त होता है तो कार्य शुरू होता है और फिर एक mHandler.post (hideProgressRunnable) करता है। चूंकि नवीनतम प्रोग्रेसडिअलॉग का संदर्भ अब एप्लिकेशन क्लास में संग्रहीत है, इसलिए मैं इसे विश्वसनीय रूप से बंद कर सकता हूं क्योंकि अब मैं पुराने ऑब्जेक्ट संदर्भ पर नहीं हूं। भावी पीढ़ी के लिए

लिंक:

मैं showDialog (MyDialogID) कहते हैं और dismissDialog (MyDialogId) handleMessage से बाहर (myMessage): http://developer.android.com/reference/android/app/Application.html

0

मंचों के सभी प्रकार के माध्यम से खोज के बाद, मैं सिर्फ निम्नलिखित किया मेरे हैंडलर से विधि।

इससे पहले कि मैंने अपने ऑनक्रेट() - विधि में showDialog को बुलाया और हैंडल-संदेश में संवाद को खारिज करने का प्रयास किया। इस समस्या को हल क्यों किया, मैं नहीं बता सकता।

6

गतिविधि के ऑनरेट ओवरराइड में एक संवाद दिखाते समय मैंने इसमें भाग लिया है। उस कोड को स्थानांतरित करने का प्रयास करें जो संवाद को ऑनपोस्टक्रेट ओवरराइड में दिखाए जाने का कारण बनता है। यह मेरे लिए काम करता प्रतीत होता है।

+0

मैंने showDialog() पर showDialog() के साथ एक ही समस्या देखी है - हालांकि ऐसा लगता है कि डीबगर के माध्यम से ऐप शुरू करते समय ऐसा ही हुआ था। MovDogog() को MovPreCreate() पर चलाना मेरे लिए नौकरी थी - धन्यवाद! – sstn

+0

ग्रेट सॉल्यूशन, डायलॉग लॉन्च करने के लिए केवल ऑनपोस्टक्रेट का उपयोग करें ... @ ओवरराइड सार्वजनिक शून्य पर पोस्टस्टेट (बंडल सेव किया गया इंस्टेंसस्टेट) { super.onCreate (savedInstanceState); launch_app(); } –

+0

यह एक प्रलेखित एंड्रॉइड बग है: http://code.google.com/p/android/issues/detail?id=24646 –

7

मेरे लिए सबसे अच्छा समाधान dismialDialog (आईडी) का उपयोग करने के बजाय dismialDialog() का उपयोग करना प्रतीत होता है; इस तरह से कम पुन: उपयोग, लेकिन सुरक्षित (कुछ भी नहीं फेंकता है) और अभिविन्यास बदलते समय कोई समस्या नहीं है।

3

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

समाधान dissmissDialog() के बजाय removeDialog को कॉल करना था। ऊपर हैरी द्वारा कई थक्स की सिफारिश की गई है।

13858


समाधान OnCreate के बजाय OnPostCreate का उपयोग कर अपने संवाद बनाने के लिए है:

मैं एक Android बग रिपोर्ट बनाई है। मैंने उस बग रिपोर्ट को जानकारी दी और dialog documentation को बेहतर बनाने की सिफारिश की।

5

मैं इस तरह की एक समस्या पर एक दिन बर्बाद हो गया था, जिसमें डीलॉगॉग को कॉल करते समय संवाद को खारिज नहीं किया जा रहा था। यह मेरी पहली स्क्रीन रोटेशन के बाद हुआ और बाद में कभी काम नहीं किया। मैं बाहरी AsyncTask का उपयोग कर रहा था जिसे स्पष्ट रूप से राज्य के संदर्भ में पारित किया गया था।

अंत में समाधान वास्तव में सरल था .... removeDialog(int)dismissDialog(int) के बजाय।

मैंने जो कुछ भी महसूस किया था, वह हमेशा मुझे साबित कर रहा था कि मैं सही गतिविधि पर खारिज कर रहा था और चीजों को कितनी बार बुलाया गया था, इसकी जांच कर रहा था, लेकिन यह दृश्यों के पीछे कुछ जिगरीपोकरी के कारण हुआ था।

0

मैं एक ही समस्या का प्रयोग कर रहा था। मैं onCreateDialog() कॉलबैक के अंदर AlertDialog और ProgressDialog बना रहा था और उन्हें onCreate() से दिखा रहा था। इन संवादों को सीधे onCreate (onCreateDialog() का उपयोग किए बिना) बनाना और onPause() में उन्हें खारिज करना मेरे लिए काम किया! https://stackoverflow.com/a/5693467/955619

0
private AlertDialog alert11 = null; 
public void gpsDialog(){ 
    if (alert11 == null || !alert11.isShowing()) { 
     AlertDialog.Builder builder1 = new AlertDialog.Builder(MainActivity.this); 
     builder1.setMessage("GPS not On"); 
     builder1.setCancelable(true); 

     builder1.setPositiveButton("Enable GPS", 
      new DialogInterface.OnClickListener() { 
       public void onClick(DialogInterface dialog, int id) { 

        Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); 
        MainActivity.this.startActivity(intent); 
        dialog.dismiss(); 
       } 
      }); 

     builder1.setNegativeButton("Cancel", 
      new DialogInterface.OnClickListener() { 
       public void onClick(DialogInterface dialog, int id) { 
        dialog.dismiss(); 
       } 
      }); 

    alert11 = builder1.create(); 

    alert11.show(); 

    } 

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