SurfaceView

SurfaceView

完成单位时间内大量的界面变化

视频播放器、游戏等。


surfaceview用的是双缓冲机制:内部有两个子线程

A、B两个子线程交替解码图像、前台显示,并发执行。两个线程可以快速的切换,以提高效率。


视频播放器跟音频播放器差不多,视频播放器需要指定视频的播放位置,即SurfaceView。

得到显示界面内容的holder方法:SurfaceHolder holer = sv.getHolder();

在prepare之前还要执行:mediaPlayer.setDisplay(holder);方法。


holder的回调方法:surfaceCreated-->surfaceChanged-->surfaceDestroyed

播放视频的时候按home键最小化,再切换到播放界面时,播放界面holder会黑屏。原因是:当播放界面可见时,系统创建holder,当播放界面不可见时,系统就自动把SurfaceView的holder给回收掉。当界面再可见时,系统又重新创建了新的holder。


为了解决这个问题,可以给holder增加回调方法:

holder.addCallback(new Callback(){

这里面实现了接口里面的三个方法。

});

当视频最小化时,暂停视频的播放,当播放界面可见时,继续播放。

重写surfaceDestroyed方法:

if(mediaPlayer != null && mediaPlayer.isPlaying(){

private int positon = mediaPlayer.getCurrentPosition();//获得当前的播放位置

mediaPlayer.stop();

mediaPlayer.release();

mediaPlayer = null;

}


重写surfaceCreated方法:

if(position>0){

代码跟播放的代码一样,不过需要添加开始播放的位置:

mediaPlayer.seekTo(position);

}


低版本模拟器上运行还要加上下面参数。模拟器不自己维护双缓冲区,而是等待多媒体播放框架主动的推送数据。

holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);


在线视频播放器跟在线音乐播放器一样,都只要在播放前判断一下是否是网络视频即可。


可拖拽的进度条SeekBar

seekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener(){

这里面也需要实现接口的三个方法:

onStopTrackingTouch、onStartTrackingTouch、onProgressChanged

});


得到文件的总时长方法:mediaPlayer.getDuration();

设置进度条的最大值的方法:seekBar.setMax();

更新进度条时需要定义一个计时器Timer、以及计时器任务TimerTask。要执行的任务写在TimerTask中的run()方法中,如:

seekBar.setProgress(mediaPlayer.getCurrentPosition());

然后再用计时器开启计时器任务

timer.schedule(task, delay, period);

task就是要执行的任务;delay是延迟多久开始执行;period是刷新周期,即多久更新一次进度条。

取消刷新:timer.cancel();task.cancel();

得到当前进度用seekBar.getProgress();

设置播放到当前拖拽的位置:mediaPlayer.seekTo();


你可能感兴趣的:(SurfaceView)