1、MediaPlayer的生命周期

有兩種類型的弧,單箭頭表示的是同步方法調(diào)用,有兩個(gè)箭頭代表異步方法調(diào)用
1、Idle 狀態(tài)及End 狀態(tài)
當(dāng)使用new()方法創(chuàng)建一個(gè)MediaPlayer對(duì)象或者調(diào)用了其reset()方法時(shí),該MediaPlayer對(duì)象處于idle狀態(tài)。release()方法調(diào)用后進(jìn)入End狀態(tài)。
2、Initialized 狀態(tài)
setDataSource()調(diào)用之后,MediaPlayer就進(jìn)入Initialized狀態(tài),表示要播放的文件已經(jīng)設(shè)置好了。如果setDataSource()在MediaPlayer的非Idle 狀態(tài)調(diào)用,會(huì)拋出IllegalStateException異常
3、Prepared狀態(tài)
MediaPlayer準(zhǔn)備好了
- prepare():同步方法,調(diào)用這個(gè)方法,MediaPlayer就進(jìn)入Prepared狀態(tài)
- prepareAsync():異步方法,經(jīng)過Preparing 狀態(tài),在準(zhǔn)備工作結(jié)束之后,進(jìn)入Prepared狀態(tài),會(huì)回調(diào)OnPreparedListener.onPrepared()。
在Prepared狀態(tài)之后,就可以調(diào)用MediaPlayer的一些set方法了,如,setScreenOnWhilePlaying()、setVolume()、setLooping()。
4、Started 狀態(tài),Paused 狀態(tài)
在MediaPlayer準(zhǔn)備好之后,調(diào)用start()方法,此時(shí)MediaPlayer就處于Started狀態(tài);調(diào)用pause()方法,MediaPlayer進(jìn)入Paused狀態(tài)。
如果注冊(cè)過OnBufferingUpdateListener,在Started 狀態(tài)時(shí),MediaPlayer就會(huì)回調(diào)onBufferingUpdate()方法,可以使應(yīng)用程序保持跟蹤視頻流的緩沖
5、Stopped 狀態(tài)
當(dāng)MediaPlayer處于Started 、Paused 、Prepared、PlaybackCompleted狀態(tài)下,均可調(diào)用stop()停止MediaPlayer,而處于Stopped狀態(tài)的MediaPlayer要想重新播放,需要通過prepareAsync()(prepare())方法回到Prepared狀態(tài)才可以。
6、PlaybackCompleted狀態(tài)
文件正常播放完畢,而又沒有設(shè)置循環(huán)播放的話就進(jìn)入該狀態(tài),并會(huì)觸發(fā)OnCompletionListener的onCompletion()方法。
7、Error 狀態(tài)
如果由于某種原因MediaPlayer出現(xiàn)了錯(cuò)誤,會(huì)觸發(fā)OnErrorListener.onError()事件,此時(shí)MediaPlayer即進(jìn)入Error狀態(tài)
注意:
1、MediaPlayer會(huì)消耗系統(tǒng)的資源,需要在適當(dāng)?shù)臅r(shí)候把不需要的資源釋放掉。例如,如果在Activity中調(diào)用onStop()方法時(shí),需要釋放MediaPlayer。當(dāng)Activity恢復(fù)或者重新啟動(dòng)時(shí),需要?jiǎng)?chuàng)建一個(gè)新的MediaPlayer并且重新準(zhǔn)備。
釋放MediaPlayer
mediaPlayer.release();
mediaPlayer = null;
2、SurfaceView
SurfaceView是配合MediaPlayer,將一幀一幀的圖像,顯示在界面上。
指定MediaPlayer顯示圖像
void setDisplay(SurfaceHolder holder)
- SurfaceHolder可以理解為SurfaceView裝載需要顯示的一幀幀圖像的容器,它可以通過SurfaceHolder.getHolder()方法獲得。
- SurfaceView,通過雙緩沖的機(jī)制來顯示幀圖像。雙緩沖可以理解為有兩個(gè)線程輪番去 解析視頻流的幀圖像,當(dāng)一個(gè)線程解析完幀圖像后,把圖像渲染到界面中,同時(shí)另一線程開始解析下一幀圖像,使得兩個(gè)線程輪番配合去解析視頻流,以達(dá)到流暢播放的效果。
- SurfaceView內(nèi)部實(shí)現(xiàn)了雙緩沖的機(jī)制,但是實(shí)現(xiàn)這個(gè)功能是非常消耗系統(tǒng)內(nèi)存的。因?yàn)橐苿?dòng)設(shè)備的局限性,Android在設(shè)計(jì)的時(shí)候規(guī) 定,SurfaceView如果為用戶可見的時(shí)候,創(chuàng)建SurfaceView的SurfaceHolder用于顯示視頻流解析的幀圖片,如果發(fā)現(xiàn) SurfaceView變?yōu)橛脩舨豢梢姷臅r(shí)候,則立即銷毀SurfaceView的SurfaceHolder,以達(dá)到節(jié)約系統(tǒng)資源的目的。所以,需要去維護(hù)一個(gè)SurfaceHolder,需要用到它的一個(gè)回調(diào),SurfaceHolder.Callback()
public interface Callback {
public void surfaceCreated(SurfaceHolder holder);
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height);
public void surfaceDestroyed(SurfaceHolder holder);
}
3、使用
/**
* todo public
* 加載視頻
*/
public void loadAndPlay(String videoUrl){
this.videoUrl=videoUrl;
surfaceView.getHolder().setKeepScreenOn(true);
surfaceView.getHolder().addCallback(new SurfaceViewCallback());
}
/**
* 當(dāng)用戶不可見的時(shí)候 ,SurfaceHolder 就會(huì)銷毀,當(dāng)再次可見的時(shí)候,會(huì)創(chuàng)建新的SurfaceHolder;
* 使用SurfaceHolder.Callback()維護(hù)一個(gè)SurfaceHolder
*/
class SurfaceViewCallback implements SurfaceHolder.Callback {
@Override
public void surfaceCreated(SurfaceHolder holder) {
if(mediaPlayer==null){
mediaPlayer=new MediaPlayer();
mediaPlayer.setDataSource(videoUrl);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setOnPreparedListener(this);
mediaPlayer.setOnBufferingUpdateListener(this);
mediaPlayer.setOnErrorListener(this);
mediaPlayer.setOnCompletionListener(new MediaPlayerCompletion());
mediaPlayer.prepareAsync();
mediaPlayer.setDisplay(surfaceView.getHolder());
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
isVideoPrepared=false;
if(mediaPlayer!=null){
mediaPlayer.release();
mediaPlayer=null;
}
}
}
/**
* 視頻準(zhǔn)備好回調(diào)
*/
@Override
public void onPrepared(MediaPlayer mp) {
isVideoPrepared=true;
mediaPlayer.start();
mediaPlayer.setScreenOnWhilePlaying(true);
}
private boolean isVideoPrepared;

Android Multimedia框架總結(jié)(一)MediaPlayer介紹之狀態(tài)圖及生命周期、Android Multimedia框架總結(jié)(三)MediaPlayer中創(chuàng)建到setDataSource過程