近期做的一個專案,裡面涉及到很多音訊播放,於是在網上找一篇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的一點小結,如有疑問或錯誤,可在下方評論區留言,謝謝~