监控报警,Dialog偶现Crash。日志如下:
java.lang.IllegalArgumentException: View=DecorView@9d9a86 not attached to window manager
at android.view.WindowManagerGlobal.findViewLocked(WindowManagerGlobal.java:619)
at android.view.WindowManagerGlobal.removeView(WindowManagerGlobal.java:511)
at android.view.WindowManagerImpl.removeViewImmediate(WindowManagerImpl.java:200)
at android.app.Dialog.dismissDialog(Dialog.java:766)
at android.app.Dialog.dismiss(Dialog.java:746)
对应代码如下:
private void doNetWork() {
showLoading();
//网络请求...
hideLoading();
}
private void showLoading() {
if (loadingDialog == null) {
loadingDialog = new LoadingDialog(this);
}
loadingDialog.show();
}
private void hideLoading() {
if (loadingDialog != null) {
loadingDialog.dismiss();
}
}
初步分析:dialog在diss时发现无可依附window,原因可能为异步网络请求返回时此Activity已经finish。
初步方案是:isShowLoading里有判断window所依赖的View是否为null,加上试试。
/**
* @return Whether the dialog is currently showing.
*/
public boolean isShowing() {
return mDecor == null ? false : mDecor.getVisibility() == View.VISIBLE;
}
private void doNetWork() {
showLoading();
//网络请求ing
hideLoading();
}
//....
private void hideLoading() {
if (loadingDialog != null && loadingDialog.isShowing()) {
loadingDialog.dismiss();
}
}
为了mock还原场景,执行了如下代码,发现依然有“not attached to window manager”的日志报错。
private void doNetWork() {
showLoading();
finish();
//网络请求ing
hideLoading();
}
需要判断当前依附Activity是否存在,最终优化代码如下:
private void hideLoading() {
if (loadingDialog != null && loadingDialog.isShowing() && isValidActivity()) {
loadingDialog.dismiss();
}
}
private boolean isValidActivity() {
if (!isDestroyed() && !isFinishing()) {
return true;
}
return false;
}