被這個The surface has been released錯誤糾纏了2天,今天終於解決了,現在整理下思路。
自己練手做了個項目,使用SurfaceView播放視頻。但是測試時發現如果播放時來電話,通話結束後不能自動播放。經過百度,重寫了onPush和onResume方法,測試通過。但是此時如果按HOME鍵,再切換回主程序時,視頻不能自動播放,並且會報The surface has been released這個錯誤。
各位大神的見解基本都差不多,說是 在surfaceHolder還沒準備好的時候,就調用了MediaPlayer的start()方法。並建議將mediaPlayer.setDisplay(surfaceHolder)放在surfaceCreated中,自己嘗試了下,問題並沒有解決。最後經過多方查閱,才知道surface的創建在onResume方法之後,但是我確是在onResume方法之中調用的play方法,因此必然會報這個錯。
好的,既然知道了問題,那麼答案也就在眼前了,我的解決思路是,不採用onPush和onResume這兩個方法來判斷應用是否在前臺。而是用surfaceHolder.addCallback(new SurfaceCallback());來監聽,通過surfaceCreated和surfaceDestroyed這兩個方法來判斷。當然,這樣只是解決了HOME鍵返回的問題,當來電話時是不會調用這兩個方法的(但是onPush和onResume方法卻會調用,很奇怪,不知道爲什麼),所以接下來要做的是對來電進行監聽。
//獲取電話服務
manager = (TelephonyManager) this.getSystemService(TELEPHONY_SERVICE);
// 手動註冊對PhoneStateListener中的listen_call_state狀態進行監聽
manager.listen(new MyPhoneStateListener(), PhoneStateListener.LISTEN_CALL_STATE);
創建MyPhoneStateListener類,由於OFFHOOK是主動掛斷電話,API中沒有被動掛斷這一狀態,所以只能定義一個isCalling用來判斷被動掛斷這種情況。
private class MyPhoneStateListener extends PhoneStateListener{
@Override
public void onCallStateChanged(int state, String incomingNumber) {
//需要考慮主動掛斷和被動掛斷兩種情況
switch (state){
//空閒
case TelephonyManager.CALL_STATE_IDLE:
System.out.println("電話處於空閒狀態......");
//判斷通話是否爲對方掛斷
if (isCalling) {
if (position > 0 && path != null) {
play(position);
position = 0;
}
}
isCalling = false;
break;
//來電
case TelephonyManager.CALL_STATE_RINGING:
System.out.println("電話呼入......電話號碼是:"+incomingNumber);
if (mediaPlayer.isPlaying()) {
position = mediaPlayer.getCurrentPosition();
mediaPlayer.stop();
}
isCalling = true;
break;
//主動掛斷
case TelephonyManager.CALL_STATE_OFFHOOK:
System.out.println("電話掛斷......");
if (position > 0 && path != null) {
play(position);
position = 0;
}
break;
}
super.onCallStateChanged(state, incomingNumber);
}
}
最後,千萬別忘了註冊權限
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
現在。OK,大功告成,無論是電話進來,還是按HOME鍵返回,當程序切換回來的時候,視頻都可以繼續播放了!
最後,如果我的經驗對你有用,不要吝嗇你寶貴的支持,在下面回覆下吧!