Camera APP层分析之对camera framework层封装解析
来源:互联网 发布:linux关闭tomcat报错 编辑:程序博客网 时间:2024/06/07 13:14
Android4.4版本的camera和4.0版本的设计差距还是很大的,4.0版本以前的camera在是camera 主activity中直接调用camera hal层的的接口(如android.hardware.camera.open(), android.hardware.camera.setPreviewDisplay(),android.hardware.camera..startPreview()等)与camera device通信。Android4.4版本camera app对camera device的访问又封装了一次,对camera device的访问必须经过camera manager接口,camera manager接口定义了camera基本操作,这样便于控制和管理camera device。下图为相关类关系图。
1.CameraManager接口:提供的访问camera设备基本的操作,实现类必须调用CameraManager.cameraOpen获取CameraManager.CameraProxy接口对象来控制camera,实现CameraManager接口的类必须拥有一个独立于主线程的线程来实现对camera的操作,CameraManager接口也包装回调函数
2.CameraProxy接口,封装在CameraManager接口之内,接收对camera操作请求,发送消息到camer handle。所有对camera的操作都经由改接口,进行异步处理
3. AndroidCameraManagerImpl类,该类实现了CameraManager接口,与camera framework层接口直接通信,起到camera app 与camera framework对话中介的作用。
4.AndroidCameraProxyImpl类,AndroidCameraManagerImpl内部类,实现CameraManager.CameraProxy接口,CameraProxy已经介绍过了就是控制对camera的访问,AndroidCameraProxyImpl类实现了具体的操作。
5. CameraManagerFactory类,这个类的实现很简单,看到Factory,会想到软件设计中的工厂模式,这里就是封装了创建CameraManager对象的细节
6. CameraHolder类,看名字就可以看出这个类的基本功能了,就用来保存camera实力对象的,用在不同的module之间快速切换
以上是我们对camera app对camera framework层接口封装了的介绍。下面我们来看camera初始化过程。时序图如下
Step 1. CameraHolder.instance()
public static synchronized CameraHolder instance() { if (sHolder == null) { sHolder = new CameraHolder(); } return sHolder;}
这个函数定义在Camera2/src/com/android/cameraCameraHolder.java中
这个函数很简单就是创建一个CameraHolder实例,并保存在变量sHolder中,如果是第一次调用sHolder肯定是null,接着new 一个CameraHolder实例对象,这样的设计在android中经常见到,一种单例设计模式。现在我们来看看CameraHolder都做了些什么private CameraHolder() { HandlerThread ht = new HandlerThread("CameraHolder"); ht.start(); mHandler = new MyHandler(ht.getLooper()); if (mMockCameraInfo != null) { mNumberOfCameras = mMockCameraInfo.length; mInfo = mMockCameraInfo; } else { mNumberOfCameras = android.hardware.Camera.getNumberOfCameras(); mInfo = new CameraInfo[mNumberOfCameras]; for (int i = 0; i < mNumberOfCameras; i++) { mInfo[i] = new CameraInfo(); android.hardware.Camera.getCameraInfo(i, mInfo[i]); } } // get the first (smallest) back and first front camera id for (int i = 0; i < mNumberOfCameras; i++) { if (mBackCameraId == -1 && mInfo[i].facing == CameraInfo.CAMERA_FACING_BACK) { mBackCameraId = i; } else if (mFrontCameraId == -1 && mInfo[i].facing == CameraInfo.CAMERA_FACING_FRONT) { mFrontCameraId = i; } } }
CameraHolder对象,首先创建了一个HandlerThread线程,独立于main thread,启动该线程。接着创建自己MyHandler,用于在HandlerThread中处理自己的事物。最后初始化mInfo变量,保存camerainfo。
Step 2. CameraHolder.open()
public synchronized CameraProxy open( Handler handler, int cameraId, CameraManager.CameraOpenErrorCallback cb) { … Assert(!mCameraOpened); if (mCameraDevice != null && mCameraId != cameraId) { mCameraDevice.release(); mCameraDevice = null; mCameraId = -1; } if (mCameraDevice == null) { Log.v(TAG, "open camera " + cameraId); if (mMockCameraInfo == null) { mCameraDevice = CameraManagerFactory .getAndroidCameraManager().cameraOpen(handler, cameraId, cb); } else { if (mMockCamera != null) { mCameraDevice = mMockCamera[cameraId]; } else { Log.e(TAG, "MockCameraInfo found, but no MockCamera provided."); mCameraDevice = null; } } if (mCameraDevice == null) { Log.e(TAG, "fail to connect Camera:" + mCameraId + ", aborting."); return null; } mCameraId = cameraId; mParameters = mCameraDevice.getCamera().getParameters(); } else { if (!mCameraDevice.reconnect(handler, cb)) { Log.e(TAG, "fail to reconnect Camera:" + mCameraId + ", aborting."); return null; } mCameraDevice.setParameters(mParameters); } mCameraOpened = true; mHandler.removeMessages(RELEASE_CAMERA); mKeepBeforeTime = 0; return mCameraDevice; }
该函数首先判断当前camera是否已经打开,如果已经打开。需要先调用mCameraDevice.release()释放掉,在重新调用CameraManagerFactory获取mCameraDevice实例对象。
Step 3. CameraManagerFactory. getAndroidCameraManager ()
Public static synchronized CameraManager getAndroidCameraManager() { if (sAndroidCameraManager == null) { sAndroidCameraManager = new AndroidCameraManagerImpl(); } return sAndroidCameraManager; }
该函数定义在Camera2/src/com/android/camera/ CameraManagerFactory.java文件中,代码很简单new AndroidCameraManagerImpl对象返回给调用者。
AndroidCameraManagerImpl() { HandlerThread ht = new HandlerThread("Camera Handler Thread"); ht.start(); mCameraHandler = new CameraHandler(ht.getLooper()); }
从这个类的初始化中可以看到,该对象内部创建了自己的HandlerThread,并启动,这个很重要,后期的client对camera的操作都在这个线程中完成的。后面遇到具体操作我们在分析。
Step 4. AndroidCameraManagerImpl. cameraOpen ()
public CameraManager.CameraProxy cameraOpen( Handler handler, int cameraId, CameraOpenErrorCallback callback) { mCameraHandler.obtainMessage(OPEN_CAMERA, cameraId, 0, CameraOpenErrorCallbackForward.getNewInstance( handler, callback)).sendToTarget(); mCameraHandler.waitDone(); if (mCamera != null) { return new AndroidCameraProxyImpl(); } else { return null; } }
这个函数定义在Camera2/src/com/android/camera/AndroidCameraManagerImpl.java文件中
函数首先通过mCameraHandler获取OPEN_CAMERA消息并发送给mCameraHandler处理,mCameraHandler处理是在AndroidCameraManagerImpl初始化的时候创建的HandlerThread线程中处理的。发送完消息之后调用mCameraHandler.waitDone()阻塞当前主线程,等待framework层的camera开启。Step 5. android.hardware.Camera.open
在上一步发送了OPEN_CAMERA,指令给mCameraHandler。mCameraHandler收到这个指令之后调用framework层camera接口android.hardware.Camera.open开启cameradevice。当这一步完成之后,主线程会被唤醒,继续执行下一步。
Step 6 AndroidCameraProxyImpl
当主线程再次被唤醒的时候,判断camera device是否成功开启,如果成功开启,将创建AndroidCameraProxyImpl实例,后续对camera所有的操作的都要经过AndroidCameraProxyImpl统一发送到mCameraHandler进行处理。
- Camera APP层分析之对camera framework层封装解析
- android Camera framework层解析
- Camera从上层APP到底层分析
- Camera从上层APP到底层分析
- Android Camera从App层到framework层到HAL层的初始化过程
- Camera显示之Framework层设置显示窗口
- Camera显示之Framework层设置显示窗口
- 二、Camera显示之Framework层设置显示窗口
- camera GC0339 Rawdata hal层分析
- camera GC0339 Rawdata hal层分析
- Camera HAL层代码分析1
- Camera HAL层代码分析2
- Camera CullingMask层处理
- Android framework camera分析
- Android7.0 App层实现多Camera同时打开
- MTK Android Camera 运行流程-app到底层
- unity 切换camera 渲染层
- Android5.0 MTk Camera HAL层代码分析
- Tomcat是如何响应静态资源的?
- 深度学习_循环神经网络RNN与LSTM
- 在 CentOS 下安装使用 XWiki
- JSP页面的执行过程
- node中,已经在app中设置了跨域的问题,但是用jq的ajax请求时仍然报跨域错误
- Camera APP层分析之对camera framework层封装解析
- redis面试题总结
- 集合框架
- 猜拳游戏
- czmq编译错误zargs_t *
- 解决webgl使用canvas.toDataURL()没有内容的问题
- 文章标题
- Ubuntu17.10如何安装网易云音乐并解决无法打开
- 回溯走迷宫