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进行处理。