为什么使用WeakReference for Handler仍然泄密?

时间:2016-03-18 13:06:43

标签: leakcanary

private static class MyHandler extends Handler {
        private final WeakReference<ChannelPlayer> parentReference;

        protected MyHandler(ChannelPlayer activity) {
            parentReference = new WeakReference<>(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 > -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;
            }

        }
    }

在&#39; onCreate&#39;中,我初始化处理程序:

mEventHandler = new MyHandler(this);

和onDestroy

mEventHandler.removeCallbacksAndMessages(null);
mEventHandler = null;

但它仍然显示泄漏!为什么?

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.<Java Local>
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

非常难过。 顺便说一句,我的应用程序有两个进程,一个是主要活动,另一个用于媒体播放器,所以当我完成视频活动时,它就是显示泄漏。

0 个答案:

没有答案