&引用;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