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


143

这是什么错误...我在stackoverflow社区中未找到有关此错误的任何讨论详细:-

10-18 23:53:11.613: ERROR/AndroidRuntime(3197): Uncaught handler: thread main exiting due to uncaught exception
10-18 23:53:11.658: ERROR/AndroidRuntime(3197): android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@45d459c0 is not valid; is your activity running?
10-18 23:53:11.658: ERROR/AndroidRuntime(3197):     at android.view.ViewRoot.setView(ViewRoot.java:468)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197):     at android.view.Window$LocalWindowManager.addView(Window.java:424)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197):     at android.app.Dialog.show(Dialog.java:239)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197):     at com.vishal.contacte.Locationlistener$MyLocationListener.onLocationChanged(Locationlistener.java:86)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197):     at android.location.LocationManager$ListenerTransport._handleMessage(LocationManager.java:179)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197):     at android.location.LocationManager$ListenerTransport.access$000(LocationManager.java:112)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197):     at android.location.LocationManager$ListenerTransport$1.handleMessage(LocationManager.java:128)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197):     at android.os.Handler.dispatchMessage(Handler.java:99)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197):     at android.os.Looper.loop(Looper.java:123)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197):     at android.app.ActivityThread.main(ActivityThread.java:4363)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197):     at java.lang.reflect.Method.invokeNative(Native Method)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197):     at java.lang.reflect.Method.invoke(Method.java:521)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:862)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197):     at dalvik.system.NativeStart.main(Native Method)

检查此链接:Android – [显示来自后台线程的对话框](dimitar.me/android-displaying-dialogs-from-background-threads
Naveen

您的链接与已接受的答案相似,但是更容易解释。谢谢你
LuckyMalaka 2013年


Answers:


343

这很可能发生,因为您试图在执行后台线程后显示对话框,而活动被破坏了。

当调用对话框的活动由于某种原因而结束时,或者由于尝试显示对话框而导致的其他原因时,我偶尔从某些应用程序中报告此错误。这是为我解决的问题:

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

几年来,我一直使用它来解决旧版本Android上的问题,此后再也没有看到崩溃。


1
这实际上可以解决问题!但是即使发生这种情况,有没有办法打开对话框?我不太确定发生这种情况时如何管理对话框。有什么建议?提前致谢!
2015年

@CarlaStabile嗨!我认为发生这种情况时显示对话框的唯一方法是,如果您可以为尚未完成的活动获取有效的上下文,则这取决于您在哪里调用此代码,以及是否可以检索到来自另一项非整理活动的环境。
DiscDev

8
太感谢了!对我来说,当我在显示对话框之前按下“后退”按钮时,会发生崩溃(上面有错误消息)。因此,即使我处于不同的活动中,代码也将继续尝试显示它。但这阻止了崩溃,我轻松地参加了新活动!
Azurespot

1
有许多类似的问题,但没有一个被提出。就个人而言,这是我的情况的唯一正确解决方案。
fillobotto

什么是kotlin版本?isFinishing()是否足够?
Alok Rajasukumaran

12

我遇到了同样的问题,并使用了上面DiscDev提出的代码,并做了如下微小改动:

if (!MainActivity.this.isFinishing()){
    alertDialog.show();
}

我更改是因为(Activity)上下文的意思是MainActivity.this对于我的情况。另外,您对用户个人资料链接的看法是正确的,但我认为您可以在上面找到它。
Hamza Polat'7

4

如果对话框由于线程而引发此问题,则应在UI线程上像这样运行它:

runOnUiThread(new Runnable() {
            @Override
            public void run() {
                dialog.show();

            }
        });

2

当您显示对话框的上下文不再存在时,会发生此错误。

致电之前,.show()请检查活动/上下文是否尚未完成

if (!(context instanceof Activity && ((Activity) context).isFinishing())) {
    alert.show();
}

1

countDownTimer在应用程序中遇到时遇到此错误。它在我的应用中有一个调用GameOver的方法为

public void onFinish() {
     GameOver();
}

但是实际上,由于用户的错误点击(时间是点击游戏),游戏可能在时间到之前就结束了。因此,当我在20秒后查看“游戏结束”对话框时,我忘了取消设置,countDownTimer所以一旦时间到了,对话框就会再次出现。或由于某些原因导致上述错误崩溃。


1

解决方法非常简单。只需在显示对话框之前测试活动是否正在完成其阶段即可:

  private Handler myHandler = new Handler() {
  @Override
  public void handleMessage(Message msg) {
    switch (msg.what) {
      case DISPLAY_DLG:
        if (!isFinishing()) {
        showDialog(MY_DIALOG);
        }
      break;
    }
  }
};

在这里看到更多


1

在我的情况下,问题是Context在extends类中一直作为弱引用Handler。然后,我经过Messenger,将处理程序包装Intent到到Service。每当onResume()方法出现在屏幕上时,我都会这样做。

如您所知,Messenger及其字段(包括上下文)一起进行了序列化,因为这是使用Intent-序列化对象的唯一方法。在Messenger传递给服务的那一刻,活动本身仍未准备好显示对话框,因为它处于另一种状态(即onResume(),与活动已经在屏幕上时绝对不同)。因此,当对Messenger进行反序列化时,上下文仍处于恢复状态,而活动实际上已经在屏幕上了。此外,反序列化为新对象分配内存,这与原始对象完全不同。

解决方案就是每次需要时都绑定到该服务,并返回一个绑定器,该绑定器具有类似于“ setMessenger(Messenger messenger)”的方法,并在您绑定到服务时调用它。


1

我通过使用WeakReference<Activity>上下文来解决此问题。坠机事件再也没有出现。这是Kotlin中的示例代码:

对话框管理器类:

class DialogManager {

        fun showAlertDialog(weakActivity: WeakReference<Activity>) {
            val wActivity = weakActivity.get()
            wActivity?.let {
                val builder = AlertDialog.Builder(wActivity, R.style.MyDialogTheme)
                val inflater = wActivity.layoutInflater
                val dialogView = inflater.inflate(R.layout.alert_dialog_info, null)
                builder.setView(dialogView)

                // Set your dialog properties here. E.g. builder.setTitle("MyTitle")

                builder.create().show()
            }
         }

}

然后显示如下对话框:

 val dialogManager = DialogManager()
 dialogManager.showAlertDialog(WeakReference<Activity>(this@MainActivity))

如果您想防止超级杜珀斯崩溃。代替builder.create().show()使用:

val dialog = builder.create()
safeShow(weakActivity, dialog)

这是safeShow方法:

private fun safeShow(weakActivity: WeakReference<Activity>, dialog: AlertDialog?) {
        val wActivity = weakActivity.get()
        if (null != dialog && null != wActivity) {
            // Api >=17
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
                if (!dialog.isShowing && !(wActivity).isFinishing && !wActivity.isDestroyed) {
                    try {
                        dialog.show()
                    } catch (e: Exception) {
                        //Log exception
                    }
                }
            } else {

                // Api < 17. Unfortunately cannot check for isDestroyed()
                if (!dialog.isShowing && !(wActivity).isFinishing) {
                    try {
                        dialog.show()
                    } catch (e: Exception) {
                        //Log exception
                    }
                }
            }
        }
    }

这是一种用于安全关闭对话框的类似方法:

private fun safeDismissAlertDialog(weakActivity: WeakReference<Activity>, dialog: AlertDialog?) {
        val wActivity = weakActivity.get()
        if (null != dialog && null != wActivity) {
            // Api >=17
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
                if (dialog.isShowing && !wActivity.isFinishing && !wActivity.isDestroyed) {
                    try {
                        dialog.dismiss()
                    } catch (e: Exception) {
                        //Log exception
                    }
                }
            } else {

                // Api < 17. Unfortunately cannot check for isDestroyed()
                if (!dialog.isShowing && !(wActivity).isFinishing) {
                    try {
                        dialog.dismiss()
                    } catch (e: Exception) {
                        //Log exception
                    }
                }
            }
        }
    }

0

如何为要调用的对话框创建一个新实例?实际上,我遇到了同样的问题,这就是我要做的。因此,而不是:

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

这个怎么样?

 YourDialog mDialog = new YourDialog();
 mDialog1.show(((AppCompatActivity) mContext).getSupportFragmentManager(), "OrderbookDialog");
                        }

因此,我认为,如果仅创建一个新实例来显示对话框,则不仅仅是检查是否安全或不显示该对话框,还可以更加安全。

像我一样,就我而言,我试图创建一个实例(从Fragment onCreate)并在adapterList的另一内容中调用这些对话框的实例,这将导致“正在运行您的活动”-error。我以为那是因为我只是从onCreate创建一个实例,然后销毁了它,所以当我尝试从另一个adapterList调用它时,我从旧实例中调用了对话框。

我不确定我的解决方案是否对内存友好,因为我没有尝试对其进行概要分析,但是它可以工作 (当然,如果您不创建太多实例,这是安全的)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.