放牧代码和思想
专注自然语言处理、机器学习算法
    愛しさ 優しさ すべて投げ出してもいい

Solution of java.lang.IllegalArgumentException: View not attached to window manager

项目里的ProgressDialog导致了这么一个IllegalArgumentException异常,原因是在延时线程里调用了ProgressDialog.dismiss,但此时主Activity已经destroy了。于是应用崩溃,我写了一个 SafeProgressDialog 来避免这个问题,主要原理是覆写dismiss方法,在ProgressDialog.dismiss之前判断Activity是否存在。

在看源码之前先看看异常:

12-10 07:33:36.193    3335-3335/com.example.LoadingProgressDialogTest E/AndroidRuntime﹕ FATAL EXCEPTION: main
    java.lang.IllegalArgumentException: View not attached to window manager
            at android.view.WindowManagerGlobal.findViewLocked(WindowManagerGlobal.java:383)
            at android.view.WindowManagerGlobal.removeView(WindowManagerGlobal.java:285)
            at android.view.WindowManagerImpl.removeView(WindowManagerImpl.java:79)
            at android.app.Dialog.dismissDialog(Dialog.java:323)
            at android.app.Dialog.dismiss(Dialog.java:306)
            at com.example.LoadingProgressDialogTest.MyActivity$1.run(MyActivity.java:33)
            at android.os.Handler.handleCallback(Handler.java:725)
            at android.os.Handler.dispatchMessage(Handler.java:92)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:5041)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
            at dalvik.system.NativeStart.main(Native Method)

一段fire bug 代码:

public class MyActivity extends Activity
{

    private ProgressDialog mProgressDialog;

    /**
     * Called when the activity is first created.
     */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        // The code below throws a java.lang.IllegalArgumentException: View not attached to window manager
        // Which makes your app crashed
        mProgressDialog = new ProgressDialog(this);
        // But my SafeProgressDialog will solve this issue
//        mProgressDialog = new SafeProgressDialog(this);
        mProgressDialog.show();
        new Handler().postDelayed(new Runnable()
        {
            @Override
            public void run()
            {
                mProgressDialog.dismiss();
            }
        }, 1000);

        finish();
    }
}

我写的SafeProgressDialog ,可以完美地防止IllegalArgumentException:

class SafeProgressDialog extends ProgressDialog
{
    Activity mParentActivity;
    public SafeProgressDialog(Context context)
    {
        super(context);
        mParentActivity = (Activity) context;
    }

    @Override
    public void dismiss()
    {
        if (mParentActivity != null && !mParentActivity.isFinishing())
        {
            super.dismiss();    //调用超类对应方法
        }
    }
}

为了方便测试,你可以直接复制下面这段代码来测试我的代码:

package com.hankcs.LoadingProgressDialogTest;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;

public class MyActivity extends Activity
{

    private ProgressDialog mProgressDialog;

    /**
     * Called when the activity is first created.
     */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        // The code below throws a java.lang.IllegalArgumentException: View not attached to window manager
        // Which makes your app crashed
//        mProgressDialog = new ProgressDialog(this);
        // But my SafeProgressDialog will solve this issue
        mProgressDialog = new SafeProgressDialog(this);
        mProgressDialog.show();
        new Handler().postDelayed(new Runnable()
        {
            @Override
            public void run()
            {
                mProgressDialog.dismiss();
            }
        }, 1000);

        finish();
    }
}

class SafeProgressDialog extends ProgressDialog
{
    Activity mParentActivity;
    public SafeProgressDialog(Context context)
    {
        super(context);
        mParentActivity = (Activity) context;
    }

    @Override
    public void dismiss()
    {
        if (mParentActivity != null && !mParentActivity.isFinishing())
        {
            super.dismiss();    //调用超类对应方法
        }
    }
}

知识共享许可协议 知识共享署名-非商业性使用-相同方式共享码农场 » Solution of java.lang.IllegalArgumentException: View not attached to window manager

评论 欢迎留言

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

我的作品

HanLP自然语言处理包《自然语言处理入门》