美文网首页
Android VideoView 在ViewPager+Fra

Android VideoView 在ViewPager+Fra

作者: 咸鱼Jay | 来源:发表于2018-06-21 14:24 被阅读271次

    在我上一篇中实现了VideoView在ViewPager+Fragment中实现图片和视频混播的效果,参见Android 图片和视屏混播的实现和坑.但是在实际中发现有时会出现ANR异常,最后经过分析发现这是由于MediaPlayer是基于状态机实现的,有一些操作,例如reset(),release()等等都是同步实现,所以频繁操作会引起ANR,解决方案就是将所用针对mediaPlayer的操作放到单独现场handler中去同一处理,达到同步处理的目的。

    修改前的代码:

        public void startPlayer() {
            if (null != mVideoView) {
                mVideoView.seekTo(currentPosition);
                mVideoView.start();
            }
        }
    
        public void circulationPlayer(){
            if (null != mVideoView) {
                mVideoView.setVideoPath(bannerBean.getUrl());
                mVideoView.start();
            }
        }
    
        private void stopPlayer() {
            if (null != mVideoView) {
                mVideoView.stopPlayback();
            }
        }
    
        public boolean isPlaying(){
            if(null != mVideoView){
                return mVideoView.isPlaying();
            }
            return false;
        }
    
        private void pausePlayer() {
            if (null != mVideoView) {
                playerPaused = true;
                this.currentPosition = mVideoView.getCurrentPosition();
                mVideoView.pause();
            }
        }
    
        @Override
        public void onResume() {
            super.onResume();
            if(playerPaused){
                startPlayer();
            }
        }
    
        @Override
        public void onPause() {
            super.onPause();
            pausePlayer();
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
            stopPlayer();
            Log.e(TAG, "onDestroy=" + bannerBean.getUrl());
        }
    

    修改后的代码:

        /**
         * 使用Handler是为了避免出现ANR异常
         */
        private Handler handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                switch (msg.what) {
                    case STOP_PLAYER:
                        stopPlayer();
                        break;
                    case START_PLAYER:
                        startPlayer();
                        break;
                    case PAUSE_PLAYER:
                        pausePlayer();
                        break;
                    case SET_VIDEO_URL:
                        setVideoUrl();
                        startPlayer();
                        break;
                }
                super.handleMessage(msg);
            }
        };
    
        private void setVideoUrl() {
            String url = bannerBean.getUrl();
            mUrl = url;
            //播放本地视频
            mVideoView.setVideoURI(Uri.parse(url));
        }
    
        public void startPlayer() {
            if (null != mVideoView) {
                mVideoView.seekTo(currentPosition);
                mVideoView.start();
            }
        }
    
        public void circulationPlayer(){
            /*if (null != mVideoView) {
                mVideoView.setVideoPath(bannerBean.getUrl());
                mVideoView.start();
            }*/
            sendStartVideoMsg(true);
        }
    
        private void stopPlayer() {
            if (null != mVideoView) {
                mVideoView.stopPlayback();
                handler.removeCallbacksAndMessages(null);
            }
        }
    
        public boolean isPlaying(){
            if(null != mVideoView){
                return mVideoView.isPlaying();
            }
            return false;
        }
    
        private void pausePlayer() {
            if (null != mVideoView) {
                playerPaused = true;
                this.currentPosition = mVideoView.getCurrentPosition();
                mVideoView.pause();
            }
        }
    
        private void sendStartVideoMsg() {
            sendStartVideoMsg(false);
        }
    
        private void sendStartVideoMsg(boolean isHasUrl) {
            removeMessages();
            if (!handler.hasMessages(START_PLAYER)) {
                if (null != mVideoView) {
                    if (isHasUrl) {
                        try {
                            mVideoView.setVideoURI(Uri.parse(mUrl));
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                    handler.sendEmptyMessage(START_PLAYER);
                }
            }
        }
    
        private void sendStopVideoMsg() {
            removeMessages();
            if (!handler.hasMessages(STOP_PLAYER)) {
                if (null != mVideoView) {
                    handler.sendEmptyMessage(STOP_PLAYER);
                }
            }
        }
    
        private void sendPauseVideoMsg() {
            removeMessages();
            if (!handler.hasMessages(PAUSE_PLAYER)) {
                if (null != mVideoView) {
                    handler.sendEmptyMessage(PAUSE_PLAYER);
                }
            }
        }
    
        private void sendSetVideoUrlMsg() {
            removeMessages();
            if (!handler.hasMessages(SET_VIDEO_URL)) {
                if (null != mVideoView) {
                    Log.e(TAG, "sendSetVideoUrlMsg------");
                    handler.sendEmptyMessage(SET_VIDEO_URL);
                }
            }
        }
    
        private void removeMessages() {
            if (handler.hasMessages(START_PLAYER)) {
                handler.removeMessages(START_PLAYER);
            }
            if (handler.hasMessages(STOP_PLAYER)) {
                handler.removeMessages(STOP_PLAYER);
            }
            if (handler.hasMessages(PAUSE_PLAYER)) {
                handler.removeMessages(PAUSE_PLAYER);
            }
            if (handler.hasMessages(SET_VIDEO_URL)) {
                handler.removeMessages(SET_VIDEO_URL);
            }
        }
    
        @Override
        public void onResume() {
            super.onResume();
            if(playerPaused){
    //            startPlayer();
                sendStartVideoMsg();
            }
        }
    
        @Override
        public void onPause() {
            super.onPause();
    //        pausePlayer();
            sendPauseVideoMsg();
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
            //stopPlayer();
            sendStopVideoMsg();
            Log.e(TAG, "onDestroy=" + bannerBean.getUrl());
        }
    

    完整的代码:

    public class ImageVideoFragment extends Fragment {
        private static final String TAG = ImageVideoFragment.class.getSimpleName();
        private OnVideoCompletionListener listener;
        private VideoView mVideoView;
        private BannerBean bannerBean;
        private FrameLayout waitLoading;
        private int currentPosition;
        private boolean playerPaused;
        private String mUrl;
        private final int STOP_PLAYER = 0x2000;
        private final int START_PLAYER = 0x2001;
        private final int PAUSE_PLAYER = 0x2002;
        private final int SET_VIDEO_URL = 0x2003;
    
        /**
         * 使用Handler是为了避免出现ANR异常
         */
        private Handler handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                switch (msg.what) {
                    case STOP_PLAYER:
                        stopPlayer();
                        break;
                    case START_PLAYER:
                        startPlayer();
                        break;
                    case PAUSE_PLAYER:
                        pausePlayer();
                        break;
                    case SET_VIDEO_URL:
                        setVideoUrl();
                        startPlayer();
                        break;
                }
                super.handleMessage(msg);
            }
        };
    
        @Override
        public void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            Bundle bundle = getArguments();
            bannerBean = (BannerBean) bundle.getSerializable("bannerBean");
            Log.e(TAG, "type=" + bannerBean.getType() + ",url=" + bannerBean.getUrl());
        }
    
        @Nullable
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            View view;
            if (bannerBean != null) {
                int type = bannerBean.getType();
                if (type == 0) {
                    view = LayoutInflater.from(getActivity()).inflate(R.layout.item_image_view, container, false);
                    ImageView imageView = view.findViewById(R.id.iv);
                    Glide.with(container.getContext()).load(bannerBean.getUrl())
                            .into(imageView);
                } else {
                    view = LayoutInflater.from(getActivity()).inflate(R.layout.item_video_view, container, false);
                    mVideoView = view.findViewById(R.id.video_view);
                    waitLoading = view.findViewById(R.id.wait_loading_layout);
                    initData();
                }
            } else {
                view = LayoutInflater.from(getActivity()).inflate(R.layout.item_image_view, container, false);
            }
            return view;
        }
    
        private void initData() {
    
            if (null != mVideoView) {
    //            mVideoView.setVideoPath(bannerBean.getUrl());
                sendSetVideoUrlMsg();
                mVideoView.setMediaController(new MediaController(getActivity()));
                mVideoView.requestFocus();
                mVideoView.setVideoURI(Uri.parse(bannerBean.getUrl()));
                mVideoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                    @Override
                    public void onCompletion(MediaPlayer mp) {
                        mVideoView.stopPlayback();
                        if (null != listener) {
                            listener.onVideoCompletion(mp);
                        }
                    }
                });
    
                mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                    @Override
                    public void onPrepared(MediaPlayer mp) {
                        Log.e(TAG, "视频加载完成" + bannerBean.getUrl());
                        mp.setOnInfoListener(new MediaPlayer.OnInfoListener() {
                            @Override
                            public boolean onInfo(MediaPlayer mp, int what, int extra) {
                                waitLoading.setVisibility(View.GONE);
                                mVideoView.setVisibility(View.VISIBLE);
                                /*if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START) {
                                    waitLoading.setVisibility(View.GONE);
                                    mVideoView.setVisibility(View.VISIBLE);
                                    return true;
                                }*/
                                return false;
                            }
                        });
                    }
                });
    
                mVideoView.setOnErrorListener(new MediaPlayer.OnErrorListener() {
                    @Override
                    public boolean onError(MediaPlayer mp, int what, int extra) {
                        Log.e(TAG, "视频播放出错了-what="+what+",extra="+extra);
                        mVideoView.stopPlayback();
                        if(null != listener){
                            listener.onError(mp);
                        }
                        if(what == MediaPlayer.MEDIA_ERROR_SERVER_DIED){
                            //媒体服务器挂掉了。此时,程序必须释放MediaPlayer 对象,并重新new 一个新的。
                            Log.e(TAG, "媒体服务器挂掉了");
                        }else if(what == MediaPlayer.MEDIA_ERROR_UNKNOWN){
                            if(extra == MediaPlayer.MEDIA_ERROR_IO){
                                //文件不存在或错误,或网络不可访问错误
                                Log.e(TAG, "文件不存在或错误,或网络不可访问错误");
                            }else if(extra == MediaPlayer.MEDIA_ERROR_TIMED_OUT){
                                //超时
                                Log.e(TAG, "超时");
                            }
                        }
                        return true;
                    }
                });
    //            startPlayer();
            }
        }
    
        private void setVideoUrl() {
            String url = bannerBean.getUrl();
            mUrl = url;
            //播放本地视频
            mVideoView.setVideoURI(Uri.parse(url));
        }
    
        public void startPlayer() {
            if (null != mVideoView) {
                mVideoView.seekTo(currentPosition);
                mVideoView.start();
            }
        }
    
        public void circulationPlayer(){
            /*if (null != mVideoView) {
                mVideoView.setVideoPath(bannerBean.getUrl());
                mVideoView.start();
            }*/
            sendStartVideoMsg(true);
        }
    
        private void stopPlayer() {
            if (null != mVideoView) {
                mVideoView.stopPlayback();
                handler.removeCallbacksAndMessages(null);
            }
        }
    
        public boolean isPlaying(){
            if(null != mVideoView){
                return mVideoView.isPlaying();
            }
            return false;
        }
    
        private void pausePlayer() {
            if (null != mVideoView) {
                playerPaused = true;
                this.currentPosition = mVideoView.getCurrentPosition();
                mVideoView.pause();
            }
        }
    
        private void sendStartVideoMsg() {
            sendStartVideoMsg(false);
        }
    
        private void sendStartVideoMsg(boolean isHasUrl) {
            removeMessages();
            if (!handler.hasMessages(START_PLAYER)) {
                if (null != mVideoView) {
                    if (isHasUrl) {
                        try {
                            mVideoView.setVideoURI(Uri.parse(mUrl));
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                    handler.sendEmptyMessage(START_PLAYER);
                }
            }
        }
    
        private void sendStopVideoMsg() {
            removeMessages();
            if (!handler.hasMessages(STOP_PLAYER)) {
                if (null != mVideoView) {
                    handler.sendEmptyMessage(STOP_PLAYER);
                }
            }
        }
    
        private void sendPauseVideoMsg() {
            removeMessages();
            if (!handler.hasMessages(PAUSE_PLAYER)) {
                if (null != mVideoView) {
                    handler.sendEmptyMessage(PAUSE_PLAYER);
                }
            }
        }
    
        private void sendSetVideoUrlMsg() {
            removeMessages();
            if (!handler.hasMessages(SET_VIDEO_URL)) {
                if (null != mVideoView) {
                    Log.e(TAG, "sendSetVideoUrlMsg------");
                    handler.sendEmptyMessage(SET_VIDEO_URL);
                }
            }
        }
    
        private void removeMessages() {
            if (handler.hasMessages(START_PLAYER)) {
                handler.removeMessages(START_PLAYER);
            }
            if (handler.hasMessages(STOP_PLAYER)) {
                handler.removeMessages(STOP_PLAYER);
            }
            if (handler.hasMessages(PAUSE_PLAYER)) {
                handler.removeMessages(PAUSE_PLAYER);
            }
            if (handler.hasMessages(SET_VIDEO_URL)) {
                handler.removeMessages(SET_VIDEO_URL);
            }
        }
    
        @Override
        public void onResume() {
            super.onResume();
            if(playerPaused){
    //            startPlayer();
                sendStartVideoMsg();
            }
        }
    
        @Override
        public void onPause() {
            super.onPause();
    //        pausePlayer();
            sendPauseVideoMsg();
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
            //stopPlayer();
            sendStopVideoMsg();
            Log.e(TAG, "onDestroy=" + bannerBean.getUrl());
        }
        public interface OnVideoCompletionListener {
            void onVideoCompletion(MediaPlayer mp);
            void onError(MediaPlayer mp);
        }
    
        public void setOnVideoCompletionListener(OnVideoCompletionListener listener) {
            this.listener = listener;
        }
    }
    

    项目地址

    相关文章

      网友评论

          本文标题:Android VideoView 在ViewPager+Fra

          本文链接:https://www.haomeiwen.com/subject/bhiqyftx.html