Camera服务之--JNI部分

这一部分主要在/frameworks/base/core/java/android/hardware/Camera.java和/frameworks/base/core/jni/android_hardware_Camera.cpp中实现的。

在Camera.java中声明了很多native的方法,这些方法都是在android_hardware_Camera.cpp,通过JNI的方式来调用。


1.Camera.java分析

Camera.java主要的功能就是提供一个对Camera操作的java入口,并且定义一些回调接口。

先看一下成员变量:

    private int mNativeContext; // accessed by native methods
    private EventHandler mEventHandler;
    private ShutterCallback mShutterCallback;
    private PictureCallback mRawImageCallback;
    private PictureCallback mJpegCallback;
    private PreviewCallback mPreviewCallback;
    private PictureCallback mPostviewCallback;
    private AutoFocusCallback mAutoFocusCallback;
    private OnZoomChangeListener mZoomListener;
    private ErrorCallback mErrorCallback;

除了mNativeContext都是上一篇文章提到的一些回调接口。这个mNativeContext实际上是给android_hardware_Camera.cpp使用的,在JNI部分会分析到。


再看一下open方法:

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

open是对Camera操作的入口方法,根据cameraID打开前置或后置摄像头。


再看看Camera的构造方法都做了什么:

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);
    }

也很简单,初始化关于回调接口的成员变量,然后调用native_setup(new WeakReference<Camera>(this), cameraId);,把自己和cameraID传进去,在JNI层进行初始化。

完成了以上初始化,就可以对Camera进行各种操作了,比如setPreviewDisplay, startPreview等。


2.android_hardware_Camera.cpp分析

(1)首先来看JNI的注册函数。

int register_android_hardware_Camera(JNIEnv *env)
{
    field fields_to_find[] = {
        { "android/hardware/Camera", "mNativeContext",   "I", &fields.context },
        { "android/view/Surface",    ANDROID_VIEW_SURFACE_JNI_ID, "I", &fields.surface },
        { "android/hardware/Camera$CameraInfo", "facing",   "I", &fields.facing },
        { "android/hardware/Camera$CameraInfo", "orientation",   "I", &fields.orientation },
    };

    if (find_fields(env, fields_to_find, NELEM(fields_to_find)) < 0)
        return -1;

    jclass clazz = env->FindClass("android/hardware/Camera");
    fields.post_event = env->GetStaticMethodID(clazz, "postEventFromNative",
                                               "(Ljava/lang/Object;IIILjava/lang/Object;)V");
    if (fields.post_event == NULL) {
        LOGE("Can't find android/hardware/Camera.postEventFromNative");
        return -1;
    }


    // Register native functions
    return AndroidRuntime::registerNativeMethods(env, "android/hardware/Camera",
                                              camMethods, NELEM(camMethods));
}

这个函数中主要做了两件事:第一,也就是JNI的基本任务,注册JNINativeMethod camMethods[]函数数组,使得java层可以调用。第二, 通过env->GetStaticMethodID获取到java层中postEventFromNative方法的ID,这样就可以将camera service的一些通知信息传递给java层。这也回答了上一篇《Camera服务之--Camera应用部分》的一个疑问,就是camera 色让vice是怎么通知上层应用的,就是通过这个postEventFromNative方法。

(2)android_hardware_Camera_native_setup分析

这个函数是java层向下调用的入口,如果需要对camera进行操作,这个是必须首先调用的。

// 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);
   .......
    sp<JNICameraContext> context = new JNICameraContext(env, weak_this, clazz, camera);
    context->incStrong(thiz);
    camera->setListener(context);

    // save context in opaque field
    env->SetIntField(thiz, fields.context, (int)context.get());
}

首先调用camera service的connect函数,获得一个camera service的对象(代理),然后创建一个JNICameraContext对象,并把service对象保存在其中,最后再把回调接口设置到camera service中。因为JNICameraContext实现了回调接口CameraListener,所以也就是把JNICameraContext设置到camera service中。


(3)其他JNI函数分析

通过JNI注册的其他函数,都是static的函数,这些函数基本上可以总结为两种实现方式:

一个是对camera service的对象(代理)的调用,比如

static void android_hardware_Camera_stopPreview(JNIEnv *env, jobject thiz)
{
    LOGV("stopPreview");
    sp<Camera> c = get_native_camera(env, thiz, NULL);
    if (c == 0) return;

    c->stopPreview();
}

另一个是对JNICameraContext对象的调用,比如:

static void android_hardware_Camera_addCallbackBuffer(JNIEnv *env, jobject thiz, jbyteArray bytes) {
    LOGV("addCallbackBuffer");

    JNICameraContext* context = reinterpret_cast<JNICameraContext*>(env->GetIntField(thiz, fields.context));

    if (context != NULL) {
        context->addCallbackBuffer(env, bytes);
    }
}

(4)JNICameraContext分析

这个类实现了CameraListener接口,也就是实现了camera service的回调接口。这个类的主要作用就是这个,对camera service回调event的一个中转站,将回调event处理后调用java层的回调实现。



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值