因为公司可能需要用到自定义照相机和在线播放一些技术,所以就先去了解下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; } } }