转自: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所在线程中执行。
本文讨论了如何在Android开发中避免onPreviewFrame()阻塞UI线程,通过在子线程中开启Camera并设置预览回调。同时探讨了如何在子线程中处理人脸识别等任务以提高性能。
2165

被折叠的 条评论
为什么被折叠?



