Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
&引用;android.view.WindowManager$BadTokenException:无法添加窗口";在builder.show()上_Android_Android Alertdialog - Fatal编程技术网

&引用;android.view.WindowManager$BadTokenException:无法添加窗口";在builder.show()上

&引用;android.view.WindowManager$BadTokenException:无法添加窗口";在builder.show()上,android,android-alertdialog,Android,Android Alertdialog,在我的主活动中,我需要调用一个内部类,在类中的一个方法中,我需要显示警报对话框。取消后,按下OK按钮,转到Google Play进行购买 AlertDialog.Builder builder = new AlertDialog.Builder(classname1.this); builder.setCancelable(true); //if successful builder.setMessage(" "); builder.setInverseBack

在我的主
活动中
,我需要调用一个内部类,在类中的一个方法中,我需要显示
警报对话框
。取消后,按下OK按钮,转到Google Play进行购买

AlertDialog.Builder builder = new AlertDialog.Builder(classname1.this);
    builder.setCancelable(true);

    //if successful
    builder.setMessage(" ");
    builder.setInverseBackgroundForced(true);
    builder.setNeutralButton("Ok",new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton){
            // dialog.dismiss();
                   }
    });
    builder.show();
}
大多数情况下,一切都很正常,但对于少数用户来说,它会在
builder.show()
上崩溃,我可以从崩溃日志中看到
“android.view.WindowManager$BadTokenException:
无法添加窗口”。请建议

AlertDialog.Builder builder = new AlertDialog.Builder(classname1.this);
    builder.setCancelable(true);

    //if successful
    builder.setMessage(" ");
    builder.setInverseBackgroundForced(true);
    builder.setNeutralButton("Ok",new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton){
            // dialog.dismiss();
                   }
    });
    builder.show();
}
我的代码大致如下:

public class classname1 extends Activity{

  public void onCreate(Bundle savedInstanceState) {
    this.requestWindowFeature(Window.FEATURE_NO_TITLE);
    super.onCreate(savedInstanceState);
    setContentView(R.layout.<view>); 

    //call the <className1> class to execute
  }

  private class classNamename2 extends AsyncTask<String, Void, String>{

    protected String doInBackground(String... params) {}

    protected void onPostExecute(String result){
      if(page.contains("error")) 
      {
        AlertDialog.Builder builder = new AlertDialog.Builder(classname1.this);
        builder.setCancelable(true);
        builder.setMessage("");
        builder.setInverseBackgroundForced(true);
        builder.setNeutralButton("Ok",new DialogInterface.OnClickListener() {
          public void onClick(DialogInterface dialog, int whichButton){
            dialog.dismiss();
            if(!<condition>)
            {
              try
              {
                String pl = ""; 

                mHelper.<flow>(<class>.this, SKU, RC_REQUEST, 
                  <listener>, pl);
              }

              catch(Exception e)
              {
                e.printStackTrace();
              }
            }  
          }
        });

        builder.show();
      }
    }
  }
}
AlertDialog.Builder builder = new AlertDialog.Builder(classname1.this);
    builder.setCancelable(true);

    //if successful
    builder.setMessage(" ");
    builder.setInverseBackgroundForced(true);
    builder.setNeutralButton("Ok",new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton){
            // dialog.dismiss();
                   }
    });
    builder.show();
}
  • 首先,如果不重写doInBackground,就不能扩展AsyncTask
  • 其次,尝试从生成器创建AlterDailog,然后调用show()

    AlertDialog.Builder builder = new AlertDialog.Builder(classname1.this);
        builder.setCancelable(true);
    
        //if successful
        builder.setMessage(" ");
        builder.setInverseBackgroundForced(true);
        builder.setNeutralButton("Ok",new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton){
                // dialog.dismiss();
                       }
        });
        builder.show();
    }
    
    private boolean visible=false;
    类chkSubscription扩展了异步任务
    {
    受保护的void onPostExecute(字符串结果)
    {
    AlertDialog.Builder=新建AlertDialog.Builder(MainActivity.this);
    builder.setCancelable(true);
    builder.setMessage(sucObject);
    builder.setInverseBackgroundForced(true);
    setNeutralButton(“确定”,新的DialogInterface.OnClickListener(){
    public void onClick(对话框接口对话框,int whichButton)
    {
    dialog.dismise();
    }
    });
    AlertDialog myAlertDialog=builder.create();
    如果(可见)myAlertDialog.show();
    }
    @凌驾
    受保护的字符串doInBackground(字符串…arg0)
    {
    //TODO自动生成的方法存根
    返回null;
    }
    }
    @凌驾
    受保护的void onResume()
    {
    //TODO自动生成的方法存根
    super.onResume();
    可见=真实;
    }
    @凌驾
    受保护的void onStop()
    {
    可见=假;
    super.onStop();
    }
    
问题:

AlertDialog.Builder builder = new AlertDialog.Builder(classname1.this);
    builder.setCancelable(true);

    //if successful
    builder.setMessage(" ");
    builder.setInverseBackgroundForced(true);
    builder.setNeutralButton("Ok",new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton){
            // dialog.dismiss();
                   }
    });
    builder.show();
}
当应用程序试图从通知用户时,会发生此异常 通过打开对话框来启动后台线程(异步任务)

AlertDialog.Builder builder = new AlertDialog.Builder(classname1.this);
    builder.setCancelable(true);

    //if successful
    builder.setMessage(" ");
    builder.setInverseBackgroundForced(true);
    builder.setNeutralButton("Ok",new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton){
            // dialog.dismiss();
                   }
    });
    builder.show();
}
如果您试图从后台线程修改UI(通常是 从AsyncTask的onPostExecute()开始),如果活动进入 完成阶段,即)显式调用finish(),用户按home键 或者后退按钮或者安卓系统的活动清理,然后你就得到了这个 错误

AlertDialog.Builder builder = new AlertDialog.Builder(classname1.this);
    builder.setCancelable(true);

    //if successful
    builder.setMessage(" ");
    builder.setInverseBackgroundForced(true);
    builder.setNeutralButton("Ok",new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton){
            // dialog.dismiss();
                   }
    });
    builder.show();
}
原因:

AlertDialog.Builder builder = new AlertDialog.Builder(classname1.this);
    builder.setCancelable(true);

    //if successful
    builder.setMessage(" ");
    builder.setInverseBackgroundForced(true);
    builder.setNeutralButton("Ok",new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton){
            // dialog.dismiss();
                   }
    });
    builder.show();
}
出现此异常的原因是,正如异常消息所述, 活动已完成,但您正试图显示一个对话框 已完成活动的上下文。因为这里没有窗户 显示android运行时的对话框引发此异常

AlertDialog.Builder builder = new AlertDialog.Builder(classname1.this);
    builder.setCancelable(true);

    //if successful
    builder.setMessage(" ");
    builder.setInverseBackgroundForced(true);
    builder.setNeutralButton("Ok",new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton){
            // dialog.dismiss();
                   }
    });
    builder.show();
}
解决方案:

AlertDialog.Builder builder = new AlertDialog.Builder(classname1.this);
    builder.setCancelable(true);

    //if successful
    builder.setMessage(" ");
    builder.setInverseBackgroundForced(true);
    builder.setNeutralButton("Ok",new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton){
            // dialog.dismiss();
                   }
    });
    builder.show();
}
使用Android调用的
isFinishing()
方法检查 此活动正在完成:是否显式完成() Android进行的呼叫或活动清理。通过使用这种方法,它是 活动时很容易避免从后台线程打开对话框 正在结束

AlertDialog.Builder builder = new AlertDialog.Builder(classname1.this);
    builder.setCancelable(true);

    //if successful
    builder.setMessage(" ");
    builder.setInverseBackgroundForced(true);
    builder.setNeutralButton("Ok",new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton){
            // dialog.dismiss();
                   }
    });
    builder.show();
}
同时为活动维护一个
弱参考
(而不是强参考 参考,以便在不需要时可以销毁活动)并检查 如果活动未在使用此命令执行任何UI之前完成 活动参考(即显示对话框)

AlertDialog.Builder builder = new AlertDialog.Builder(classname1.this);
    builder.setCancelable(true);

    //if successful
    builder.setMessage(" ");
    builder.setInverseBackgroundForced(true);
    builder.setNeutralButton("Ok",new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton){
            // dialog.dismiss();
                   }
    });
    builder.show();
}
例如

AlertDialog.Builder builder = new AlertDialog.Builder(classname1.this);
    builder.setCancelable(true);

    //if successful
    builder.setMessage(" ");
    builder.setInverseBackgroundForced(true);
    builder.setNeutralButton("Ok",new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton){
            // dialog.dismiss();
                   }
    });
    builder.show();
}
private class chkSubscription extends AsyncTask<String, Void, String>{

  private final WeakReference<login> loginActivityWeakRef;

  public chkSubscription (login loginActivity) {
    super();
    this.loginActivityWeakRef= new WeakReference<login >(loginActivity)
  }

  protected String doInBackground(String... params) {
    //web service call
  }

  protected void onPostExecute(String result) {
    if(page.contains("error")) //when not subscribed
    {
      if (loginActivityWeakRef.get() != null && !loginActivityWeakRef.get().isFinishing()) {
        AlertDialog.Builder builder = new AlertDialog.Builder(login.this);
        builder.setCancelable(true);
        builder.setMessage(sucObject);
        builder.setInverseBackgroundForced(true);

        builder.setNeutralButton("Ok",new DialogInterface.OnClickListener() {
          public void onClick(DialogInterface dialog, int whichButton){
            dialog.dismiss();
          }
        });

        builder.show();
      }
    }
  }
}
私有类chkSubscription扩展了异步任务{
私人最终WeakReference loginActivityWeakRef;
公共chkSubscription(登录登录活动){
超级();
this.loginActivityWeakRef=新的WeakReference(loginActivity)
}
受保护的字符串doInBackground(字符串…参数){
//web服务调用
}
受保护的void onPostExecute(字符串结果){
if(page.contains(“error”)//未订阅时
{
if(loginActivityWeakRef.get()!=null&&!loginActivityWeakRef.get().isFinishing()){
AlertDialog.Builder=新建AlertDialog.Builder(login.this);
builder.setCancelable(true);
builder.setMessage(sucObject);
builder.setInverseBackgroundForced(true);
setNeutralButton(“确定”,新的DialogInterface.OnClickListener(){
public void onClick(对话框接口对话框,int whichButton){
dialog.dismise();
}
});
builder.show();
}
}
}
}
更新:

AlertDialog.Builder builder = new AlertDialog.Builder(classname1.this);
    builder.setCancelable(true);

    //if successful
    builder.setMessage(" ");
    builder.setInverseBackgroundForced(true);
    builder.setNeutralButton("Ok",new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton){
            // dialog.dismiss();
                   }
    });
    builder.show();
}
窗口标记:

AlertDialog.Builder builder = new AlertDialog.Builder(classname1.this);
    builder.setCancelable(true);

    //if successful
    builder.setMessage(" ");
    builder.setInverseBackgroundForced(true);
    builder.setNeutralButton("Ok",new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton){
            // dialog.dismiss();
                   }
    });
    builder.show();
}
顾名思义,窗口令牌是一种特殊类型的绑定令牌 窗口管理器用于唯一标识窗口中的窗口的 系统。窗口令牌对于安全性很重要,因为它们可以 恶意应用程序无法在的窗口顶部绘制 其他应用程序。窗口管理器通过 要求应用程序将其应用程序的窗口令牌作为 添加或删除窗口的每个请求的一部分。如果代币没有 匹配时,窗口管理器拒绝请求并抛出 BadTokenException。如果没有窗口标记,这是必需的 无法执行标识步骤,窗口管理器 无法保护自己免受恶意应用程序的攻击

AlertDialog.Builder builder = new AlertDialog.Builder(classname1.this);
    builder.setCancelable(true);

    //if successful
    builder.setMessage(" ");
    builder.setInverseBackgroundForced(true);
    builder.setNeutralButton("Ok",new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton){
            // dialog.dismiss();
                   }
    });
    builder.show();
}
真实场景:

AlertDialog.Builder builder = new AlertDialog.Builder(classname1.this);
    builder.setCancelable(true);

    //if successful
    builder.setMessage(" ");
    builder.setInverseBackgroundForced(true);
    builder.setNeutralButton("Ok",new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton){
            // dialog.dismiss();
                   }
    });
    builder.show();
}
当应用程序第一次启动时, ActivityManagerService创建一种特殊的窗口标记 称为应用程序窗口令牌,它唯一地标识 应用程序的顶级容器窗口 此令牌同时发送给应用程序和窗口管理器,以及 应用程序每次需要时都向窗口管理器发送令牌 将新窗口添加到屏幕。这确保了安全的交互 在应用程序和窗口管理器之间(通过 无法在其他应用程序上添加窗口),并且 使活动管理器可以轻松地直接向 窗口管理器

AlertDialog.Builder builder = new AlertDialog.Builder(classname1.this);
    builder.setCancelable(true);

    //if successful
    builder.setMessage(" ");
    builder.setInverseBackgroundForced(true);
    builder.setNeutralButton("Ok",new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton){
            // dialog.dismiss();
                   }
    });
    builder.show();
}

我正在
onCreate
中创建对话框,并将其与
show
hide
一起使用。对我来说,根本原因不是解雇onBa