转自:https://blog.youkuaiyun.com/qq_31939617/article/details/86360335
https://www.huaweicloud.com/zhishi/arc-13664997.html
注意,onPreviewFrame()方法跟Camera.open()是运行于同一个线程,所以为了防止onPreviewFrame()会阻塞UI线程,将Camera.open()放置在子线程中运行。
1,void setPreviewCallback (Camera.PreviewCallback cb)
一旦使用此方法注册预览回调接口,onPreviewFrame()方法会一直被调用,直到camera preview销毁
注意,onPreviewFrame()方法跟Camera.open()是运行于同一个线程,所以为了防止onPreviewFrame()会阻塞UI线程,将Camera.open()放置在子线程中运行。
我们知道,Camera的打开是耗时的,我们可以放在子线程里。那么我们既然要在onPreviewFrame(byte[] data, Camera camera)回调中进行人脸识别比对等等,还要自己再开子线程,我们想这个回调就是子线程回调的要怎么办?
假如我们在子线程打开的Camera,那么onPreviewFrame(byte[] data, Camera camera)就会在子线程?恐怕想得美。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
public class HandlerThreadActivity2 extends Activity implements Callback { static final String TAG = "jason"; Camera mCamera; SurfaceView surfaceView; SurfaceHolder surfaceHolder; byte[] buffers; HandlerThread mHandlerThread = new HandlerThread("my_handlerthread"); Handler subHandler; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_handler_thread2); surfaceView = (SurfaceView) findViewById(R.id.surface_view); surfaceHolder = surfaceView.getHolder(); surfaceHolder.addCallback(this); } class MyTask implements Runnable, PreviewCallback{ @Override public void run() { //打开相机 //子线程中打开 Log.d("jason", Thread.currentThread().getName() + "_open"); mCamera = Camera.open(CameraInfo.CAMERA_FACING_BACK); try { mCamera.setPreviewDisplay(surfaceHolder); } catch (IOException e) { e.printStackTrace(); } Camera.Parameters parameters = mCamera.getParameters(); //设置相机参数 parameters.setPreviewSize(480, 320); //预览画面宽高 mCamera.setParameters(parameters); //获取预览图像数据 buffers = new byte[480 * 320 * 4]; mCamera.addCallbackBuffer(buffers); mCamera.setPreviewCallbackWithBuffer(this); mCamera.startPreview(); Log.d(TAG, Thread.currentThread().getName()+ "_run"); } @Override public void onPreviewFrame(byte[] data, Camera camera) { if(mCamera != null){ mCamera.addCallbackBuffer(buffers); //编码 Log.d(TAG, Thread.currentThread().getName()+ "_onPreviewFrame"); } } } @Override public void surfaceCreated(SurfaceHolder holder) { mHandlerThread.start(); subHandler = new Handler(mHandlerThread.getLooper()); subHandler.post(new MyTask()); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { } } |
Camera维护了一个EventHandler。 Handler.handleMessage的执行一定在它的Looper所在线程中。 onPreviewFrame的执行在Camera所持有的Looper所在线程中执行。