android视图未连接到窗口管理器
我有以下一些例外情况:android视图未连接到窗口管理器,android,exception,Android,Exception,我有以下一些例外情况: java.lang.IllegalArgumentException: View not attached to window manager at android.view.WindowManagerImpl.findViewLocked(WindowManagerImpl.java:355) at android.view.WindowManagerImpl.updateViewLayout(WindowManagerImpl.java:191) at android
java.lang.IllegalArgumentException: View not attached to window manager
at android.view.WindowManagerImpl.findViewLocked(WindowManagerImpl.java:355)
at android.view.WindowManagerImpl.updateViewLayout(WindowManagerImpl.java:191)
at android.view.Window$LocalWindowManager.updateViewLayout(Window.java:428)
at android.app.Dialog.onWindowAttributesChanged(Dialog.java:596)
at android.view.Window.setDefaultWindowFormat(Window.java:1013)
at com.android.internal.policy.impl.PhoneWindow.access$700(PhoneWindow.java:86)
at com.android.internal.policy.impl.PhoneWindow$DecorView.drawableChanged(PhoneWindow.java:1951)
at com.android.internal.policy.impl.PhoneWindow$DecorView.fitSystemWindows(PhoneWindow.java:1889)
at android.view.ViewRoot.performTraversals(ViewRoot.java:727)
at android.view.ViewRoot.handleMessage(ViewRoot.java:1633)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:4338)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
at dalvik.system.NativeStart.main(Native Method)
我在谷歌上搜索了一下,发现它与弹出窗口和打开屏幕有关,但没有提到我的代码
问题是:
希望有帮助 我在该活动的清单中添加了以下内容
android:configChanges="keyboardHidden|orientation|screenLayout"
我遇到了这样一个问题:在屏幕方向发生变化时,活动在AsyncTask完成之前完成,进度对话框也完成了。我似乎通过将对话框设置为null
onPause()
来解决这个问题,然后在取消之前在AsyncTask中检查它
@Override
public void onPause() {
super.onPause();
if ((mDialog != null) && mDialog.isShowing())
mDialog.dismiss();
mDialog = null;
}
。。。在我的任务中:
protected void onPreExecute() {
mDialog = ProgressDialog.show(mContext, "", "Saving changes...",
true);
}
protected void onPostExecute(Object result) {
if ((mDialog != null) && mDialog.isShowing()) {
mDialog.dismiss();
}
}
在清单中声明活动时,需要android:configChanges=“定向” 例如:
<activity android:theme="@android:style/Theme.Light.NoTitleBar" android:configChanges="orientation" android:label="traducción" android:name=".PantallaTraductorAppActivity"></activity>
或者只需添加
protected void onPreExecute() {
mDialog = ProgressDialog.show(mContext, "", "Saving changes...", true, false);
}
这将使
ProgressDialog
无法取消根据windowManager(链接)的代码,当您尝试更新的视图(可能属于对话框,但不是必需的)不再附加到窗口的实际根目录时,会发生这种情况
正如其他人所建议的,在对对话框执行特殊操作之前,应该检查活动的状态
以下是相关代码,这是问题的原因(复制自Android源代码):
public void updateViewLayout(视图、ViewGroup.LayoutParams参数){
如果(!(WindowManager的参数instanceof.LayoutParams)){
抛出新的IllegalArgumentException(“参数必须是WindowManager.LayoutParams”);
}
最终WindowManager.LayoutParams wparams
=(WindowManager.LayoutParams)参数;
view.setLayoutParams(wparams);
已同步(此){
int index=findViewLocked(视图,true);
ViewRootImpl root=mRoots[index];
mParams[索引]=wparams;
setLayoutParams(wparams,false);
}
}
私有int findViewLocked(视图,需要布尔值){
已同步(此){
最终整数计数=mViews!=null?mViews.length:0;
对于(int i=0;i我的问题是通过在我的android上锁定屏幕旋转来解决的。导致我出现问题的应用程序现在可以正常工作了另一个选项是在对话框通过覆盖onAttachedToWindow()连接到窗口之前不启动异步任务在对话框上,这样它总是可以被拒绝的。如果您有一个活动对象挂起,您可以使用isDestroyed()
方法:
Activity activity;
// ...
if (!activity.isDestroyed()) {
// ...
}
如果您有一个非匿名的AsyncTask
子类,可以在不同的地方使用它,这很好。我使用的是一个定制的静态类,它生成-显示和隐藏一个对话框。
这个类也被其他活动使用,而不仅仅是一个活动。
现在,你所描述的问题也出现在我的脑海中,我已经呆了一夜,想找到一个解决办法
最后,我向您介绍解决方案
如果您想显示或关闭对话框,但不知道是哪个活动启动了该对话框以便触摸它,则以下代码适用于您
static class CustomDialog{
public static void initDialog(){
...
//init code
...
}
public static void showDialog(){
...
//init code for show dialog
...
}
/****This is your Dismiss dialog code :D*******/
public static void dismissProgressDialog(Context context) {
//Can't touch other View of other Activiy..
//http://stackoverflow.com/questions/23458162/dismiss-progress-dialog-in-another-activity-android
if ( (progressdialog != null) && progressdialog.isShowing()) {
//is it the same context from the caller ?
Log.w("ProgressDIalog dismiss", "the dialog is from"+progressdialog.getContext());
Class caller_context= context.getClass();
Activity call_Act = (Activity)context;
Class progress_context= progressdialog.getContext().getClass();
Boolean is_act= ( (progressdialog.getContext()) instanceof Activity )?true:false;
Boolean is_ctw= ( (progressdialog.getContext()) instanceof ContextThemeWrapper )?true:false;
if (is_ctw) {
ContextThemeWrapper cthw=(ContextThemeWrapper) progressdialog.getContext();
Boolean is_same_acivity_with_Caller= ((Activity)(cthw).getBaseContext() == call_Act )?true:false;
if (is_same_acivity_with_Caller){
progressdialog.dismiss();
progressdialog = null;
}
else {
Log.e("ProgressDIalog dismiss", "the dialog is NOT from the same context! Can't touch.."+((Activity)(cthw).getBaseContext()).getClass());
progressdialog = null;
}
}
}
}
}
为什么不试试抓,像这样:
protected void onPostExecute(Object result) {
try {
if ((mDialog != null) && mDialog.isShowing()) {
mDialog.dismiss();
}
} catch (Exception ex) {
Log.e(TAG, ex.getMessage(), ex);
}
}
在与这个问题进行斗争之后,我终于找到了以下解决方法:
/**
* Dismiss {@link ProgressDialog} with check for nullability and SDK version
*
* @param dialog instance of {@link ProgressDialog} to dismiss
*/
public void dismissProgressDialog(ProgressDialog dialog) {
if (dialog != null && dialog.isShowing()) {
//get the Context object that was used to great the dialog
Context context = ((ContextWrapper) dialog.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) {
// Api >=17
if (!((Activity) context).isFinishing() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
if (!((Activity) context).isDestroyed()) {
dismissWithExceptionHandling(dialog);
}
} else {
// Api < 17. Unfortunately cannot check for isDestroyed()
dismissWithExceptionHandling(dialog);
}
}
} else
// if the Context used wasn't an Activity, then dismiss it too
dismissWithExceptionHandling(dialog);
}
dialog = null;
}
}
/**
* Dismiss {@link ProgressDialog} with try catch
*
* @param dialog instance of {@link ProgressDialog} to dismiss
*/
public void dismissWithExceptionHandling(ProgressDialog dialog) {
try {
dialog.dismiss();
} catch (final IllegalArgumentException e) {
// Do nothing.
} catch (final Exception e) {
// Do nothing.
} finally {
dialog = null;
}
}
/**
*关闭{@link ProgressDialog},检查是否为空以及SDK版本
*
*要关闭的{@link ProgressDialog}的@param dialog实例
*/
public void dismissProgressDialog(ProgressDialog对话框){
if(dialog!=null&&dialog.isShowing()){
//获取用于创建对话框的上下文对象
上下文=((ContextWrapper)dialog.getContext()).getBaseContext();
//如果此处使用的上下文是一个活动,但尚未完成或销毁
//那就驳回它吧
if(活动的上下文实例){
//Api>=17
if(!((活动)上下文).isFinishing(){
if(Build.VERSION.SDK\u INT>=Build.VERSION\u code.JELLY\u BEAN\u MR1){
if(!((活动)上下文).isDestroyed()){
dismissWithExceptionHandling(对话框);
}
}否则{
//Api<17。很遗憾,无法检查isDestroyed()
/**
* Dismiss {@link ProgressDialog} with check for nullability and SDK version
*
* @param dialog instance of {@link ProgressDialog} to dismiss
*/
public void dismissProgressDialog(ProgressDialog dialog) {
if (dialog != null && dialog.isShowing()) {
//get the Context object that was used to great the dialog
Context context = ((ContextWrapper) dialog.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) {
// Api >=17
if (!((Activity) context).isFinishing() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
if (!((Activity) context).isDestroyed()) {
dismissWithExceptionHandling(dialog);
}
} else {
// Api < 17. Unfortunately cannot check for isDestroyed()
dismissWithExceptionHandling(dialog);
}
}
} else
// if the Context used wasn't an Activity, then dismiss it too
dismissWithExceptionHandling(dialog);
}
dialog = null;
}
}
/**
* Dismiss {@link ProgressDialog} with try catch
*
* @param dialog instance of {@link ProgressDialog} to dismiss
*/
public void dismissWithExceptionHandling(ProgressDialog dialog) {
try {
dialog.dismiss();
} catch (final IllegalArgumentException e) {
// Do nothing.
} catch (final Exception e) {
// Do nothing.
} finally {
dialog = null;
}
}
@Override
protected void onDestroy() {
if (progressDialog != null && progressDialog.isShowing())
progressDialog.dismiss();
super.onDestroy();
}