音頻播放中點(diǎn)擊當(dāng)前歌曲播放下一首歌的問題解決

在項(xiàng)目中有這樣一個(gè)需求,就是在列表中點(diǎn)擊一首歌會(huì)跳到歌曲的詳情頁進(jìn)行播放,關(guān)于音頻播放常用的做法就是用service來進(jìn)行播放,activity與service直接建立一個(gè)中間人對(duì)象,通過中間人來控制音樂的播放與暫停或者上一首,下一首。

在播放代碼中一般對(duì)MediaPlayer對(duì)象進(jìn)行如下設(shè)置:

mediaPlayer.setDataSource(url);
mediaPlayer.setOnPreparedListener(mOnPreparedListener);
mediaPlayer.setOnCompletionListener(mOnCompletionListener);
mediaPlayer.setOnErrorListener(mOnErrorListener);
mediaPlayer.prepareAsync();

在實(shí)際運(yùn)用過程中發(fā)現(xiàn)當(dāng)我點(diǎn)擊第一首播放的時(shí)候,會(huì)自動(dòng)播放下一首,第一首不會(huì)播放。對(duì)播放的監(jiān)聽里面打log發(fā)現(xiàn),一開始播放第一首的時(shí)候直接不會(huì)走PreparedListener的監(jiān)聽而是直接走了CompletionListener的監(jiān)聽。但是當(dāng)我在當(dāng)前界面而不進(jìn)入詳情頁,通過startService來進(jìn)行播放的時(shí)候就沒有問題。

然后進(jìn)行谷歌,上面說prepareAsync( )方法是一個(gè)異步操作,用prepared( )方法才會(huì)走PreparedListener的監(jiān)聽,遂將prepareAsync()方法改為prepared( )。這個(gè)時(shí)候問題貌似解決了,但是后面還有更大的坑在等著我。。。。

因?yàn)閜repared( )在主線程中是個(gè)耗時(shí)操作,原先的時(shí)候在音樂詳情頁的activity中oncreat( )下通過bindservice 跟 startservice來進(jìn)行音樂的播放。當(dāng)我們點(diǎn)擊當(dāng)前列表?xiàng)l目的時(shí)候,需要等待4 5 秒才能進(jìn)入音樂詳情頁進(jìn)行音樂的播放。

很顯然這樣是不符合我們的預(yù)期的,經(jīng)過打斷點(diǎn)調(diào)試發(fā)現(xiàn)問題就出在startservice( )調(diào)用之后再在service里面的mediaplayer調(diào)用prepared( )方法所致。當(dāng)時(shí)開發(fā)比較緊張,先用handler的postdelayed( )方法延遲500毫秒加載startService( )方法。

至此可以現(xiàn)在打開音樂詳情的界面,然后進(jìn)行播放了。但是這樣也是治標(biāo)不治本,prepared( )還是運(yùn)行在主線程,等待播放的時(shí)候還是需要等待4 5 秒鐘,很容易造成ANR。并且在測試環(huán)境下,有可能后臺(tái)給的歌曲地址不正確播放不出來的時(shí)候,app就會(huì)假死,盡管我設(shè)置了出錯(cuò)的監(jiān)聽。

本質(zhì)上還是要把prepared( )方法改為prepareAsync( ),經(jīng)老大研究別的開源項(xiàng)目指點(diǎn),將CompletionListener放在PreparedListener里面,代碼如下:

mediaPlayer.setDataSource(url);
mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(mOnPreparedListener);
mediaPlayer.setOnErrorListener(mOnErrorListener);

private MediaPlayer.OnPreparedListener mOnPreparedListener = new MediaPlayer.OnPreparedListener( ) {    
@Override    
public void onPrepared(MediaPlayer mp) {        
OnCompletionListener(mOnCompletionListener);   
  }
 };

自我感覺的話應(yīng)該是異步的時(shí)候還沒準(zhǔn)備好就直接進(jìn)行CompletionListener了,上面代碼這樣操作的時(shí)候就相當(dāng)于準(zhǔn)備好了以后才能進(jìn)行播放完成的監(jiān)聽。

因?yàn)橐纛l播放的問題相對(duì)來說開發(fā)的比較少,谷歌的很多都是基礎(chǔ)的播放問題,還是需要自己多多琢磨啊。

前人栽樹后人乘涼,以后就會(huì)少走很多彎路,共勉

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容