无法添加窗口—— Token android.os。 BinderProxy 无效; 您的活动正在运行吗?

我尝试通过 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)

知道吗?

176061 次浏览

当显示不再存在的上下文的对话框时,可能会出现这种情况。一个常见的情况-如果“显示对话框”操作在异步操作之后,并且在该操作期间原始活动(即对话框的父活动)被销毁。要获得更好的描述,请看这篇博客文章和评论:

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

从上面的堆栈跟踪可以看出,facebook 库异步地剥离了身份验证操作,并且您有一个 Handler-Callback 机制(在侦听器上调用 onComplete) ,它可以轻松地创建这个场景。

当我在我的应用程序中看到这个报道时,它非常罕见,并且与博客文章中的体验相匹配。活动出错/在 AsyncTask 工作期间被销毁。我不知道您的修改如何每次都会导致这种结果,但是也许您正在引用一个 Activity 作为对话框的上下文,而这个对话框总是在代码执行时被销毁?

另外,虽然我不确定这是否是判断你的活动是否正在运行的最好方法,但是看看下面这个答案吧:

检查活动是否处于活动状态

我的一些应用程序偶尔会报告这个错误,以下是我解决这个问题的方法:

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

所有其他的答案似乎都在做一些奇怪的事情,比如迭代正在运行的活动列表,但是这个方法要简单得多,而且似乎很有效。

我面临着完全相同的问题。调用 '(!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();
}

一个简单的解决办法是捕捉异常:

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

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

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

Looper.loop();
Looper.myLooper().quit();
  • 在我的案例中,问题是因为我试图在 onPostExecute AsyncTask 中打开/显示对话框而发生的

  • 然而它的一个错误的方法 showing dialog或 Ui 在 onPostExecute的变化。

  • 为此,我们需要检查活动是在活动 例如: !isFinishing(),如果活动没有完成,那么只能显示我们的对话框或 ui 更改。

    @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());
    }
    }
    }
    });
    }
    

对我来说,只要删除 DialogHelper.class 方法中的 static属性(负责创建和隐藏对话框)就可以解决这个问题,因为我在这些方法中有与 Window相关的属性

在 DependencyServices 下,以上这些都没有帮助到我,我最终做了如下事情:

    class Static_Toast_Android
{
private static Context _context
{
get { return Android.App.Application.Context; }
}
public static void StaticDisplayToast(string message)
{
Toast.MakeText(_context, message, ToastLength.Long).Show();
}
}
public class Toast_Android : IToast
{


public void DisplayToast(string message)
{
Static_Toast_Android.StaticDisplayToast(message);
}
}

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

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

把代码移到 onAttachedToWindow()解决了这个问题。这可能不是一个永久的解决方案,但尽管我可以测试,它总是工作。

在我的例子中,当活动变得可见时,需要增加屏幕的亮度。onResume()中的 getWindow().getAttributes().screenBrightness行导致了一个异常。把代码移到 onAttachedToWindow()成功了。

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

这种崩溃通常是由于您的应用程序试图使用以前完成的 Activity 作为上下文显示对话框造成的。例如,如果某个 Activity 触发一个 AsyncTask,该任务在完成时试图显示一个对话框,但用户在任务完成之前从 Activity 导航回来,就会发生这种情况。

外部资源

Android-从后台线程显示对话框

错误: BinderProxy@45d459c0无效; 您的活动正在运行吗?

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

你应该这样做:

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

我是如何处理是每次解散和做 null的对话框参考之前显示对话框

public static void showProgressDialog(Context context){
if (context==null)return;
//do force null when trigger this method to avoid Unable to add window -- token android.os.BinderProxy is not valid; is your activity running?
if (dialog!=null && dialog.isShowing()){
dialog.dismiss();
dialog=null;
}
dialog=new Dialog(context);


dialog.setCancelable(false);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
dialog.setContentView(ProgressBarLayoutBinding.inflate(LayoutInflater.from(context)).getRoot());
if ((context instanceof AppCompatActivity  &&  !((AppCompatActivity) context).isFinishing()) && !dialog.isShowing()) {
dialog.show();
}
}
if ((context instanceof AppCompatActivity && !((AppCompatActivity) context).isFinishing()) && !dialog.isShowing()) {
dialog.show();
}

试试这个,只有当活动处于活动状态时才会调用对话框,否则就不会调用对话框。