Camera APP层分析之对camera framework层封装解析

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






  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值