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();