title: BadTokenException while showing a Dialog
body: <p>I have an activity on an Android Application that starts a Sync Process with my server. This process consumes a lot of memory and processing and takes some time do be completed.</p>
  
  <p>After the process completes, a AlertDialog is presented to the user, showing if the process was completed Successfully or not.</p>
  
  <p>If I leave the activity foreground, everything always works as expected. But, sometimes, when I leave the application, the background process continues its job, but, when I return to the application, it crash with the following error:</p>
  
  <p><strong>android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@4086ea48 is not valid; is your activity running?</strong></p>
  
  <p>Could this error be caused because the activity was destroyed by the OS? If yes, how could the process (that is running on another thread) continues running? And, how could I handle this scenario, avoid the crash and displaying the dialog to the user, even, if the we confirm that the issue is being caused by the Activities' destruction?</p>
  
  <p>Here is some code...</p>
  
  <pre><code>public class ActSincronizacao extends Activity {
  
      @Override
      protected void onCreate(Bundle savedInstanceState) {
  
          super.onCreate(savedInstanceState);
          setContentView(R.layout.sincronizacao);
  
          //Prepare so starts the process
          [...]
  
          // Defines a Handler that will be called when the process gets finished
          oSocketEngine.addProgressUpdateFinishListener(new ProgressUpdateFinishListener() {
  
              @Override
              public void ProgressUpdateFinishOccurred(final ProgressUpdateFinish evt) {
  
                  //Do some processing that doesn´t envolve UI
                  [...]
  
                  // Process that envolves UI
                  runOnUiThread(new Runnable() {
  
                      public void run() {
  
                          if ((boolean)evt.getArgs().getResult()) {
  
                              //If the process gets Success
                              AlertDialog.Builder builder = new AlertDialog.Builder(ActSincronizacao.this);
                              builder.setIcon(android.R.drawable.ic_dialog_info);
                              builder.setTitle("Informação");
                              builder.setMessage("Sincronização concluida com sucesso.");
  
                              // Defines a button handler
                              builder.setNeutralButton("OK", new OnClickListener() {
  
                                  @Override
                                  public void onClick(DialogInterface dialog, int which) {
  
                                      //Go to another Activity
                                      [...]
  
  
                                  }
                              });
  
                              //Call the Dialog
                              builder.create().show();
  
                          } else {
  
  
                              //If something wrong hapenned
  
                              StringBuilder stb = new StringBuilder();
                              stb.append("Some error ocurrend while running the sync process.");
  
                              if (evt.getArgs().getMessage() != null) {
                                  stb.append("\n\n");
                                  stb.append(evt.getArgs().getMessage());
                              } else {
                                  stb.append("\n\n");
                                  stb.append("Try again...");
                              }
  
                              AlertDialog.Builder builder = new AlertDialog.Builder(ActSincronizacao.this);
                              builder.setIcon(android.R.drawable.ic_dialog_alert);
                              builder.setTitle("Error");
                              builder.setMessage(stb.toString());
                              builder.setNeutralButton("OK", null);
                              builder.create().show();            //&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; Crash is reported here
  
                          }
                      }
                  });
              }
          });
  
          //Starts the process in backgroud (Thread)
          oSocketEngine.StartCommunication(oDeviceConfig);
  
      }
  
  }
  </code></pre>
  
  <p>Here is the full stacktrace logged:</p>
  
  <pre><code>android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@4086ea48 is not valid; is your activity running?
  at android.view.ViewRoot.setView(ViewRoot.java:532)
  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:200)
  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:114)
  at android.view.Window$LocalWindowManager.addView(Window.java:424)
  at android.app.Dialog.show(Dialog.java:241)
  at PortalExecutivoSales.Android.ActSincronizacao$3$1.run(ActSincronizacao.java:138)
  at android.os.Handler.handleCallback(Handler.java:587)
  at android.os.Handler.dispatchMessage(Handler.java:92)
  at android.os.Looper.loop(Looper.java:130)
  at android.app.ActivityThread.main(ActivityThread.java:3687)
  at java.lang.reflect.Method.invokeNative(Native Method)
  at java.lang.reflect.Method.invoke(Method.java:507)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
  at dalvik.system.NativeStart.main(Native Method)
  </code></pre>