title: AlertDialog leaks despite using a WeakReference
body: <p>I have a problem with creating AlertDialog inside a Handler, because it causes memory leaks or another errors.</p>
  
  <h3>Details:</h3>
  
  <p>I have an Activity, Thread and Handler with a WeakReference to an activity. 
  Before I start my thread, I create ProgressDialog <code>dialog</code> in my activity class.
  Thread task have a reference to MyHandler object.
  When user dismisses <code>dialog</code> in my activity, the onCancelListener calls thread's interrupt(). My thread finishes safely task and send Message DOWNLOAD_STATE.CANCELLED to main activity thread. Then I cretate AlertDialog with code inside <code>MyHandler</code></p>
  
  <h3>Problem:</h3>
  
  <p>The problem is when the user press a back button immediately after dismissing <code>alert</code> (which cancells thread) and before new <code>AlertDialog</code> has been created (inside MyHandler class). It tooks about second. When user doesn't press back in this time, everything is working.</p>
  
  <p>It leaks here (inside MyHandler class):
   <code>new AlertDialog.Builder(activity).setMessage("update cancelled").setPositiveButton("OK", null).show();</code></p>
  
  <p>The normal thing is when user presses the back button, activity is destroyed (effect of activity onBackKeyPressed), but why handleMessage isn't stopped and creates <code>AlertDialog</code>?</p>
  
  <p><b>My handler class:</b></p>
  
  <pre><code>static class MyHandler extends Handler {
  
      WeakReference&lt;MainActivity&gt; activityRef;
      MyHandler(MainActivity activity)
      {
          this.activityRef=new WeakReference&lt;MainActivity&gt;(activity);
      }
  
      @Override
      public void handleMessage(Message msg) {
  
          MainActivity activity=activityRef.get();
          if(activity==null)
              return;
  
          if (msg.arg1==DownloadTask.DOWNLOAD_STATE.FINISHED.ordinal())
          {
              activity.dialog.dismiss();
              Toast.makeText(activity, "updated", Toast.LENGTH_LONG).show();
          }
  
          else if( msg.arg1== DownloadTask.DOWNLOAD_STATE.CANCELLED.ordinal())
          {
              new AlertDialog.Builder(activity).setMessage("update cancelled").setPositiveButton("OK", null).show();
          }
  
          else if(msg.arg1==DownloadTask.DOWNLOAD_STATE.ERROR.ordinal())
          {
  
                activity.dialog.dismiss();
              new AlertDialog.Builder(activity).setMessage(activity.getString(R.string.no_connection_info)).setPositiveButton("OK", null).show();
          }
  
      }
  }
  </code></pre>
  
  <p><b>Inside thread's runnable: </b></p>
  
  <pre><code>if(Thread.interrupted()) 
          {
              Message msg=handler.obtainMessage();
              msg.arg1=DOWNLOAD_STATE.CANCELLED.ordinal();
              msg.arg2=counter;
              msg.obj=cities.length;
              handler.sendMessage(msg);
  
              return;
          }
  </code></pre>
  
  <p><b>Error stack trace1:</b></p>
  
  <pre><code>android.view.WindowLeaked: Activity com.mycompany.mooz.MainActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@42723848 that was originally added here
          at android.view.ViewRootImpl.&lt;init&gt;(ViewRootImpl.java:403)
          at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:311)
          at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:224)
          at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:149)
          at android.view.Window$LocalWindowManager.addView(Window.java:554)
          at android.app.Dialog.show(Dialog.java:277)
          at android.support.v7.app.AlertDialog$Builder.show(AlertDialog.java:902)
          at com.mycompany.mooz.MainActivity$MyHandler.handleMessage(MainActivity.java:55)
          at android.os.Handler.dispatchMessage(Handler.java:99)
          at android.os.Looper.loop(Looper.java:137)
          at android.app.ActivityThread.main(ActivityThread.java:4921)
          at java.lang.reflect.Method.invokeNative(Native Method)
          at java.lang.reflect.Method.invoke(Method.java:511)
          at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1027)
          at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)
          at dalvik.system.NativeStart.main(Native Method)
  </code></pre>
  
  <p><b>Error stack trace 2:</b></p>
  
  <pre><code>android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@427329e0 is not valid; is your activity running?
          at android.view.ViewRootImpl.setView(ViewRootImpl.java:700)
          at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:345)
          at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:224)
          at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:149)
          at android.view.Window$LocalWindowManager.addView(Window.java:554)
          at android.app.Dialog.show(Dialog.java:277)
          at android.support.v7.app.AlertDialog$Builder.show(AlertDialog.java:902)
          at com.mycompany.mooz.MainActivity`enter code here`$MyHandler.handleMessage(MainActivity.java:55)
          at android.os.Handler.dispatchMessage(Handler.java:99)
          at android.os.Looper.loop(Looper.java:137)
          at android.app.ActivityThread.main(ActivityThread.java:4921)
          at java.lang.reflect.Method.invokeNative(Native Method)
          at java.lang.reflect.Method.invoke(Method.java:511)
          at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1027)
          at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)
          at dalvik.system.NativeStart.main(Native Method)
  </code></pre>