一、概述
視頻的播放有兩種方法:
- VideoView 安卓封裝好的,直接用
- SurfaceView 這個比較靈活,是VideoView的父類,當中可以放視頻,也可以放圖片,最最重要的是,它可以在子線程中更新UI(還有一個是ProgressBar,Android中只有這兩個控件比較刁)
繼承關係如下:
二、SurfaceView
surfaceView是一個比較厲害的控件,可以在子線程裏面更新UI ,並且它可以在單位時間大量渲染各種各樣的畫面。並且,其內部是雙緩衝的機制:
- 線程0 : 顯示界面 — 後臺計算 —-顯示UI
- 線程1 : 後臺計算 —顯示UI — 後臺計算
但是,使用中一定要注意:SurfaceView容易產生空指針異常,放在Activity的onCreate()中。原因是 surfaceView這個 控件非常的消耗資源, 所以android並不是以上來就渲染這個控件,而是當界面可見的時候纔去渲染這個控件, 如果當界面還不可見,就直接去拿surfaceView的畫布,就會拋出空指針的異常。爲了避免上面的問題,可以用SurfaceView的方法回調來解決這個問題
/*
* 這裏用接口的回調,把surfaceview的加載寫到了onCreate方法中,避免了在onCreate方法中空指針異常的發生
* */
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SurfaceView sv =(SurfaceView) findViewById(R.id.sv);
//得到一個sharedpreferences
final SharedPreferences sp = getSharedPreferences("oppo", 0);
//1.得到控制器
SurfaceHolder holder = sv.getHolder();
//2.註冊回調監聽
holder.addCallback(new Callback() {
private MediaPlayer mediaPlayer;
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
int position = mediaPlayer.getCurrentPosition();
sp.edit().putInt("position", position).commit();
mediaPlayer.stop();
mediaPlayer.release();
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
mediaPlayer = new MediaPlayer();
//2.設置路徑
mediaPlayer.setDataSource("/mnt/sdcard/oppo.3gp");
//3.準備
mediaPlayer.prepare();
//4.指定顯示畫面的surfaceview
mediaPlayer.setDisplay(holder);
//5.開始搞
mediaPlayer.seekTo(sp.getInt("position", 0));
mediaPlayer.start();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
});
}
三、VideoView
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//1.先拿到控件
VideoView vv = (VideoView) findViewById(R.id.vv);
//2.拿到控制器
MediaController controller = new MediaController(this);
//3.設置播放的數據源
vv.setVideoPath("/mnt/sdcard/oppo.3gp");
//4.互相綁定
vv.setMediaController(controller);
controller.setAnchorView(vv);
vv.start();
}