Ошибка: BinderProxy @45d459c0 недействителен; работает ли ваша деятельность?

Что это за ошибка... я не нашел обсуждения этой ошибки в сообществе 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 [email protected] 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)

Ответ 1

Это, скорее всего, происходит потому, что вы пытаетесь показать диалог после выполнения фонового потока, а активность уничтожается.

Я видел, что эта ошибка сообщалась раз в то время из некоторых моих приложений, когда активность, вызывающая диалог, заканчивалась по той или иной причине, когда она пыталась показать диалог. Вот что решило это для меня:

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

Я использую это, чтобы обойти эту проблему в более старых версиях Android уже несколько лет, и с тех пор не видел аварии.

Ответ 3

Я столкнулся с той же проблемой и использовал код, предложенный DiscDev выше, с небольшими изменениями следующим образом:

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

Ответ 4

Я столкнулся с этой ошибкой, когда у меня было countDownTimer в моем приложении. У него был метод, вызывающий GameOver в моем приложении как

public void onFinish() {
     GameOver();
}

но на самом деле игра может закончиться до того, как время закончилось из-за неправильного щелчка пользователя (это была игра с щелчком). Поэтому, когда я смотрел диалоговое окно Game Over, например, 20 секунд, я забыл отменить countDownTimer, поэтому раз время было, диалог снова появился. Или по какой-то причине с ошибкой выше.

Ответ 5

Исправить это довольно просто. Просто проверьте, проходит ли Activity на своей заключительной стадии перед отображением диалога:

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

подробнее здесь

Ответ 6

В моем случае проблема заключалась в том, что Context оставался слабой ссылкой в классе, расширяющем Handler. Затем я передавал Messenger, который оборачивает обработчик, через Intent на Service. Я делал это каждый раз, когда активность появлялась на экране в onResume().

Итак, как вы понимаете, Messenger был сериализован вместе со своими полями (включая контекст), потому что это единственный способ передавать объекты с помощью Intent - их сериализация. В тот момент, когда Messenger был передан в службу, само действие все еще не было готово для отображения диалогов, поскольку оно находится в другом состоянии (как говорится на Resume(), которое абсолютно отличается от того, когда действие уже находится на экране). Поэтому, когда мессенджер был десериализован, контекст все еще находился в состоянии возобновления, в то время как действие фактически уже было на экране. Кроме того, десериализация выделяет память для нового объекта, который полностью отличается от исходного.

Решение состоит в том, чтобы просто связываться со службой каждый раз, когда вам это нужно, и возвращать связыватель, у которого есть метод, такой как 'setMessenger (Messenger messenger)', и вызывать его, когда вы привязаны к службе.

Ответ 7

если диалог вызывает эту проблему из-за потока, вы должны выполнить это в потоке пользовательского интерфейса следующим образом:

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

            }
        });

Ответ 8

Я WeakReference<Activity> эту проблему, используя WeakReference<Activity> в качестве контекста. Крушение никогда не появлялось снова. Вот пример кода в Котлине:

Диалог менеджер класса:

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>([email protected]))

Если вы хотите быть супер-защищенным от сбоев. Вместо 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
                    }
                }
            }
        }
    }

Ответ 9

Эта ошибка возникает, когда вы показываете диалог для контекста, который больше не существует.

Перед вызовом .show() убедитесь, что действие/контекст не заканчивается

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

Ответ 10

В моем случае я забыл прокомментировать finish();

Ответ 11

как насчет создания нового экземпляра этого диалога, который вы хотите вызвать? Я на самом деле только что встретил ту же проблему, и это то, что я делаю. так, а не:

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

как насчет этого?

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

поэтому вместо того, чтобы просто проверять, безопасно или нет показывать диалог, я думаю, что гораздо безопаснее, если мы просто создадим новый экземпляр для показа диалога.

Как и я, в моем случае я попытался создать один экземпляр (из фрагмента onCreate) и вызвать экземпляр этого диалогового окна в другом содержимом адаптера, и это приведет к ошибке "ваша деятельность запущена" - ошибка. Я думал, что это потому, что я просто создаю один экземпляр (из onCreate), а затем он уничтожается, поэтому, когда я пытался вызвать его из другого адаптера, я вызывал диалог из старого экземпляра.

Я не уверен, является ли мое решение дружественным к памяти или нет, потому что я не пытался его профилировать, но оно работает (конечно, безопасно, если вы не создаете слишком много экземпляров)