对MediaPlayer的错误使用总结

近期做的一个项目,里面涉及到很多音频播放,于是在网上找一篇MeidialPlayer的代码使用,功能开发完毕,提交测试之后,发现音频播放几十次之后就停止了,无法播放,必须退出Activity重新进入才可以再次播放;于是从头开始根据google官方关于MediaPalyer的介绍看了一遍,很快就解决的问题。

首先来看网站找的代码(只贴核心代码)

    public void startPlay(String path) {
        stopPlay();
        MediaPlayer mediaPlayer = new MediaPlayer();
        mediaPlayer.setOnPreparedListener(this);
        mediaPlayer.setOnCompletionListener(this);
        mediaPlayer.setOnErrorListener(this);
        try {
            mediaPlayer.setDataSource(path);
            mediaPlayer.prepareAsync();
        } catch (IOException e) {
            e.printStackTrace();
            if(listener != null) {
                listener.onError(String.format("MediaPlayer setDataSource Error by %s", e.getMessage()));
            }
        }
    }
  
    public void stopPlay() {
        if(mediaPlayer != null && !isRelease) {
            mediaPlayer.stop();
            mediaPlayer.release();
            mediaPlayer = null;
        }
    }
  
      @Override
    public void onPrepared(MediaPlayer mediaPlayer) {
        this.mediaPlayer = mediaPlayer;
        this.mediaPlayer.start();
        this.isRelease = false;
        if(listener != null) {
            listener.onPrepared();
        }
    }

    @Override
    public void onCompletion(MediaPlayer mediaPlayer) {
        if(this.mediaPlayer != null) {
            if(isRelease) {
                this.mediaPlayer.release();
                isRelease = true;
            }
            mediaPlayer = null;
        }
        if(listener != null) {
            listener.onCompletion();
        }
    }
复制代码

我先说说它的实现:把MediaPlayer做一层封装,把MediaPlayer做了全局变量,首先在启动播放之前,先关闭(释放资源并置空)上一个音频播放,然后初始化MediaPlayer和一些监听;当MediaPlayer到达准备状态之后,把MediaPlayer做成全局引用,并设置是否释放音频资源的状态,然后当音频播放完成之后,再完成回调中执行释放操作;这样使用相当于频繁的创建MediaPlayer和释放;如果只是偶尔播放一下音频应该不会出现问题,但如果做需要播放大量音频的项目,就会报错;

要解决这个问题,我们先来看看google官方是如何教我们使用MediaPlayer的:

上面很清楚的可以看到MediaPlayer各个状态的切换: 1、Idle:空闲状态,用户通过new创建MediaPlayer或者调用reset()都可进入此状态,注意该状态下不可执行prepare()、start()等方法; 2、Initialized:初始化状态,对处于空闲状态下的MediaPlayer调用setDataSource()即可,该状态下用户可执行prepare()、prepareAsync()方法; 3、Prepared:准备状态,设置播放资源后,调用prepare()或prepareAsync()方法进入准备播放状态,用户可以通过调用start()方法来播放音频(注意如果是网络地址必须在onPrepared()中start()); 4、Started:播放状态,执行start()之后,开始播放音频,播放完成后,执行OnComplete()回调,调用paused()进入暂停状态,调用start()可以恢复播放状态; 5、Stopped:停止状态; 6、Paused:暂停状态;

public class PlayUtils implements MediaPlayer.OnPreparedListener, MediaPlayer.OnCompletionListener, MediaPlayer.OnErrorListener {

    private MediaPlayer mediaPlayer;
    private OnPlayerListener listener;

    public PlayUtils() {
        mediaPlayer = new MediaPlayer();
    }

    public void setOnPlayerListener(OnPlayerListener onPlayerListener) {
        this.listener = onPlayerListener;
    }

    @Override
    public void onPrepared(MediaPlayer mediaPlayer) {
        mediaPlayer.start();
        if(listener != null) {
            listener.onPrepared();
        }
    }

    @Override
    public void onCompletion(MediaPlayer mediaPlayer) {
        if(listener != null) {
            listener.onCompletion();
        }
    }

    @Override
    public boolean onError(MediaPlayer mediaPlayer, int i, int i1) {
        if(listener != null) {
            listener.onError(String.format("MediaPlayer error what %d error %d", i, i1));
        }
        return true;
    }

    public interface OnPlayerListener {
        void onPrepared();

        void onCompletion();

        void onError(String error);
    }

    public void startPlay(String path) {
        if(mediaPlayer == null) {
            mediaPlayer = new MediaPlayer();
        }else {
            stopPlay();
        }
        mediaPlayer.setOnPreparedListener(this);
        mediaPlayer.setOnCompletionListener(this);
        mediaPlayer.setOnErrorListener(this);
        try {
            mediaPlayer.setDataSource(path);
            mediaPlayer.prepareAsync();
        } catch (IOException e) {
            e.printStackTrace();
            if(listener != null) {
                listener.onError(String.format("MediaPlayer setDataSource Error by %s", e.getMessage()));
            }
        }
    }

    public void stopPlay() {
        if(mediaPlayer != null) {
            mediaPlayer.stop();
            mediaPlayer.reset();
        }
    }

    public boolean isPlaying() {
        return mediaPlayer != null && mediaPlayer.isPlaying();
    }

    public void onDestroy() {
        if(mediaPlayer != null) {
            mediaPlayer.stop();
            mediaPlayer.release();
            mediaPlayer = null;
        }
    }
}
复制代码

以上就是使用MediaPlayer的一点小结,如有疑问或错误,可在下方评论区留言,谢谢~

转载于:https://juejin.im/post/5b5d38346fb9a04fbe12ebd9

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值