Android_Camera(1)

        我固执的喜欢着Android_Camera,希望有一天自己能作Camera_Driver相关的东西。下面在我能力范围内,我会介绍下我对Camera的学习心得。主要通过讲解preview的过程来分析camera的数据流向

        从Camera的AP层开始分析。首先在Camera 应用启动之后,最先启动的是Camera的预览线程。在Camera.java@/packages/apps/Camera的onCreate()函数中,会开启预览线程。调用startPreview()---->call---->mCameraDevice.startPreview()。然后看下面的一张图。

         


        下面这张图描述camera = Camera::connect(cameraId)的调用过程。

         Android_Camera(1)_第1张图片



-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

总结一下上述过程:


       

       

        startPreview();//Camera.java@ packages/apps/camera的onCreate函数中
                -
                -
                -
                -
         ensureCameraDevice();
                -
                -
                -
                -
       该函数通过调确保在java层有一个可用的mCameraDevice实例。
       mCameraDevice = android.hardware.Camera.open(cameraId);//该函函数的实现如下

       public static Camera open(int cameraId) {
                 return new Camera(cameraId);
      }

       Camera(int cameraId) {
            mShutterCallback = null;
            mRawImageCallback = null;
            mJpegCallback = null;
            mPreviewCallback = null;
            mPostviewCallback = null;
            mZoomListener = null;

        Looper looper;
        if ((looper = Looper.myLooper()) != null) {
            mEventHandler = new EventHandler(this, looper);
        } else if ((looper = Looper.getMainLooper()) != null) {
            mEventHandler = new EventHandler(this, looper);
        } else {
            mEventHandler = null;
        }

        native_setup(new WeakReference<Camera>(this), cameraId);
    }
        注意到目前为止我们已经有一个java层的实例,mCameraDevice即android.hardware.Camera类型。在mCameraDevice实例化的过程中,我们调用了native_setup()函数。该函数也是一个native函数。native_setup函数的作用后面会做解释。
        -
        -
        -
        -

//在Camera.java@ packages/apps/camera的 startPreview函数中,接着被调用到,在//android.hardware.Camera。java中 startPreview()是一个native函数。

    mCameraDevice.startPreview();
        -
        -
        -
        -
代码跟到这里,native_setup的作用也不得不说了。先看下native_setup的代码:
    
// connect to camera service
static void android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz,
        jobject weak_this, jint cameraId)
{
        sp<Camera> camera = Camera::connect(cameraId);

        if (camera == NULL) {
            jniThrowException(env, "java/lang/RuntimeException",
                          "Fail to connect to camera service");
                return;
        }

        // make sure camera hardware is alive
        if (camera->getStatus() != NO_ERROR) {
            jniThrowException(env, "java/lang/RuntimeException", "Camera initialization failed");
            return;
        }

        jclass clazz = env->GetObjectClass(thiz);
        if (clazz == NULL) {
        jniThrowException(env, "java/lang/RuntimeException", "Can't find android/hardware/Camera");
        return;
    }

        // We use a weak reference so the Camera object can be garbage collected.
        // The reference is only used as a proxy for callbacks.
        //可以看到Camera::connect(cameraId)返回的camera被保存在了 context中
        sp<JNICameraContext> context = new JNICameraContext(env, weak_this, clazz, camera);
        context->incStrong(thiz);
        camera->setListener(context);

    // save context in opaque field,这个 context被保存了,当我们需要使用这个camera的时候,
   //可以通过getIntField把保存的context取出来。
   //在函数get_native_camera()@android_hardware_camera.cpp中就是这么做的。
        env->SetIntField(thiz, fields.context, (int)context.get());
}    

sp<Camera> Camera::connect(int cameraId)
{
        LOGV("connect");
        sp<Camera> c = new Camera();
        const sp<ICameraService>& cs = getCameraService();
        if (cs != 0) {
          //CameraService::connect返回的CameraService::client给了c->mCamera
        c->mCamera = cs->connect(c, cameraId);
    }
    if (c->mCamera != 0) {
        c->mCamera->asBinder()->linkToDeath(c);
        c->mStatus = NO_ERROR;
    } else {
        c.clear();
    }
    return c;
}
    
        首先该函数通过Camera::connect(cameraId);----》CameraService::connect()-----》在CameraService::connect函数中会new一个CameraService::client,这个Client是CameraService中对客户端请求做出相应的真正worker。然后这个new 出来的CameraService::Client会被返回给客户端的Camera client,随后Camera通过这个sp<ICamera> mCamera对象调用函数就如同直接调用CameraService::Client类的函数。
        到目前为止总结下。在Camera框架中,我们有了一个android.hardware.camera在java层的实例,与之对应的变量是mCameraDevice,然后我们在native层有了一个可以和CameraService进行交互的mCamera。被保存在 JNICameraContext  context中,当客户端Camera Client发出请求需要CameraService提供服务的时候,可以使用get_native_camera()来获得一个mCamera,通过这个mCamera就可以获得想要的服务。

         分析到这里,再看前面mCameraDevice.startPreview();中调用的native层的startPreview()函数在JNI层具体的实现如下:

       static void android_hardware_Camera_startPreview(JNIEnv *env, jobject thiz)
     {
         LOGV("startPreview");
         sp<Camera> camera = get_native_camera(env, thiz, NULL);
         if (camera == 0) return;
         if (camera->startPreview() != NO_ERROR) {
               jniThrowException(env, "java/lang/RuntimeException", "startPreview failed");
               return;
         }
     }

    其startPreview()的具体实现肯定是有CameraService::Client::startPreview()函数来完成的。   




---------------------------------------------文章写的很乱,希望看的人耐心点,本人菜鸟能力有限,还希望与大家一起进步。


 




你可能感兴趣的:(java,android,jni,null,reference,initialization)