无法添加窗口 - 令牌android.os.BinderProxy无效;你的活动在运行吗?

时间:2012-03-02 07:23:40

标签: android facebook

我尝试通过Facebook API连接到Facebook,我按照这个例子:https://github.com/facebook/facebook-android-sdk/tree/master/examples/simple

一切都还可以,但是当我尝试编辑一些代码时,我的意思是我希望在登录成功后显示对话框发布消息,如下所示:

public void onAuthSucceed() {
        mText.setText("You have logged in! ");   
        //This is the code to call the post message dialog.                     
        mFacebook.dialog(Example.this, "feed",new SampleDialogListener());   
    }

我在logcat中收到此错误:

03-02 13:32:08.629: E/AndroidRuntime(14991): android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@405180f8 is not valid; is your activity running?
03-02 13:32:08.629: E/AndroidRuntime(14991):    at android.view.ViewRoot.setView(ViewRoot.java:532)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at android.view.Window$LocalWindowManager.addView(Window.java:424)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at android.app.Dialog.show(Dialog.java:241)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at com.facebook.android.Facebook.dialog(Facebook.java:780)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at com.facebook.android.Facebook.dialog(Facebook.java:737)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at com.facebook.android.Example$SampleAuthListener.onAuthSucceed(Example.java:113)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at com.facebook.android.SessionEvents.onLoginSuccess(SessionEvents.java:78)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at com.facebook.android.Example$LoginDialogListener.onComplete(Example.java:88)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at com.facebook.android.Facebook$1.onComplete(Facebook.java:320)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at com.facebook.android.FbDialog$FbWebViewClient.shouldOverrideUrlLoading(FbDialog.java:144)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at android.webkit.CallbackProxy.uiOverrideUrlLoading(CallbackProxy.java:218)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at android.webkit.CallbackProxy.handleMessage(CallbackProxy.java:337)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at android.os.Handler.dispatchMessage(Handler.java:99)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at android.os.Looper.loop(Looper.java:130)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at android.app.ActivityThread.main(ActivityThread.java:3687)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at java.lang.reflect.Method.invokeNative(Native Method)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at java.lang.reflect.Method.invoke(Method.java:507)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at dalvik.system.NativeStart.main(Native Method)

有什么想法吗?

12 个答案:

答案 0 :(得分:125)

我看到我的一些应用程序偶尔会报告此错误,这就是为我解决的问题:

if(!((Activity) context).isFinishing())
{
    //show dialog
}

所有其他答案似乎都在做一些奇怪的事情,比如遍历正在运行的活动列表,但这样做更简单,似乎可以解决问题。

答案 1 :(得分:106)

当您显示不再存在的上下文的对话框时,可能会发生这种情况。常见情况 - 如果'show dialog'操作在异步操作之后,并且在该操作期间,原始活动(即对话框的父级)将被销毁。有关描述的详细信息,请参阅此博客文章和评论:

http://dimitar.me/android-displaying-dialogs-from-background-threads/

从上面的堆栈跟踪中,看来facebook库异步地旋转了auth操作,并且你有一个Handler - Callback机制(onConmplete在一个监听器上调用),可以很容易地创建这个场景。

当我在我的应用程序中看到这个报道时,它非常罕见并且与博客文章中的体验相符。活动出了问题/它在AsyncTask工作期间被销毁了。我不知道你的修改每次都会导致这种情况,但是你可能会引用一个Activity作为对话框的上下文,它总是在你的代码执行时被破坏?

此外,虽然我不确定这是否是判断您的活动是否正在运行的最佳方式,但请参阅此答案,了解一种方法:

Check whether activity is active

答案 2 :(得分:4)

一个简单的解决方法是捕获异常:

try {
        alertDialog.show()
    }
catch (WindowManager.BadTokenException e) {
        //use a log message
    }

这不是很优雅,但是当您必须管理异步操作并且不确定要显示对话框时是否活动已经启动时,有时会很容易。

答案 3 :(得分:1)

我遇到了完全相同的问题。调用'(!isFinishing())'可以防止崩溃,但无法显示“警报”消息。

然后我尝试调用函数'静态',其中显示警报。之后,没有发生崩溃,也显示了消息。

例如:

public static void connect_failure() {      
        Log.i(FW_UPD_APP, "Connect failed");

        new AlertDialog.Builder(MyActivity)
        .setTitle("Title")
        .setMessage("Message")
        .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) { 
                  //do nothing
            }
         })
        .setIcon(R.drawable.the_image).show();      
    }

答案 4 :(得分:1)

执行线程后,添加这两行代码,这将解决问题。

Looper.loop();
Looper.myLooper().quit();

答案 5 :(得分:1)

  • 对于我而言,是由于试图在onPostExecute AsyncTask中打开/显示对话框而出现问题

  • 然而,showing dialog或Ui的错误方法在onPostExecute中发生了变化。

  • 为此,我们需要检查活动是否处于活动状态例如: !isFinishing()中,如果活动未完成,则只能显示对话框或用户界面更改。

    @Override
    protected void onPostExecute(String response_str) {
    
       getActivity().runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        if (!((Activity) mContext).isFinishing()) {
                            try {
                                ShowAgilDialog();
                            } catch (WindowManager.BadTokenException e) {
                                Log.e("WindowManagerBad ", e.toString());
                            }
                        }
                    }
                });
    }
    

答案 6 :(得分:1)

无法添加窗口-令牌无效;您的活动正在进行吗?

此崩溃通常是由您的应用尝试使用先前完成的“活动”作为上下文来显示对话框时引起的。例如,如果“活动”触发一个AsyncTask并在完成时尝试显示对话框,但是用户在任务完成之前从“活动”导航返回,则会发生这种情况。

外部资源

Android – Displaying Dialogs From Background Threads

Error : BinderProxy@45d459c0 is not valid; is your activity running?

答案 7 :(得分:0)

对我来说,已通过仅删除DialogHelper.class方法中的<meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script> <div class="btn-group"> <button type="button" class="btn btn-dark dropdown-toggle" data-toggle="dropdown">menu1</button> <ul class="dropdown-menu"> <li><a href="#">a</a></li> <li><a href="#">b</a></li> <li><a href="#">c</a></li> <li><a href="#">d</a></li> <li><a href="#">e</a></li> </ul> </div> <div class="btn-group"> <button type="button" class="btn btn-light dropdown-toggle" data-toggle="dropdown">menu2</button> <ul class="dropdown-menu"> <li><a href="#">1</a></li> <li><a href="#">2</a></li> <li><a href="#">3</a></li> <li><a href="#">4</a></li> <li><a href="#">5</a></li> </ul> </div>属性(可用于创建和隐藏对话框)来解决,因为我在那些方法中具有与static相关的属性

答案 8 :(得分:0)

在dependencyServices下,以上方法均无济于事,我最终如下所示:

CREATE OR REPLACE FUNCTION function_to_be_fixed(filter_date date)                   
RETURNS void as  $$
Begin
  CREATE OR REPLACE VIEW view_to_create.randomname AS
  SELECT * from other_table where date_col <= filter_date
End;
$$ LANGUAGE plpgsql;

我必须使用“双重类”,因为接口不能是静态的。 L-

答案 9 :(得分:0)

另一个开发人员用例:如果在WindowManagergetWindow()onCreate()上调用onStart()onResume(),则BadTokenException为抛出。您将需要等到视图准备好并附加好。

将代码移至onAttachedToWindow()即可解决。它可能不是一个永久性的解决方案,但经过我的测试,它始终有效。

就我而言,当活动可见时,需要增加屏幕亮度。 getWindow().getAttributes().screenBrightness中的行onResume()导致异常。将代码移至onAttachedToWindow()可以正常工作。

答案 10 :(得分:0)

您应该做的是在显示警报之前检查活动是否已完成。为此,在Activity类中定义了isFinishing()方法。

这是您应该做的:

if(!isFinishing())
 {
     alert.show();
 }

答案 11 :(得分:-1)

我通过以下方法解决了这个问题:

@Override
protected void onDestroy() {
    accessTokenTracker.stopTracking();
    super.onDestroy();
}