title: why use WeakReference for Handler still leak?
body: <pre><code>private static class MyHandler extends Handler {
          private final WeakReference&lt;ChannelPlayer&gt; parentReference;
  
          protected MyHandler(ChannelPlayer activity) {
              parentReference = new WeakReference&lt;&gt;(activity);
          }
  
          @Override
          public void handleMessage(Message msg) {
              final ChannelPlayer parent = parentReference.get();
              if (parent != null) {
                  runWithParent(parent, msg);
              }
              super.handleMessage(msg);
          }
  
          public void runWithParent(ChannelPlayer parent, Message msg){
              switch (msg.what) {
                  case MEDIA_PLAYER_VIDEO_NETSPEED: {
                      parent.mMediaController.setDownloadRate(String.valueOf(msg.arg1) + "KB/s");
                      parent.mNetSpeed.setTextSize(30);
                      parent.mNetSpeed.setText(String.format(mNetSpeedText, String.valueOf(msg.arg1) + "KB/s"));
                      break;
                  }
  
                  case MEDIA_PLAYER_BUFFERING_UPDATE: {
                      break;
                  }
                  case MEDIA_PLAYER_COMPLETION: {
                      break;
                  }
                  case MEDIA_PLAYER_LONG_PREPERING: {
                      // 如果长时间没有完成prepering，也就是长时间没有加载进视频直接换台
                      // 播放错误了，自动换台
  
                      parent.sendChannelBroken();
                      parent.sendChannelSave(true);
                      parent.changeSource();
                      break;
                  }
                  case MEDIA_PLAYER_INFO: {
                      if (msg.arg1 == IMediaPlayer.MEDIA_INFO_NOT_SEEKABLE) {
                          parent.mCanSeek = false;
                      } else if (msg.arg1 == IMediaPlayer.MEDIA_INFO_BUFFERING_START) {
                          parent.mProgressBarPreparing.setVisibility(View.VISIBLE);
                          parent.mNetSpeed.setVisibility(View.VISIBLE);
                      /*
                       * if (parent.mMediaPlayer.isPlaying()) {
                       * parent.mMediaPlayer.pause(); }
                       */
                      } else if (msg.arg1 == IMediaPlayer.MEDIA_INFO_BUFFERING_END) {
                          parent.mEventHandler.removeMessages(MEDIA_PLAYER_LONG_PREPERING);
                          parent.mProgressBarPreparing.setVisibility(View.GONE);
                          parent.mProgressBarPreparingText.setVisibility(View.GONE);
                          parent.mProgressBarPreparingEpgNextText.setVisibility(View.GONE);
                          parent.mProgressBarPreparingEpgCurrentText.setVisibility(View.GONE);
                          parent.mNetSpeed.setVisibility(View.GONE);
                      /*
                       * if (parent.mMediaPlayer.isPlaying()) {
                       * parent.mMediaPlayer.start(); }
                       */
                      }
                      break;
                  }
                  case MEDIA_PLAYER_CHANGE_CHANNEL: {
                      parent.setProgressBarPreParingText();
                      parent.resetMediaPlayer();
                      break;
                  }
                  case MEDIA_PLAYER_SETED_DATASOURCE: {
                      parent.setDataSource(parent.mMediaPath);
                      parent.mChannelList.setSelection(parent.favListAdapter.getSelection());
                      break;
                  }
                  case MEDIA_PLAYER_NUM_UPDATE: {
                      // 更新数字建
                      int position = parent.favListAdapter.getPosition(parent.playerKeyNum);
                      if (position &gt; -1) {
                          parent.changeChannel(parent.favListAdapter.getBean(position));
                          parent.setChannelListTitle();
                      } else {
                          parent.mPlayerKeyView.setText(R.string.player_worng_channel_number);
                      }
  
                      parent.playerKeyNum = -1;
                      parent.mEventHandler.sendEmptyMessageDelayed(MEDIA_PLAYER_NUMKEY_HIDDEN, 2000);
                      break;
  
                  }
                  case MEDIA_PLAYER_NUMKEY_HIDDEN: {
                      parent.hiddenPlayerKeyNum();
                      break;
                  }
  
                  case EPG_LIST_HIDDEN: {
                      parent.mChannelEpgList.setVisibility(View.GONE);
                      break;
                  }
                  case EPG_LIST_SHOWING: {
                      parent.mChannelEpgList.setVisibility(View.VISIBLE);
                      break;
                  }
                  default:
                      break;
              }
  
          }
      }
  </code></pre>
  
  <p>In 'onCreate', I init the handler:</p>
  
  <pre><code>mEventHandler = new MyHandler(this);
  </code></pre>
  
  <p>and in onDestroy</p>
  
  <pre><code>mEventHandler.removeCallbacksAndMessages(null);
  mEventHandler = null;
  </code></pre>
  
  <p>but it is still show leak!why?</p>
  
  <pre><code>03-18 20:49:40.135 14372-15987/tv.zvdio D/LeakCanary: In tv.zvdio:WTV-B-20160320:116.
  03-18 20:49:40.135 14372-15987/tv.zvdio D/LeakCanary: * tv.zvdio.ui.player.ChannelPlayer has leaked:
  03-18 20:49:40.135 14372-15987/tv.zvdio D/LeakCanary: * GC ROOT android.os.HandlerThread.&lt;Java Local&gt;
  03-18 20:49:40.135 14372-15987/tv.zvdio D/LeakCanary: * leaks tv.zvdio.ui.player.ChannelPlayer instance
  03-18 20:49:40.135 14372-15987/tv.zvdio D/LeakCanary: * Retaining: 5.8 MB.
  03-18 20:49:40.135 14372-15987/tv.zvdio D/LeakCanary: * Reference Key: 4c2be65c-0924-44f2-ac68-333ff539507a
  03-18 20:49:40.135 14372-15987/tv.zvdio D/LeakCanary: * Device: Xiaomi Xiaomi MI 3C cancro
  03-18 20:49:40.135 14372-15987/tv.zvdio D/LeakCanary: * Android Version: 6.0.1 API: 23 LeakCanary: 1.4-beta1 02804f3
  03-18 20:49:40.135 14372-15987/tv.zvdio D/LeakCanary: * Durations: watch=5020ms, gc=174ms, heap dump=6094ms, analysis=31821ms
  03-18 20:49:40.135 14372-15987/tv.zvdio D/LeakCanary: * Details:
  03-18 20:49:40.135 14372-15987/tv.zvdio D/LeakCanary: * Instance of android.os.HandlerThread
  03-18 20:49:40.135 14372-15987/tv.zvdio D/LeakCanary: |   mLooper = android.os.Looper@851452256 (0x32c02160)
  03-18 20:49:40.135 14372-15987/tv.zvdio D/LeakCanary: |   mPriority = 0
  03-18 20:49:40.135 14372-15987/tv.zvdio D/LeakCanary: |   mTid = 14895
  03-18 20:49:40.135 14372-15987/tv.zvdio D/LeakCanary: |   contextClassLoader = dalvik.system.PathClassLoader@851452736 (0x32c02340)
  03-18 20:49:40.135 14372-15987/tv.zvdio D/LeakCanary: |   daemon = false
  03-18 20:49:40.135 14372-15987/tv.zvdio D/LeakCanary: |   group = java.lang.ThreadGroup@1896861424 (0x710fcef0)
  03-18 20:49:40.136 14372-15987/tv.zvdio D/LeakCanary: |   hasBeenStarted = true
  03-18 20:49:40.136 14372-15987/tv.zvdio D/LeakCanary: |   id = 37566
  03-18 20:49:40.136 14372-15987/tv.zvdio D/LeakCanary: |   inheritableValues = null
  03-18 20:49:40.136 14372-15987/tv.zvdio D/LeakCanary: |   interruptActions = java.util.ArrayList@853002752 (0x32d7ca00)
  03-18 20:49:40.136 14372-15987/tv.zvdio D/LeakCanary: |   localValues = java.lang.ThreadLocal$Values@853002784 (0x32d7ca20)
  03-18 20:49:40.136 14372-15987/tv.zvdio D/LeakCanary: |   lock = java.lang.Object@851448048 (0x32c010f0)
  03-18 20:49:40.136 14372-15987/tv.zvdio D/LeakCanary: |   name = java.lang.String@851614976 (0x32c29d00)
  03-18 20:49:40.136 14372-15987/tv.zvdio D/LeakCanary: |   nativePeer = -1412130816
  03-18 20:49:40.136 14372-15987/tv.zvdio D/LeakCanary: |   parkBlocker = null
  03-18 20:49:40.136 14372-15987/tv.zvdio D/LeakCanary: |   parkState = 1
  03-18 20:49:40.136 14372-15987/tv.zvdio D/LeakCanary: |   priority = 5
  03-18 20:49:40.136 14372-15987/tv.zvdio D/LeakCanary: |   stackSize = 0
  03-18 20:49:40.136 14372-15987/tv.zvdio D/LeakCanary: |   target = null
  03-18 20:49:40.136 14372-15987/tv.zvdio D/LeakCanary: |   uncaughtHandler = null
  03-18 20:49:40.136 14372-15987/tv.zvdio D/LeakCanary: |   shadow$_klass_ = android.os.HandlerThread
  03-18 20:49:40.136 14372-15987/tv.zvdio D/LeakCanary: |   shadow$_monitor_ = 1252025007
  03-18 20:49:40.136 14372-15987/tv.zvdio D/LeakCanary: * Instance of tv.zvdio.ui.player.ChannelPlayer
  </code></pre>
  
  <p>it is very sad.
  btw, my app has two process, one is the main activity, another is used for media player, so when i finished the video activity, it is show leak.</p>