关闭

Android VideoView 跟随Fragment生命周期切换视频播放,引起的ANR问题解答

标签: 多媒体ANRMediaPlayer
921人阅读 评论(0) 收藏 举报
分类:

最近工作用遇到了需要根据当前所在fragment生命周期去控制全屏显示VideoView播放问题,但是由于MediaPlayer是基于状态机实现的,有一些操作,例如reset(),release()等等都是同步实现,所以频繁操作会引起ANR,解决方案就是将所用针对mediaPlayer的操作放到单独现场handler中去同一处理,达到同步处理的目的。

修改前代码如下:

@Override
    public void onResume() {
        super.onResume();
        isPause = false;
        if (canResume() && needResume && mVideoView != null) {
            sendStartVideoMsg();
            try {
                mVideoView.setVideoURI(Uri.parse("file://" + info.accUrl));
                mVideoView.start();
                needResume = false;
            } catch (Exception e) {

            }
        }
    }
    boolean isPause = false;
    @Override
    public void onPause() {
        super.onPause();
        isPause = true;
        if (mImageView != null && mImageView.getVisibility() != View.VISIBLE) {
            mImageView.setVisibility(View.VISIBLE);
        }
        if (canResume() && mVideoView != null) {
            if (mVideoView.isPlaying()) {
                mVideoView.stopPlayback();
            }
            needResume = true;
            onVideoStop(PreviewAccessoryType.TYPE_LOCAL_VIDEO, VIDEO_STOP);
        }
    }
修改后代码如下:

@Override
    public void onResume() {
        super.onResume();
        isPause = false;
        if (canResume() && needResume && mVideoView != null) {
            sendStartVideoMsg();
//            try {
//                mVideoView.setVideoURI(Uri.parse("file://" + info.accUrl));
//                mVideoView.start();
//                needResume = false;
//            } catch (Exception e) {
//
//            }
        }
    }
    boolean isPause = false;
    @Override
    public void onPause() {
        super.onPause();
        isPause = true;
        if (mImageView != null && mImageView.getVisibility() != View.VISIBLE) {
            mImageView.setVisibility(View.VISIBLE);
        }
        if (canResume() && mVideoView != null) {
            sendStopVideoMsg();
//            if (mVideoView.isPlaying()) {
//                mVideoView.stopPlayback();
//            }
            needResume = true;
            onVideoStop(PreviewAccessoryType.TYPE_LOCAL_VIDEO, VIDEO_STOP);
        }
    }

    private boolean canResume() {
        return mhidden == STATE_VISIBLE;
    }

    HandlerThread ht = new HandlerThread("stopPlayBack");
    Handler handler;

    private final int STOPPLAYBACK = 1000;
    private final int START = 2000;

    private void sendStartVideoMsg() {
        if (handler.hasMessages(STOPPLAYBACK)) {
            handler.removeMessages(STOPPLAYBACK);
        }
        if (handler.hasMessages(START)) {
            handler.removeMessages(START);
        }
        if (!handler.hasMessages(START)) {
            if (null != mVideoView) {
                try {
                    mVideoView.setVideoURI(Uri.parse("file://" + info.accUrl));
                } catch (Exception e) {
                }
                handler.sendEmptyMessage(START);
            }
        }
    }

    private void sendStopVideoMsg() {
        if (handler.hasMessages(START)) {
            handler.removeMessages(START);
        }
        if (handler.hasMessages(STOPPLAYBACK)) {
            handler.removeMessages(STOPPLAYBACK);
        }
        if (!handler.hasMessages(STOPPLAYBACK)) {
            if (null != mVideoView) {
                handler.sendEmptyMessage(STOPPLAYBACK);
            }
        }
    }

    private void startVideo() {
        if (mVideoView != null && !mVideoView.isPlaying()) {
            try {
                mVideoView.start();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private void stopVideo() {
        if (mVideoView != null) {
            if (mVideoView.isPlaying()) {
                mVideoView.stopPlayback();
            }
            onVideoStop(PreviewAccessoryType.TYPE_LOCAL_VIDEO, VIDEO_STOP);
        }
    }

handler处理如下:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    initData(position, pos, info);
    ht.start();
    handler = new Handler(ht.getLooper()) {
        @Override
        public void handleMessage(Message msg) {
            try {
                switch (msg.what) {
                    case STOPPLAYBACK:
                        stopVideo();
                        break;
                    case START:
                        startVideo();
                        break;
                }
            } catch (Exception e) {

            }
            super.handleMessage(msg);
        }
    };
}

1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:3360次
    • 积分:104
    • 等级:
    • 排名:千里之外
    • 原创:5篇
    • 转载:13篇
    • 译文:0篇
    • 评论:2条