Что это за ошибка ... Я не нашел обсуждения этой ошибки в сообществе 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)
Ответы:
Скорее всего, это происходит из-за того, что вы пытаетесь показать диалог после выполнения фонового потока, когда Activity уничтожается.
Время от времени я получал сообщения об этой ошибке из некоторых моих приложений, когда действие, вызывающее диалог, по той или иной причине заканчивалось, когда оно пыталось показать диалог. Вот что для меня решило:
if(!((Activity) context).isFinishing()) { //show dialog }
Я уже несколько лет использую это, чтобы обойти проблему в старых версиях Android, и с тех пор не видел сбоев.
источник
Я столкнулся с той же проблемой и использовал код, предложенный DiscDev выше, с небольшими изменениями следующим образом:
if (!MainActivity.this.isFinishing()){ alertDialog.show(); }
источник
если диалог вызывает эту проблему из-за потока, вы должны запустить его в потоке пользовательского интерфейса следующим образом: -
runOnUiThread(new Runnable() { @Override public void run() { dialog.show(); } });
источник
Эта ошибка возникает, когда вы показываете диалог для контекста, который больше не существует.
Перед вызовом
.show()
убедитесь, что действие / контекст не завершаютсяif (!(context instanceof Activity && ((Activity) context).isFinishing())) { alert.show(); }
источник
Я столкнулся с этой ошибкой, когда
countDownTimer
в моем приложении был. У него был метод, вызывающий GameOver в моем приложении какpublic void onFinish() { GameOver(); }
но на самом деле игра могла быть закончена раньше, чем время истекло из-за неправильного щелчка пользователя (это была игра с щелчком). Поэтому, когда я смотрел на диалог Game Over, например, через 20 секунд, я забыл отменить его,
countDownTimer
поэтому, когда время истекло, диалог появился снова. Или по какой-то причине произошел сбой с указанной выше ошибкой.источник
Исправить это довольно просто. Перед отображением диалогового окна просто проверьте, проходит ли действие завершающую фазу:
private Handler myHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case DISPLAY_DLG: if (!isFinishing()) { showDialog(MY_DIALOG); } break; } } };
подробнее здесь
источник
В моем случае проблема заключалась в том, что
Context
он хранился как слабая ссылка в расширяемом классеHandler
. Затем я передавалMessenger
обработчик через объектIntent
aService
. Я делал это каждый раз, когда действие появлялось на экране вonResume()
методе.Итак, как вы понимаете, Messenger был сериализован вместе со своими полями (включая контекст), потому что это единственный способ передавать объекты, используя
Intent
- для их сериализации. В тот момент, когда Messenger был передан в службу, само действие еще не было готово для отображения диалогов, поскольку оно находится в другом состоянии (как говорится, onResume (), что абсолютно отличается от того, когда действие уже отображается на экране). Итак, когда мессенджер был десериализован, контекст все еще находился в состоянии возобновления, в то время как действие фактически уже было на экране. Более того, десериализация выделяет память для нового объекта, который полностью отличается от исходного.Решение состоит в том, чтобы просто привязываться к службе каждый раз, когда она вам нужна, и возвращать привязку, у которой есть такой метод, как «setMessenger (Messenger messenger)», и вызывать его, когда вы привязаны к службе.
источник
Я решаю эту проблему, используя
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>(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 } } } } }
источник
как насчет создания нового экземпляра этого диалогового окна, которое вы хотите вызвать? На самом деле я только что столкнулся с той же проблемой, и я этим занимаюсь. так, а не:
if(!((Activity) context).isFinishing()) { //show dialog }
как насчет этого?
YourDialog mDialog = new YourDialog(); mDialog1.show(((AppCompatActivity) mContext).getSupportFragmentManager(), "OrderbookDialog"); }
так что вместо того, чтобы просто проверять, безопасно или нет показывать диалог, я думаю, будет намного безопаснее, если мы просто создадим новый экземпляр, чтобы показать диалог.
Как и я, в моем случае я попытался создать один экземпляр (из фрагмента onCreate ) и вызвать экземпляр этого диалога в другом содержимом адаптера, и это приведет к ошибке «выполняется ли ваша активность» . Я думал, что это потому, что я просто создаю один экземпляр (из onCreate), а затем он уничтожается, поэтому, когда я попытался вызвать его из другого адаптера, я вызвал диалог из старого экземпляра.
Я не уверен, подходит ли мое решение для памяти или нет, потому что я не пробовал его профилировать, но оно работает (ну, конечно, это безопасно, если вы не создаете слишком много экземпляров)
источник
В Котлине
if (!(context is Activity && context.isFinishing)) { pausingDialog!!.show() }
источник