java.lang.IllegalArgumentException: View=PhoneWindow$DecorView{...} not attached to window manager

针对此问题本文主要是抛出解决方案,定义一个基类BaseDialog,其他Dialog继承此基类,BaseDialog代码如下:

import android.app.Activity;
import android.app.Dialog;
import android.arch.lifecycle.Lifecycle;
import android.arch.lifecycle.LifecycleObserver;
import android.arch.lifecycle.OnLifecycleEvent;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v4.app.FragmentActivity;

abstract public class BaseDialog extends Dialog implements LifecycleObserver {
    protected Context context;

    public BaseDialog(@NonNull Context context) {
        super(context);
        init(context);
    }

    public BaseDialog(@NonNull Context context, int themeResId) {
        super(context, themeResId);
        init(context);
    }

    private void init(Context context) {
        this.context = context;
        if (context instanceof FragmentActivity) {
            ((FragmentActivity) context).getLifecycle().addObserver(this);
        }
    }

    @Override
    public void dismiss() {
        if (context instanceof Activity) {
            Activity activity = (Activity) context;
            if (!activity.isFinishing()) {
                super.dismiss();
            }
        }
    }

    @Override
    public void show() {
        if (context instanceof Activity) {
            Activity activity = (Activity) context;
            if (!activity.isFinishing()) {
                super.show();
            }
        }
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    public void onDestroy() {
        if (isShowing()) {
            dismiss();
        }
    }
}

重现此错误我的方法是打开设置,找到开发者选项下的不保留活动的选项,选择打开,截图如下:

java.lang.IllegalArgumentException: View=PhoneWindow$DecorView{...} not attached to window manager_第1张图片

测试代码为:

public class DialogTestActivity extends AppCompatActivity {

    private SimpleDialog simpleDialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        simpleDialog=new SimpleDialog(this);
        simpleDialog.show();

        new DialogThread().start();
    }

    private class DialogThread extends Thread{
        @Override
        public void run() {
            SystemClock.sleep(5000);
            simpleDialog.dismiss();
        }
    }
}

SimpleDialog代码为:

public class SimpleDialog extends Dialog {

    public SimpleDialog(@NonNull Context context) {
        super(context);
        setContentView(android.R.layout.simple_list_item_checked);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

}

运行在手机上然后马上按下Home键将应用退出后台,此时重现此错误,打印的错误日志信息全文为:

11-05 10:52:04.407 23911-23911/com.midas.demo E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.midas.demo, PID: 23911
    java.lang.IllegalArgumentException: View=com.android.internal.policy.impl.PhoneWindow$DecorView{41f587f8 V.E..... R.....I. 0,0-640,485} not attached to window manager
        at android.view.WindowManagerGlobal.findViewLocked(WindowManagerGlobal.java:370)
        at android.view.WindowManagerGlobal.removeView(WindowManagerGlobal.java:299)
        at android.view.WindowManagerImpl.removeViewImmediate(WindowManagerImpl.java:84)
        at android.app.Dialog.dismissDialog(Dialog.java:350)
        at android.app.Dialog$1.run(Dialog.java:126)
        at android.os.Handler.handleCallback(Handler.java:733)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:136)
        at android.app.ActivityThread.main(ActivityThread.java:5061)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:812)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:628)
        at dalvik.system.NativeStart.main(Native Method)

从上面的日志可以看出,是当dialog调用dismiss方法的时候引发的。

原因分析大概就是dialog所依附的activity已经销毁,此时再调用dismiss就会发现没有activity依附,所以就抛出此异常。

在查找资料时发现有篇博文https://blog.csdn.net/u012264122/article/details/52002506 提出了解决方法,就是:

1、在页面的destory方法中,判断dialog是否存在,若存在,dismiss就销毁,使dialog的生命周期与activity同步;

2、在一些由于耗时操作或其他操作导致容易出现activity被销毁而dialog未销毁的地方,使用activity.isfinidhing方法判断activity是否被销毁,销毁,则终止代码。

基于此解决方法的实现代码已在此文开始部分就提出,测试方法就是将上面提到的测试Dialog改成继承自定义的BaseDialog,如果大家测试有问题欢迎提出,欢迎提出更好的解决方案^_^

你可能感兴趣的:(android开发问题)