错误的窗口令牌,您无法在创建 Activity 之前或隐藏之后显示对话框

Posted

技术标签:

【中文标题】错误的窗口令牌,您无法在创建 Activity 之前或隐藏之后显示对话框【英文标题】:Bad window token, you cannot show a dialog before an Activity is created or after it's hidden 【发布时间】:2016-04-01 14:16:25 【问题描述】:

我在我的应用程序中使用AppIntro library。

它有 3 张幻灯片。当显示第三张幻灯片时,我想问用户一些事情。为此,我使用material dialogs by afollestad。

我在 AppIntro Activity 中的代码如下所示:

@Override
    public void onNextPressed() 
        if(this.pager.getCurrentItem() == 2) 
            MaterialDialog dialog = new MaterialDialog.Builder(getApplicationContext())
                    .title("QR Code scannen")
                    .content("Möchtest du den QR Code scannen oder selbst eingeben?")
                    .positiveText("eingeben")
                    .negativeText("scannen")
                    .onPositive(new MaterialDialog.SingleButtonCallback() 
                        @Override
                        public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) 
                            Intent intent = new Intent(getApplicationContext(), RegistrationActivity.class);
                            startActivity(intent);
                        
                    )
                    .onNegative(new MaterialDialog.SingleButtonCallback() 
                        @Override
                        public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) 
                            // TODO
                        
                    )
                    .show();
        
     

运行应用程序当我滑到第三张幻灯片时出现以下问题:

com.afollestad.materialdialogs.MaterialDialog$DialogException: 
Bad window token, you cannot show a dialog before an Activity is created or after it's hidden.
at com.afollestad.materialdialogs.MaterialDialog.show(MaterialDialog.java:1328)
at com.afollestad.materialdialogs.MaterialDialog$Builder.show(MaterialDialog.java:1317)
at com.ads.adstimer.fragment.Registration.RegistrationActivity.onNextPressed(RegistrationActivity.java:64)
at com.github.paolorotolo.appintro.AppIntro$2.onClick(AppIntro.java:118)
at android.view.View.performClick(View.java:5204)
at android.view.View$PerformClick.run(View.java:21153)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

我真的不明白这个问题。 因为 AppIntro Activity 已经加载,我希望它在显示特定片段时显示一个对话框。

如何实现在显示特定幻灯片时显示对话框?

【问题讨论】:

检查***.com/a/2899630/2015538 【参考方案1】:
MaterialDialog dialog = new MaterialDialog.Builder(getApplicationContext())

我想你需要在这里传递Activity 实例,而不是应用程序上下文。

【讨论】:

对于未来的读者,只需使用 YourActivityClassName.this 而不是 getApplicationContext() 有什么区别? 保留 UI 上下文的是 Activity(通过 YourActivityClassName.this)。 getApplicationContext() 只保留应用程序的上下文。对话框需要 UI 上下文,因此我们传递 Activity 上下文。 如果你使用适配器然后在你的 bindholder 中调用 materialDialog。我遇到了同样的错误。 那么这个库想要在它的builder中接收Context作为参数是没有意义的。应该是Activity【参考方案2】:

这可以通过确认当前的Activity hasWindowFocus 来解决,因为当您在片段中获取上下文时,而不是确切地说它是哪个Activity,它可能没有windowFocus

if (((Activity) mContext).hasWindowFocus()) 
        mDialog.show();

【讨论】:

谢谢,唯一对我有用的解决方案是这个,但是我们什么时候获得窗口焦点,我的意思是我需要尽快显示该对话框,对吗? @ZulqurnainJutt,在显示/隐藏暂停/恢复当前活动的视图期间,检查当前活动窗口焦点是必要的。是的,您需要在某个时候显示对话框。很高兴我提供了帮助。【参考方案3】:

使用

 MaterialDialog dialog = new MaterialDialog.Builder(YourActivityName.class)

不要使用 getApplicationContext()。

【讨论】:

应该是YourActivityClassName.this,或者只是this,而不是.class【参考方案4】:

如果即使在活动内部也发生此错误,请使用“this”而不是“getApplicationContext()”。

    mProgress = new MaterialDialog.Builder(this)

【讨论】:

【参考方案5】:
public class MainActivity extend Activity

    MaterialDialog dialog;

    protected void onCreate(Bundle savedInstanceState) 

        dialog =  new MaterialDialog.Builder(OrderInfoActivity.this)
                .title("Reject?")
                .content("Are you reject this order?")
                .onPositive(new MaterialDialog.SingleButtonCallback() 
                    @Override
                    public void onClick(MaterialDialog dialog, DialogAction which) 
                        Toast.makeText(OrderInfoActivity.this, "Option1", Toast.LENGTH_SHORT).show();
                        
                )
                .onNeutral(new MaterialDialog.SingleButtonCallback() 
                    @Override
                    public void onClick(MaterialDialog dialog, DialogAction which) 
                        Toast.makeText(OrderInfoActivity.this, "Option 2", Toast.LENGTH_SHORT).show();
                    
                )
                .onNegative(new MaterialDialog.SingleButtonCallback() 
                    @Override
                    public void onClick(MaterialDialog dialog, DialogAction which) 
                        Toast.makeText(OrderInfoActivity.this, "Option 3", Toast.LENGTH_SHORT).show();
                    
                ).build();

        accept.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View view) 

                  dialog.show();
            
        );
    

这是我现在正在使用的,它正在工作

希望对你有帮助:)

【讨论】:

以上是关于错误的窗口令牌,您无法在创建 Activity 之前或隐藏之后显示对话框的主要内容,如果未能解决你的问题,请参考以下文章

对话框抛出“无法添加窗口 - 令牌 null 不适用于应用程序”,getApplication() 作为上下文

为啥我收到错误“无法生成令牌。使用 Nodemailer 时检查您的身份验证选项?

403 错误 - 模态窗口中的 CSRF 令牌

无法获取设备的推送令牌。检查您的 FCM 配置是不是有效

Git push无法正常运行错误“您必须使用个人访问令牌或SSH密钥”

无法验证提供的 CSRF 令牌,因为找不到您的会话