针对此问题本文主要是抛出解决方案,定义一个基类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();
}
}
}
重现此错误我的方法是打开设置,找到开发者选项下的不保留活动的选项,选择打开,截图如下:
测试代码为:
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,如果大家测试有问题欢迎提出,欢迎提出更好的解决方案^_^