實習入職第九天:Attempt to call getDuration without a valid mediaplayer
這種問題,最殘忍了,
他的錯誤一般發生在設定 :MediaPlayer的播放進度條裡面,而發生這種錯誤的原因是這樣的:
attempt to callgetDuration without a valid mediaplayer
error (-38, 0)
查了好長時間,引起這個異常的原因有幾個:
一是如果mediaPlayer物件為null,那麼在執行這個方法的時候會報異常
二是在mediaPlayer物件為不可用狀態的時候也會報這個錯
為此,我查了一下書,順便學習了一下MediaPlayer的生命週期,書中是這樣解釋的:
1) 當一個MediaPlayer物件被新建或呼叫reset()方法之後,它處於空閒狀態,在呼叫release方法之後,才會處於結束狀態。
2) 一個新建的MediaPlayer物件在呼叫getCurrenProgress()、getDuration、getVideoHeight()、getVideoWith()、setAudioStreamType(int)、setLooping(boolean)、setVolume(float,float)、pause()、start()、stop()、seekTo()、prepare()、prepareAsync()方法時,不會觸發OnErrorListenerError()事件,但是MediaPlayer物件如果呼叫了reset()方法後,再使用這些方法則會觸發OnErrorListenerError()事件。
所以,當你呼叫了reset()方法後,又呼叫getDuration()時,就會報異常。
1如果你重置了mediaPlayer,或者釋放了,或者mediaPlayer為null,
2但是你再run方法裡面引用了這個變數,而且顯示進度條的時候,一般都是定時任務,它會post這個run,
3這種情況下:如果你的mediaPlayer發生了 1種描述的各種情況,那麼就會從handler裡面丟擲異常,而且這個異常還不好捕捉,
4.最開始想的是把handler裡面的run方法stop掉,呼叫removeCallBack(runnable),但是試過了沒有用,為什麼呢,我覺得是執行緒同步的問題,時間沒有搞好,run和stop錯開了,不是原子操作,那怎麼辦,我使用的方法是 :單利模式中有個雙重判定的做法,能夠避免這種情況,
5.解決辦法就是在run方法裡面加雙層判定flag變數,只有為真的時候才回去做這件事
就解決了這種問題,
但是他的缺點也是:不一定保證任何時候他們都 成功,因為有可能還是會錯開,這個時候還是會發生異常,雖然這種概率很低,
然後可以休息幾秒再次判斷比較,三層,無論你加多少層,還是無法避免:這種可能出現的情況