SurfaceView因為獨特的雙緩衝機制,在android應用中十分普遍,視訊播放器、攝像機預覽等都會用到,如果在兩個Fragment或者一個Fragment和Activity同時使用都會造成無法正常顯示。即使設定前面的SurfaceView為不可見也會在少部分機型上依然存在該問題。後來發現原因是SurfaceView是在Windows層顯示的,僅僅用View層的方法並不能控制Surface的生命週期。
解決辦法:在需要播放視訊的位置外層巢狀一個Layout,這裡我用的Framelayout,在釋放的時候使用removeAllViews直接釋放SurfaceView和他的Surface物件,下面程式碼:
/**
* 釋放資源
*/
private void release() {
if (mSurfaceView != null && mSurfaceView.getHolder() != null && mSurfaceView.getHolder().getSurface() != null) {
mSurfaceView.getHolder().getSurface().release();
if (mSurfaceHolder != null && mEquipmentVideoCallBack != null) {
mSurfaceHolder.removeCallback(mEquipmentVideoCallBack);
mSurfaceHolder = null;
}
}
parentLayout.removeAllViews();
}
需要注意的是,只要介面不在前臺或者失去焦點的時候都需要釋放一次,還有每次重新播放前也需要釋放一次,重新進入準備狀態。
//第1:顯示個隱藏的時候
@Override
public void onHiddenChanged(boolean hidden) {
super.onHiddenChanged(hidden);
release();
}
//第2:從新獲取焦點到前臺
@Override
public void onResume() {
super.onResume();
release();
}
//第3:在類似視訊播放器功能的時候一個視訊播放完也需要釋放