Android MediaPlayer的狀態(tài)管理

用過MediaPlayer來實現(xiàn)音視頻播放功能的同學(xué)應(yīng)該都知道MediaPlayer是基于狀態(tài)的启绰,也就是說MediaPlayer內(nèi)部保留著一個狀態(tài)機(jī)埋哟,用于管理內(nèi)部的狀態(tài)捡遍。在編寫代碼時必須始終注意牵祟,某些操作僅在播放器處于特定狀態(tài)時才有效痪蝇。如果在錯誤的狀態(tài)下執(zhí)行某項操作攻旦,則系統(tǒng)可能會拋出異秤骺酰或?qū)е缕渌涣夹袨椤?/p>

下圖展示了android MediaPlayer 的所有狀態(tài)以及狀態(tài)之間的轉(zhuǎn)換,該圖說明了從哪些狀態(tài)可以通過調(diào)用哪些方法從而將MediaPlayer變?yōu)榱硪环N狀態(tài)牢屋。圖中且预,藍(lán)色的橢圓表示MediaPlayer對象可能駐留的狀態(tài)±游蓿弧線表示驅(qū)動MediaPlayer對象狀態(tài)轉(zhuǎn)換的播放控制操作(也即可以調(diào)用的方法)锋谐。有兩種類型的弧線,具有單箭頭的弧表示同步方法調(diào)用截酷,而具有雙箭頭的弧表示異步方法調(diào)用涮拗。


MediaPlayer狀態(tài)轉(zhuǎn)換圖

下面通過文字來對上圖的狀態(tài)變化做一些說明:

  • 當(dāng)一個MediaPlaye對象剛剛通過 new 方法創(chuàng)建,或者在調(diào)用reset()
    方法之后迂苛,它將處于Idle狀態(tài)三热。并且在 release()方法被調(diào)用之后,它將處于End狀態(tài)三幻。在這兩種狀態(tài)之間是MediaPlayer對象的完整生命周期就漾。

  • 雖然通過new方法新創(chuàng)建的MediaPlayer對象和調(diào)用reset()方法之后的MediaPlayer對象都處于Idle狀態(tài),但二者之間卻存在著細(xì)微又非常重要的區(qū)別:

  • 在Idle狀態(tài)下通過調(diào)用setDataSource(java.io.FileDescriptor), setDataSource(java.lang.String), setDataSource(android.content.Context, android.net.Uri), setDataSource(java.io.FileDescriptor, long, long), setDataSource(android.media.MediaDataSource)等方法MediaPlayer將跳轉(zhuǎn)到Initialized狀態(tài)。

  • 然后,必須使用 prepare()prepareAsync() 方法完成準(zhǔn)備工作妒貌。當(dāng) 準(zhǔn)備就緒后通危,便會進(jìn)入Prepared狀態(tài),

  • 進(jìn)入Prepared狀態(tài)后可以通過調(diào)用 start() 使其播放媒體內(nèi)容灌曙。start()成功返回后 菊碟,MediaPlayer對象處于Started狀態(tài)≡诖蹋可以通過調(diào)用isPlaying()來測試MediaPlayer對象是否處于Started狀態(tài)逆害。

  • 可以通過調(diào)用 start()pause()seekTo() 等方法在Started蚣驼、PausedPlaybackCompleted狀態(tài)之間切換魄幕。

  • 調(diào)用stop()方法可以讓MediaPlayer停止播放,并使處于Started颖杏,Paused纯陨,Prepared PlaybackCompleted狀態(tài)的MediaPlayer 進(jìn)入 Stopped狀態(tài)。不過請注意留储,當(dāng)調(diào)用 stop()時翼抠,除非再次調(diào)用prepare()prepareAsync()將MediaPlayer對象設(shè)置為Prepared狀態(tài),否則將無法再次調(diào)用 start()進(jìn)行播放获讳。此外調(diào)用stop()對已經(jīng)處于Stopped狀態(tài)的MediaPlayer對象無效阴颖。

  • 當(dāng)播放到達(dá)音視頻流的結(jié)尾時,播放完成丐膝。此時 如果循環(huán)模式isLooping 為true 那么MediaPlayer對象將保持在Started狀態(tài)并將從頭開始重新播放膘盖。如果isLooping 為false并且預(yù)先注冊了OnCompletionListener,則播放器引擎將調(diào)用用戶提供的回調(diào)方法OnCompletion.onCompletion()尤误∠琅希回調(diào)的調(diào)用表明該對象現(xiàn)在處于PlaybackCompleted狀態(tài)。PlaybackCompleted 狀態(tài)下损晤,再次調(diào)用start()可以從音頻/視頻源的開頭重新開始播放软棺。

在編寫與 MediaPlayer相關(guān)的代碼時,請始終牢記該狀態(tài)圖尤勋,因為從錯誤的狀態(tài)調(diào)用其方法是導(dǎo)致錯誤發(fā)生的常見原因喘落。

最后附上MediaPlayer各接口方法的調(diào)用時機(jī):

方法名稱 ? ? ? ? ? 有效狀態(tài) 無效狀態(tài) 說明
attachAuxEffect {Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted} {Idle, Error} 此方法必須在setDataSource之后調(diào)用。調(diào)用它不會更改對象狀態(tài)
getCurrentPosition {Idle, Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted} {Error} 在有效狀態(tài)下成功調(diào)用此方法不會更改狀態(tài)最冰。在無效狀態(tài)下調(diào)用此方法會將對象轉(zhuǎn)移到錯誤狀態(tài)
getDuration {Prepared, Started, Paused, Stopped, PlaybackCompleted} {Idle, Initialized, Error} 在有效狀態(tài)下成功調(diào)用此方法不會更改狀態(tài)瘦棋。在無效狀態(tài)下調(diào)用此方法會將對象轉(zhuǎn)移到錯誤狀態(tài)
getVideoHeight {Idle, Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted} {Error} 在有效狀態(tài)下成功調(diào)用此方法不會更改狀態(tài)。在無效狀態(tài)下調(diào)用此方法會將對象轉(zhuǎn)移到錯誤狀態(tài)
getVideoWidth {Idle, Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted} {Error} 在有效狀態(tài)下成功調(diào)用此方法不會更改狀態(tài)暖哨。在無效狀態(tài)下調(diào)用此方法會將對象轉(zhuǎn)移到錯誤狀態(tài)
isPlaying {Idle, Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted} {Error} 在有效狀態(tài)下成功調(diào)用此方法不會更改狀態(tài)赌朋。在無效狀態(tài)下調(diào)用此方法會將對象轉(zhuǎn)移到錯誤狀態(tài)
pause {Started, Paused, PlaybackCompleted} {Idle, Initialized, Prepared, Stopped, Error} 在有效狀態(tài)下成功調(diào)用此方法會將對象轉(zhuǎn)移到“ 暫停”狀態(tài)。在無效狀態(tài)下調(diào)用此方法會將對象轉(zhuǎn)移到錯誤狀態(tài)
prepare {Initialized, Stopped} {Idle, Prepared, Started, Paused, PlaybackCompleted, Error} 在有效狀態(tài)下成功調(diào)用此方法會將對象轉(zhuǎn)移到Prepared狀態(tài)沛慢。在無效狀態(tài)下調(diào)用此方法將引發(fā)IllegalStateException
prepareAsync {Initialized, Stopped} {Idle, Prepared, Started, Paused, PlaybackCompleted, Error} 在有效狀態(tài)下成功調(diào)用此方法會將對象轉(zhuǎn)移到“ 準(zhǔn)備”狀態(tài)赡若。在無效狀態(tài)下調(diào)用此方法將引發(fā)IllegalStateException
release Any release()之后該對象不再可用
reset {Idle, Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted, Error} {} reset之后,對象就像剛剛創(chuàng)建
seekTo {Prepared, Started, Paused, PlaybackCompleted} {Idle, Initialized, Stopped, Error} 在有效狀態(tài)下成功調(diào)用此方法不會更改狀態(tài)团甲。在無效狀態(tài)下調(diào)用此方法會將對象轉(zhuǎn)移到錯誤狀態(tài)
setDataSource {Idle} {Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted, Error} 在有效狀態(tài)下成功調(diào)用此方法會將對象轉(zhuǎn)移到初始化狀態(tài)逾冬。在無效狀態(tài)下調(diào)用此方法將引發(fā)IllegalStateException
setLooping {Idle, Initialized, Stopped, Prepared, Started, Paused, PlaybackCompleted} {Error} 在有效狀態(tài)下成功調(diào)用此方法不會更改狀態(tài)。在無效狀態(tài)下調(diào)用此方法會將對象轉(zhuǎn)移到錯誤狀態(tài)
setVolume {Idle, Initialized, Stopped, Prepared, Started, Paused, PlaybackCompleted} {Error} 成功調(diào)用此方法不會更改狀態(tài)
start {Prepared, Started, Paused, PlaybackCompleted} {Idle, Initialized, Stopped, Error} 在有效狀態(tài)下成功調(diào)用此方法會將對象轉(zhuǎn)移到“ 開始”狀態(tài)躺苦。在無效狀態(tài)下調(diào)用此方法會將對象轉(zhuǎn)移到錯誤狀態(tài)
stop {Prepared, Started, Stopped, Paused, PlaybackCompleted} {Idle, Initialized, Error} 在有效狀態(tài)下成功調(diào)用此方法會將對象轉(zhuǎn)移到“已停止”狀態(tài)身腻。在無效狀態(tài)下調(diào)用此方法會將對象轉(zhuǎn)移到錯誤狀態(tài)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市匹厘,隨后出現(xiàn)的幾起案子霸株,更是在濱河造成了極大的恐慌,老刑警劉巖集乔,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件具练,死亡現(xiàn)場離奇詭異贪绘,居然都是意外死亡仗哨,警方通過查閱死者的電腦和手機(jī)判莉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進(jìn)店門屎债,熙熙樓的掌柜王于貴愁眉苦臉地迎上來肛度,“玉大人屡拨,你說我怎么就攤上這事份招≌稍埽” “怎么了哩罪?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長巡验。 經(jīng)常有香客問我际插,道長,這世上最難降的妖魔是什么显设? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任框弛,我火速辦了婚禮,結(jié)果婚禮上捕捂,老公的妹妹穿的比我還像新娘瑟枫。我一直安慰自己,他們只是感情好指攒,可當(dāng)我...
    茶點故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布慷妙。 她就那樣靜靜地躺著,像睡著了一般允悦。 火紅的嫁衣襯著肌膚如雪膝擂。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天,我揣著相機(jī)與錄音猿挚,去河邊找鬼咐旧。 笑死,一個胖子當(dāng)著我的面吹牛绩蜻,可吹牛的內(nèi)容都是我干的铣墨。 我是一名探鬼主播,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼办绝,長吁一口氣:“原來是場噩夢啊……” “哼伊约!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起孕蝉,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤屡律,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后降淮,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體超埋,經(jīng)...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年佳鳖,在試婚紗的時候發(fā)現(xiàn)自己被綠了霍殴。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,646評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡系吩,死狀恐怖来庭,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情穿挨,我是刑警寧澤月弛,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站科盛,受9級特大地震影響帽衙,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜贞绵,卻給世界環(huán)境...
    茶點故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一佛寿、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧但壮,春花似錦冀泻、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至溯祸,卻和暖如春肢专,著一層夾襖步出監(jiān)牢的瞬間舞肆,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工博杖, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留椿胯,地道東北人。 一個月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓剃根,卻偏偏與公主長得像哩盲,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子狈醉,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,514評論 2 348

推薦閱讀更多精彩內(nèi)容