因为公司可能需要用到自定义照相机和在线播放一些技术,所以就先去了解下SurfaceView,在刚开始学习Android的时候也了解过这个类,感觉太高大上,做游戏啊视频啊都用它,简直就是神器,所以有一种畏惧,之前做的GIf也是用SurfaceView,因为时间关系所以没有来分享自己学习的心得,
首先SurfaceView是带双缓冲机制的,什么是双缓冲.?
双缓冲我是这样理解的:比如你去馆子吃饭,老板点了菜,老板会先上几个菜,这是时候这个几个菜就相当于是一个线程去缓存好了,给你上来吃,当你吃的时候另一个线程就接着你吃的部分缓存,然后当你把第一份吃完,第二份线程就不去加载了,第一份线程就接着第二份线程的尾部接着加载,这时候就接着吃第二份,就这样轮流,形成一个双缓冲.[大牛求指点].
好了之前的其实也只是为了我们方便理解SurfaceView的底层的一些WorkFlow,下面我分享我看源码所学习到的东西.首先SurviceView的源码很简单,他就是继承了MockView,
而MockVIew仅仅是画了几文字,所以你在as预览中可以看见SurfaceView,(仅仅就这个作用吧).MockView继承TextView,而TextView算是Android经常开发用到的控件,这个控件的源码有9k+行.之前也看过大牛的分析,详情网上可以搜到TextView的一些渲染分析.重点是讲SurfaceHoder.
SurfaceHolder//一个帮助编辑屏幕像素等接口.
这个接口中用的比较多的是CallBack,分别为:surfaceCreated()、surfaceChanged()、surfaceDestory();
首先surfaceCreated方法是Holder已经和View已经初始化完毕后就会回调该方法,一般用于做一些初始化操作.surfaceChanged方法屏幕格式大小改变的时候回调.surfaceDestory()被销毁,一般用于释放一些内存资源.
还有两个个人认为比较中要的API,LockCanvas();源码也介绍"Start editing the pixels in the surface".当然有Lock就有UnLock,这两个方法做游戏或者绘制自定义控件也是经常用到的.由于大部分细节都是C实现的,所以java层我就只看到这些.
下面是结合了Camera做的一个Demo:
Activity的代码如下:
package com.softtanck.lenovoservice;
import android.app.Activity;
import android.graphics.Camera;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import java.io.IOException;
/**
* @author : Tanck
* @Description : TODO
* @date 8/11/2015
*/
public class BackCameraTester extends Activity implements SurfaceHolder.Callback {
private SurfaceView surfaceView;
private SurfaceHolder holder;
private android.hardware.Camera camera;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_backcamera);
surfaceView = (SurfaceView) findViewById(R.id.sv);
holder = surfaceView.getHolder();//获取hoder,SurfaceView被创建的时候Holder也跟着创建了.
holder.addCallback(this); // 添加监听
}
/**
* 创建后
*
* @param holder
*/
@Override
public void surfaceCreated(SurfaceHolder holder) {
this.holder = holder; // update Holder
new openCarmera().execute("");//执行异步
}
/**
* 改变后
*
* @param holder
* @param format
* @param width
* @param height
*/
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
/**
* 被销毁后
*
* @param holder
*/
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (camera != null) {
camera.stopPreview();
camera.release();
camera = null;
}
}
public class openCarmera extends AsyncTask<String, Void, Boolean> {
@Override
protected Boolean doInBackground(String... params) {
try {
camera = android.hardware.Camera.open();//打开摄像机获取IO.
camera.setPreviewDisplay(holder);//设置显示屏幕
//the angle that the picture will be rotated clockwise. Valid values are 0, 90, 180, and 270. The starting position is 0 (landscape).
camera.setDisplayOrientation(90);// 默认是0,为水平.
camera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
}