Mediaplayer中onCompletion的異常調(diào)用問題解決

onCompletion()正常情況下是在一首歌曲播放完之后會得到調(diào)用,但是現(xiàn)在發(fā)現(xiàn)有時候會異常調(diào)用,找了一些資料,發(fā)現(xiàn)如果在mediaplayer setDataSource之前就調(diào)用了類似 getDuration()的方法就會出錯,onCompletion()就會被調(diào)用。
那么為什么會出現(xiàn)在在setDataSource之前就調(diào)用了類似getDuration()的方法呢?我的項目中是這樣的情況:
我自定義了一個View顯示播放的信息(就是最下面的那個)


QQ圖片20161217200457.png

下面的進度信息是通過新開了一個線程,不斷地通過getDuration()來獲取歌曲進度的,但是當我們快速點擊list上面的歌曲的時候,歌曲在切換的瞬間(即當mediaplayer reset之后,setDataSource之前),那個線程來不及反應(yīng)還沒停止繼續(xù)在getDuration(),所以會有很大的幾率出現(xiàn)onCompletion()被異常調(diào)用的情況。
那么怎么解決?我們onCompletion()本身要完成的是切換下一首歌曲同時更新下面的自定義View信息,但是現(xiàn)在onCompletion()被異常調(diào)用,就會出現(xiàn)我明明點的是第一首歌,但是自定義View上顯示的卻是下一首歌的信息,這個就很尷尬了。
解決方法是:onCompletion()里面進行判斷,如果當前狀態(tài)是播放或者暫停情況下,onCompletion()被調(diào)用,就不更新View!因為我點擊list上的歌曲之前我的mediaplayer只有2種可能性,要么播放started,要么paused,其他狀態(tài)點擊list上的歌曲不會出現(xiàn)異常調(diào)用onCompletion()的可能,而我們正常情況下一首歌播放完切換下一首歌的時候mediaplayer的狀態(tài)不會是started或者paused,那么現(xiàn)在問題又來了,怎么獲取當前mediaplayer狀態(tài),mediaplayer本身是沒有這個方法的,只有isPlaying判斷是否在播放,對于我們呢沒有用,所以我們自己需要加一個狀態(tài)碼,在每次mediaplayer狀態(tài)切換的時候?qū)@個狀態(tài)碼進行修改

public int MEDIA_PLAYER_MODE=0; 
//播放模式:0——Idle  1——Initialized  3——Prepared   4——Started 5--Paused  6——Stopped

@Override
    public void onCompletion(MediaPlayer mp)
    {

        Log.d("sendError","MusicService.onCompletion()"+"mp.isPlaying()?"+mp.isPlaying());

        //歌曲在播放的時候調(diào)用到了這個方法,說明出了問題!不進行后續(xù)處理!
        if(!mp.isPlaying()&&(MEDIA_PLAYER_MODE==4||MEDIA_PLAYER_MODE==5))
        {
            switch (PLAY_MODE)
            {  
                //列表循環(huán)模式
                case 0:
                    //處理本身邏輯
                    if(curPos==songs.size()-1)  //到底了重新開始播放
                    {
                        curPos=0;
                    }
                    _toNextSong();
                    _sendToNextMessage();
                    break;
                //順序播放模式  
                case 1:
                    //處理本身邏輯
                    if(curPos==songs.size()-1)  //到底了就停止播放
                    {
                        _realeaseMediaPlayer();
                        return;
                    }
                    _toNextSong();  //切換下一首歌
                    _sendToNextMessage();   //更新View
                    break;
                case 2:
                    break;
                case 3:
                    break;
                default:
                    break;
            }
        }
    }

這里的Idle Initialized 都是mnediaplayer的生命周期,這里附上mediaplayer生命周期圖:


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

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

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