我一直在尝试在观察者回调中进行绘制,当我尝试锁定画布时,我总是得到一个空返回。SurfaceHolder 似乎还可以。我添加了一个 SurfaceHolder 回调,它在游戏早期被调用。
这是我的观察者更新方法:
// implements Observer
public void update(Observable observable, Object data) {
Canvas c = null;
Log.i(TAG, "Surface Observer of CbSurfaceState thread: "
+ Thread.currentThread().getName());
try {
synchronized(mCbHolder) {
c = mCbHolder.lockCanvas(null);
if(c == null) {
Log.i(TAG, "lockCanvas returned null");
} else {
doDraw(c);
}
}
} finally {
// do this in a finally so that if an exception is thrown
// during the above, we don't leave the Surface in an
// inconsistent state
if (c != null) {
mCbHolder.unlockCanvasAndPost(c);
}
}
}
这是我在初始化中第一次使用它的地方:
public void initCbSurfaceView(Context context) {
mContext = context;
// register our interest in hearing about changes to our surface
mCbHolder = getHolder();
Log.i(TAG,"got holder");
mCbHolder.addCallback(cbSurfaceHolderCallback);
Log.i(TAG,"added callback");
// initially in preview mode
mCbHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
// previewHolder.(SurfaceHolder); Don't know how to replace, but it
// won't work without the above.
...
mCbSurfaceState.addObserver(this);
Log.i(TAG, "Creation of CbSurfaceState thread: "
+ Thread.currentThread().getName());
}
我什至在创建表面时再次设置它,(我最近添加它只是为了确定)
SurfaceHolder.Callback cbSurfaceHolderCallback = new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
Log.i(TAG, "In surfaceCreated callback");
mCbHolder = holder;
}
...
};
这是一些日志。我打印了线程,因为起初它是从异步线程开始的,我设法避免了这种情况。:
02-24 20:31:10.380: I/CbSurfaceView(4013): In surfaceCreated callback
02-24 20:31:10.380: I/CbSurfaceView(4013): SurfaceChanged 854X404
02-24 20:31:10.380: I/CbSurfaceView(4013): initPreview width 854 height 404
...
02-24 20:31:25.974: I/CbTouchListener(4013): onTouch Down x 665.7714 y 194.92023
02-24 20:31:25.974: I/CbSurfaceView(4013): Surface Observer of CbSurfaceState thread: main
02-24 20:31:25.981: I/CbSurfaceView(4013): lockCanvas returned null
02-24 20:31:26.005: I/CbSurfaceView(4013): Surface Observer of CbSurfaceState thread: main
02-24 20:31:26.075: I/CbSurfaceView(4013): lockCanvas returned null
我到底做错了什么?我的 doDraw 一直在工作,直到它开始尝试绘制位图。然后我想从lockCanvas中检查null。
我在这里找到了答案How to draw an overlay on a surfaceView used by Camera on Android? 看来你不能在预览上画画。我得到了一个关于 PUSH_BUFFER 类型表面的异常,所以我将它重置为 NORMAL,这样它就不会抱怨了。我无法锁定预览的表面,如果它不是 NORMAL,它会抛出异常。显然你不能动态地改变表面类型。这可能是它被弃用的原因,但是除非您将其设置为 PUSH_BUFFER,否则相机预览将不起作用。我将在顶部添加另一个非 Surface 视图,用于绘制和渲染拍摄的照片。
感谢您的关注,我希望这对某人有所帮助。