在Activity中当执行某些耗时的操作时,放在线程中进行,期间弹出一个progressDialog来提醒用户!
以上为背景!
出现了问题:
当耗时线程在执行且弹出progressDialog的过程中,按Home键,然后去系统设置里面将系统语言改掉!在进入我们的Activity,此时,如果我们直接用的是progressDialog.dismiss()的话,会直接报出java.lang.IllegalArgumentException: View not attached to window manager
原因就是我们换系统语言再进入Activity,原来的Activity被destroy了,然后再重新create了,去执行progressDialog.dismiss()的时候就找不到原来的Activity报出上述错误!
网上查了下资料,说需是要用到Activity里面的onCreateDialog()方法来showDialog(int id)一个对话框
但是最后的结果是
当我们显示对话框后,去设置调整系统语言,在进入Activity,这个对话框会一直存在,不会消失!
需要补充的一点是我们执行removeDialog是在我们的耗时线程里面执行的!
可有人知道其中的原因,求大神引领!Activity Dialog

解决方案 »

  1.   

    Activity的onDestroy里把progressDialog.dismiss()
      

  2.   

    如果不需要显示的话,可以在按HOME键的时候关闭对话框,如果必须显示,可以在onResume的时候再次加载即可
      

  3.   

    可以在onStop里加上dissmissdialog,
    或者流氓点,把home键拦掉。
      

  4.   

    在onDestroy里边onDestroy掉ProgressDialog,然后把Dialog的id号记录到一个静态量中,再打开Activity时判断静态量创建ProgressDialog
      

  5.   

    这样不行,我们在onDestroy中设置将progressDialog.dismiss,然后按照步骤去设置更换系统语言,再进入Activity,这个Dialog没有消失掉,但是如果在onStop里面removeDialog的话会消失掉!具体原因我真不明白!
    需要注意的是我没有直接调用Dialog的dismiss方法,那样很容易引起java.lang.IllegalArgumentException: View not attached to window manager的错误,我用的两个方法时showDialog(int id)和removeDialog(int id)!是否和这一点有关?
      

  6.   

    不行那样的话每次进入Activity每次进行onResume的时候都会跑这段代码,不保险!很容易出问题!
      

  7.   

    拦掉对于功能的实现有影响!暂不考虑!
    在onStop里面却是可以讲Dialog remove掉,但是当耗时线程没有执行完的时候再进入Activity的话,如果不在onResume等生命周期内做操作的话,就不会显示,但是如果要做操作的话,就可能会引起其他的问题!
      

  8.   

    以前修改过类似的bug,建议不要去调整对话框的生命周期,而是给activity加上locale属性,让它在切换语言的时候不onDestory
      

  9.   

    在onDestroy里边onDestroy掉ProgressDialog,然后把Dialog的id号记录到一个静态量中,再打开Activity时判断静态量创建ProgressDialog
    我用的是showDialog(int id)来显示对话框的,id是自己定义的一个int型数字,至于说所的静态变量的做法,我不太明白步骤!所保存的Id是我在showDialog的时候传进来的id吗?
      

  10.   

    在Activity中,定义一个private static int dlgID = -1;
    在showDialog(id)时调用dlgID = id;保存该id;
    在onDestroy函数中这样调用:
    if (dlgID != -1){
       removeDialog(dlgID);
    }
    在onCreate函数中这样调用:
    if (dlgID != -1
    dismiss方法是把对话框隐藏掉;
    removeDialog方法是把对话框取消掉;
      

  11.   


    保存的Id是我在showDialog的时候传进来的id。当你切换语言再打开activity时,其实是系统又重新new 了一个该Activity的实例,所以记录dialog的id的变量要做成静态的。该变量表示activity上面是否显示对话框,显示的哪个对话框(id号区别),该变量为-1时表示activity上面没有要显示的对话框。
      

  12.   

    我将我简化的一个Activity贴上!您看看!下楼。showDialog的id是自己定义的一个final static。,但是在onDestroy的时候执行让Dialog消失的方法并不起作用啊!!!。感谢您的回复,如果有QQ的话能留下交流吗?(额 不方便就不用了)
      

  13.   

    package com.ragentek.dialog;import android.app.Activity;
    import android.app.Dialog;
    import android.app.ProgressDialog;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;public class DialogActivity extends Activity {
        /** Called when the activity is first created. */
    private Button button;
    private final static int TIME_DIALOG = 1;
    private final static String TAG = "DialogActivity" ;
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            Log.d(TAG,"onCreate");
            button = (Button)findViewById(R.id.button1);
            button.setOnClickListener(new OnClickListener() {

    @Override
    public void onClick(View v) {
    // TODO Auto-generated method stub
    showDialog(TIME_DIALOG);
    startThread();
    }
    });
        }
        public  void startThread(){
         Thread timeThread =  new Thread(new Runnable(){ @Override
    public void run() {
    try {
    Thread.sleep(10000);
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    removeDialog(TIME_DIALOG);
    }
        
         });
         timeThread.start();
        }
    @Override
    protected ProgressDialog onCreateDialog(int id) {
    // TODO Auto-generated method stub
    ProgressDialog timeDialog = new ProgressDialog(this);
    timeDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
    timeDialog.setTitle(R.string.scan_title);
    timeDialog.setMessage(getResources().getString(R.string.message));
    timeDialog.setIndeterminate(false);
    timeDialog.setCancelable(true);
    return timeDialog;
    }
    @Override
    protected void onDestroy() {
    // TODO Auto-generated method stub
    Log.d(TAG,"onDestroy");

    super.onDestroy();
    }
    @Override
    protected void onPause() {
    // TODO Auto-generated method stub
    Log.d(TAG,"onPause");
    super.onPause();
    }
    @Override
    protected void onRestart() {
    // TODO Auto-generated method stub
    Log.d(TAG,"onRestart");
    super.onRestart();
    }
    @Override
    protected void onResume() {
    // TODO Auto-generated method stub
    Log.d(TAG,"onResume");
    super.onResume();
    }
    @Override
    protected void onStart() {
    // TODO Auto-generated method stub
    Log.d(TAG,"onStart");
    super.onStart();
    }
    @Override
    protected void onStop() {
    // TODO Auto-generated method stub
     Log.d(TAG,"onStop");
    super.onStop();
    }
        
    }
      

  14.   

    我设置了多语言!
    在Dialog上有文字显示,当改变语言后,Dialog上面的文字也改变了!
      

  15.   

    单步调试时,发现了这个现象,更换语言再打开Activity,onCreateDialog被莫名的调用了。如果想办法此时不让onCreateDialog被调用是否可以解决问题?
      

  16.   

    而且这个问题也不算是个大bug,如果要这么搞的话貌似逻辑更复杂了!
      

  17.   


    在上面的代码DialogActivity中,添加上 @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onRestoreInstanceState(savedInstanceState);

    savedInstanceState.putBundle("android:savedDialogs", null);
    }就能解决问题。
      

  18.   

    这个 额貌似是直接给对话框给取消了,一转屏幕线程没执行完,Dialog也没了呀
      

  19.   


    转屏幕后,判断线程是否执行完了,若没有执行完,就不调用
    savedInstanceState.putBundle("android:savedDialogs", null);