Android - dismissDialog does not dismiss the dialog

前端 未结 8 1643
悲哀的现实
悲哀的现实 2020-12-08 01:49

I am using the showDialog() and dismissDialog() to show progress dialogs in my app. Moved from creating the dialog and calling show()

相关标签:
8条回答
  • 2020-12-08 01:51

    Please be aware that every time you change the orientation, a new instance of your Activity (and consequently of your Dialog via onCreateDialog) is created. You can verify this by adding a log statement in either constructor.

    Although difficult to say without having a glance at your code, I'm guessing you're calling dismissDialog on an older instance of your Activity.

    Consider the following Activity that simply shows an empty Dialog when a button is clicked and starts a TimerTask to dismiss it after 10 seconds:

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

    This code has a problem similar to the one you're describing: If - during the 10 seconds - the orientation is changed, the Dialog is never dismissed. Why? Because at the time the TimerTask is run, a whole different set of Test and Dialog instances has been created (during orientation change) and the TimerTask's dialog instance variable references a Test instance that is different from the one that is currently active on the screen.

    Obviously there are several ways to deal with this issue (mostly depending on your application), one quick (dirty?) way to fix the above code would be to simply make the dialog field static:

    private static Dialog dialog;
    0 讨论(0)
  • 2020-12-08 01:56

    After searching through all kinds of forums, i just did the following:

    I call the showDialog(MyDialogID) AND dismissDialog(MyDialogId) out of the handleMessage(myMessage) Method from my Handler.

    Before that i called showDialog in my onCreate()-Method and tried to dismiss the dialog in handle-Message. Why this solved the problem, i cant tell.

    0 讨论(0)
  • 2020-12-08 01:57

    After pressing the home button and navigating to app morelocal (change device language), when I came back to my app, new dialog boxes could not be closed via dismissDialog (I launched the dialog from activity onCreate).

    The solution was to call removeDialog instead of dissmissDialog(). This has been recommended by Harri above, many thx.

    I have created an Android bug report:

    13858


    Solution is to create your dialog using OnPostCreate instead of OnCreate. I added that info to the bug report and recommended to improve the dialog documentation.

    0 讨论(0)
  • 2020-12-08 01:59

    I recently ran into this problem as well. I have an application with many activities all needing to access global objects (db connections, lists of data, etc) and so I overrode the Application class. To that end, I realized all I needed was a reference to the latest instance of the progress dialog in my runnable that I was using to dismiss the dialog. This is what I came up with and it gracefully survives phone 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);
        }
    }
    

    ....random stuff here....

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

    My thread does an mHandler.post(showProgressRunnable) when the task starts and then does an mHandler.post(hideProgressRunnable) when the task finishes. Since the reference to the latest ProgressDialog is now stored in the Application class, I can close it out reliably since I am no longer holding on to an old object reference.

    Link for posterity: http://developer.android.com/reference/android/app/Application.html

    0 讨论(0)
  • 2020-12-08 02:01

    I wasted over a day on a problem like this with dialogs not being dismissed when calling dismissDialog. It occurred after my first screen rotation and never worked afterwards. I had been using an external AsyncTask which was passed a referenced to the state explicitly.

    In the end the solution was really simple.... removeDialog(int) instead of dismissDialog(int).

    I had spent what felt like forever proving to myself I was doing the dismiss on the correct activity and checking the number of times things were called etc, but it was caused by some of the jiggerypokery behind the scenes.

    0 讨论(0)
  • 2020-12-08 02:04

    The best solution for me seems to use removeDialog(id) instead of dismissDialog(); Less re-usage this way, but safer (doesn't throw anything) and no problems when changing orientation.

    0 讨论(0)
提交回复
热议问题