An error occurs:
android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@19fb3f3e is not valid; is your activity running? at android.view.ViewRootImpl.setView(ViewRootImpl.java:562) at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:282) at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:85) at android.app.Dialog.show(Dialog.java:298) at android.app.Activity.showDialog(Activity.java:3422) at android.app.Activity.showDialog(Activity.java:3371) at com.brokeyourapp.app123.StepGallery6$1.handleMessage(StepGallery6.java:481) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5294) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)
I understand it occurs when you try to create a dialogue when the activity does not exist. And I suspect that the reason is exactly how I call this dialogue.
In the onCreate
method onCreate
there is a Handler, which in a particular case shows a dialog, like this showDialog(IDD_CONGRADS);
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.stepgallery6); h = new Handler(Looper.getMainLooper()) { public void handleMessage(android.os.Message msg) { // обновляем Кнопки switch (msg.what) { case 40: if (Arrays.equals(compArray, compButtonArray)) { // runOnUiThread(new Runnable() { @Override public void run() { showDialog(IDD_CONGRADS); } }); } else { runOnUiThread(new Runnable() { @Override public void run() { showDialog(IDD_NOCONGRADS); } }); } break; case 60: GoAct(1); break; { }
The effect on Handler is like this:
@Override public void onStart() { super.onStart(); Thread t = new Thread(new Runnable() { @Override public void run() { for (int i = 1; i <= 40; i++) { try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } h.sendEmptyMessage(i); }} }); t.start(); }
And the function on call looks like this:
// Вызывает диалог по окончанию @Override protected Dialog onCreateDialog(int id) { switch (id) { case IDD_CONGRADS: //AlertDialog.Builder builder = new AlertDialog.Builder(this); AlertDialog.Builder builder = new AlertDialog.Builder(StepGallery6.this); builder.setMessage(R.string.congrats1) .setCancelable(false) .setPositiveButton(R.string.next, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { GoAct(2); } }) .setNeutralButton(R.string.back_to_menu, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { GoAct(1); } }); return builder.create(); case IDD_NOCONGRADS: AlertDialog.Builder builder2 = new AlertDialog.Builder(StepGallery6.this); builder2.setMessage(R.string.nocongrats) .setCancelable(false) .setPositiveButton(R.string.again, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { GoAct(3); } }) .setNeutralButton(R.string.back_to_menu, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { GoAct(1); } }); return builder2.create(); default: return null; } }
And it seems to me that it is all the salt in it. Some detail is missing. Please tell those who came across.
runOnUiThread(new Runnable() { @Override public void run() { showDialog(IDD_CONGRADS); } });
- Yuriy SPb ♦