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






原创粉丝点击