近期做的一个项目,里面涉及到很多音频播放,于是在网上找一篇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的一点小结,如有疑问或错误,可在下方评论区留言,谢谢~