1. 程式人生 > >Android問題集錦之五十:not attached to window manager

Android問題集錦之五十:not attached to window manager

not attached to window manager有許多場景發生,下面說下Dialog的dismiss引發的崩潰。

場景復現:

1、非同步任務或其他後臺執行緒操作,介面顯示滾動條。
兩個Tab頁快速點選切換,有一定機率出現上述問題引起的崩潰。

java.lang.IllegalArgumentException: View not attached to window manager
    at android.view.WindowManagerImpl.findViewLocked(WindowManagerImpl.java:356)
    at android.view
.WindowManagerImpl.removeView(WindowManagerImpl.java:201) at android.view.Window$LocalWindowManager.removeView(Window.java:400) at android.app.Dialog.dismissDialog(Dialog.java:268) at android.app.Dialog.access$000(Dialog.java:69) at android.app.Dialog$1.run(Dialog.java:103) at android.app
.Dialog.dismiss(Dialog.java:252) at xxx.onPostExecute(xxx$1.java:xxx)

2、有些機型上就是會偶現這個問題,著實讓人頭疼。

解決方案

1、直接try catch,將崩潰阻止

 try {
        if ((this.mDialog != null) && this.mDialog.isShowing()) {
            this.mDialog.dismiss();
        }
    } catch (final IllegalArgumentException e) {
        // Handle or log or ignore
} catch (final Exception e) { // Handle or log or ignore } finally { this.mDialog = null; }

雖然暴力,但只少不崩潰了。
2、判斷建立該Dialog的上下文是否有效,在有效的情況才關閉Dialog。

public void hideProgress() {
    if(mProgressDialog != null) {
        if(mProgressDialog.isShowing()) { //check if dialog is showing.

            //get the Context object that was used to great the dialog
            Context context = ((ContextWrapper)mProgressDialog.getContext()).getBaseContext();

            //if the Context used here was an activity AND it hasn't been finished or destroyed
            //then dismiss it
            if(context instanceof Activity) { 
                if(!((Activity)context).isFinishing() && !((Activity)context).isDestroyed()) 
                    mProgressDialog.dismiss();
            } else //if the Context used wasnt an Activity, then dismiss it too
                mProgressDialog.dismiss();
        }
        mProgressDialog = null;
    }
}

下面簡寫的判斷無效的方法:

private boolean isInvalidContext (){  

    return (isDestroyed() || isFinishing());

    }  

參考