一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第8天,点击查看活动详情。
前言
在Android系统中在一个窗口下所有View是共用同一个Surface且Surface保存在ViewRootImpl中。然而SurfaceView比较特殊,它和其他View不同点就是独立使用一个Surface。因此SurfaceView渲染效率上更搞笑,因为更新时不需要通知ViewRootImpl去执行刷新工作。
源码分析
SurfaceView源码分析主要关注Surface、SurfaceHolder、SurfaceView三个类。
Surface
Surface实现了Parcelable接口序列化对象以便于进程数据传递,该对象主要用于存储处理屏幕显示缓冲区的数据。Surface相当于是图像缓冲区的句柄,内部HwuiContext对应硬件层图像画布数据。
public class Surface implements Parcelable {
private static final String TAG = "Surface";
private static native long nativeCreateFromSurfaceTexture(SurfaceTexture surfaceTexture)
throws OutOfResourcesException;
private static native long nativeCreateFromSurfaceControl(long surfaceControlNativeObject);
private static native long nativeGetFromSurfaceControl(long surfaceObject,
long surfaceControlNativeObject);
private static native long nativeLockCanvas(long nativeObject, Canvas canvas, Rect dirty)
throws OutOfResourcesException;
private static native void nativeUnlockCanvasAndPost(long nativeObject, Canvas canvas);
......
}
在Surface中也包含Canvas对象(CompatibleCanvas)作为内部类。主要作用是兼容Android各种分辨率屏幕处理不同屏幕分辨率图像数据。
private final class CompatibleCanvas extends Canvas {
@Override
public void setMatrix(Matrix matrix) {
if (mCompatibleMatrix == null || mOrigMatrix == null || mOrigMatrix.equals(matrix)) {
// don't scale the matrix if it's not compatibility mode, or
// the matrix was obtained from getMatrix.
super.setMatrix(matrix);
} else {
Matrix m = new Matrix(mCompatibleMatrix);
m.preConcat(matrix);
super.setMatrix(m);
}
}
@SuppressWarnings("deprecation")
@Override
public void getMatrix(Matrix m) {
super.getMatrix(m);
if (mOrigMatrix == null) {
mOrigMatrix = new Matrix();
}
mOrigMatrix.set(m);
}
}
其次在Surface中还有两个比较重要方法lockCanvas和unlockCanvasAndPost。实际上就是SurfaceHolder接口方法对接调用的方法(SurfaceHolder接口由BaseSurfaceHolder抽象类来实现)其最终还是有JNI层具体实现。
SurfaceHolder
SurfaceHolder接口是作为Controller角色存在。主要用来控制Surface大小、格式、监听Surface变化。其关键接口是Callback,实现该接口可以控制绘制动画线程,也就是开发SurfaceView熟悉的三个回调方法。在获取实例化的SurfaceHolder同时能够获取到底层实际与底层交互的Surface对象从而能够和底层图像进行交互操作。
- surfaceCreated(SurfaceHolder holder)
- surfaceChanged(SurfaceHolder holder,int format,int width,int height)
- surfaceDestroyed(SurfaceHolder holder)
SurfaceView
SurfaceView作为特殊的View继承MockView。实现绘制主要在Surface和SurfaceHolder上而非SurfaceView。
- 主要作用是在视图屏幕上嵌入独立的图像绘制视图。
SurfaceView实例化后Surface并不会马上创建,因为是异步创建。因此需要使用CallBack接口来获取到Surface。
public class SurfaceView extends MockView {
public SurfaceHolder getHolder() {
return mSurfaceHolder;
}
private SurfaceHolder mSurfaceHolder = new SurfaceHolder() {
......
}
......
}