JNI调用java接口函数

举报
产品人卫朋 发表于 2021/10/29 23:10:49 2021/10/29
【摘要】 vim frameworks/base/core/jni/android_hardware_Camera.cpp fields.post_event = GetStaticMethodIDOrDie(env, clazz, "postEventFromNative", //java层函数名    &nbsp...

vim frameworks/base/core/jni/android_hardware_Camera.cpp
fields.post_event = GetStaticMethodIDOrDie(env, clazz, "postEventFromNative", //java层函数名
                                           "(Ljava/lang/Object;IIILjava/lang/Object;)V");
该函数在client被调用,它会调用java层函数,将数据传至java接口:
void JNICameraContext::postData(int32_t msgType, const sp<IMemory>& dataPtr,
                                camera_frame_metadata_t *metadata)
{
    // VM pointer will be NULL if object is released
    Mutex::Autolock _l(mLock);
    JNIEnv *env = AndroidRuntime::getJNIEnv();
    if (mCameraJObjectWeak == NULL) {
        ALOGW("callback on dead camera object");
        return;
    }
    int32_t dataMsgType = msgType & ~CAMERA_MSG_PREVIEW_METADATA;
    // return data based on callback type
    switch (dataMsgType) {
        case CAMERA_MSG_VIDEO_FRAME:
            // should never happen
            break;
        // For backward-compatibility purpose, if there is no callback
        // buffer for raw image, the callback returns null.
        case CAMERA_MSG_RAW_IMAGE:
            ALOGV("rawCallback");
            if (mRawImageCallbackBuffers.isEmpty()) {
                env->CallStaticVoidMethod(mCameraJClass, fields.post_event,
                        mCameraJObjectWeak, dataMsgType, 0, 0, NULL);
            } else {
                copyAndPost(env, dataPtr, dataMsgType);
            }
            break;
        /* MM-MC-SomcAddForSoMCAP-00+{ */
        case CAMERA_MSG_OBJECT_TRACKING:
        {
            ALOGV("object tracking callback");
            if (dataPtr == NULL) {
                ALOGE("%s: mem is null", __FUNCTION__);
                env->CallStaticVoidMethod(mCameraJClass, fields.post_event,
                        mCameraJObjectWeak, dataMsgType, 0, 0, NULL);
                return;
            }
            ssize_t offset;
            size_t size;
            sp<IMemoryHeap> heap;
            heap = dataPtr->getMemory(&offset, &size);
            ALOGV("object tracking callback:mem off=%d, size=%d", (int) offset, (int) size);
            camera_ex_msg_object_tracking_t *cb = (camera_ex_msg_object_tracking_t *) heap->base();
            jobject object_tracking_result;
    
            if (cb != NULL) {
                object_tracking_result = convertObjectTrackingResult(env, cb);
            } else {
                ALOGE("object tracking callback: heap is null");
                env->CallStaticVoidMethod(mCameraJClass, fields.post_event,
                        mCameraJObjectWeak, CAMERA_MSG_OBJECT_TRACKING, 0, 0, NULL);
                return;
            }
            env->CallStaticVoidMethod(mCameraJClass, fields.post_event,
                    mCameraJObjectWeak, CAMERA_MSG_OBJECT_TRACKING, 0, 0, object_tracking_result);   //使用android VM接口函数实现对java函数的调用
        }
        break;
       /* MM-MC-SomcAddForSoMCAP-00+} */
        // There is no data.
        case 0:
            break;
        default:
            ALOGV("dataCallback(%d, %p)", dataMsgType, dataPtr.get());
            copyAndPost(env, dataPtr, dataMsgType);
            break;
    }
    // post frame metadata to Java
    if (metadata && (msgType & CAMERA_MSG_PREVIEW_METADATA)) {
        postMetadata(env, CAMERA_MSG_PREVIEW_METADATA, metadata);
    }
}
   下面简要分析convertObjectTrackingResult,进一步理解jni如何调用java类和方法:
    convertObjectTrackingResult函数需要调用的java层的类和方法:
    vim frameworks/base/core/java/android/hardware/Camera.java
public static class ObjectTrackingResult {
    public Rect mRectOfTrackedObject;
    public boolean mIsLost;
}
    vim frameworks/base/graphics/java/android/graphics/Rect.java
public final class Rect implements Parcelable {
    public int left;
    public int top;
    public int right;
    public int bottom;
    …...
  public void set(int left, int top, int right, int bottom) {
      this.left = left;
      this.top = top;
      this.right = right;
      this.bottom = bottom;
  }
   …...
}
   jni获取java层jclass ID(类ID)、jmethod ID(方法函数ID)、jfield ID(变量ID):
   vim frameworks/base/core/jni/android_hardware_Camera.cpp
bool JNICameraContext::setUpObjectTracking(JNIEnv* env)
{
    Mutex::Autolock _l(mLock);
    objecttracking_callback_cookie *c = &objectTrackingCookie;
    ……
    // Get jclass ID.
    jclass class_results = env->FindClass( //获取java ObjectTrackingResult类
            "android/hardware/Camera$ObjectTrackingResult");
    jclass class_rect = env->FindClass( //获取java Rect类
            "android/graphics/Rect");
    c->results_clazz = (jclass) env->NewGlobalRef(class_results);
    c->rect_clazz = (jclass) env->NewGlobalRef(class_rect);
    // Get jmethod ID.
    c->rect_set_mid = env->GetMethodID(c->rect_clazz, "set", "(IIII)V");  //获取set方法
    // Get jfield ID.  //获取变量mRectOfTrackedObject
    c->mRectOfTrackedObject_fid = env->GetFieldID(c->results_clazz, "mRectOfTrackedObject",
            "Landroid/graphics/Rect;");  //获取变量mIsLost
    c->mIsLost_fid = env->GetFieldID(c->results_clazz, "mIsLost", "Z");
    env->DeleteLocalRef(class_results);
    env->DeleteLocalRef(class_rect);
    return true;
}
   使用java层函数,即convertObjectTrackingResult:
jobject JNICameraContext::convertObjectTrackingResult(JNIEnv *env, camera_ex_msg_object_tracking_t* cb)
{
    ……
    objecttracking_callback_cookie *c = &objectTrackingCookie;
    if (NULL == c->results_clazz) {
        ALOGD("%s: c->results_clazz is NULL;", __FUNCTION__ );
        return NULL;
    } //获取使用ObjectTrackingResult类
    jobject callbackObject = env->AllocObject(c->results_clazz);  // create ObjectTrackingResult class
    if (NULL == callbackObject) {
        ALOGW("%s: object is NULL;", __FUNCTION__ );
        return NULL;
    }
    // Create android.graphics.Rect object.  //获取使用Rect类
    jobject rect_obj = env->AllocObject(c->rect_clazz);
    if (NULL == rect_obj) {
        ALOGW("%s Error rect_obj = %p", __FUNCTION__, rect_obj);
        return NULL;
    }
    // Set rect data to android.graphics.Rect object.
    env->CallVoidMethod(rect_obj, c->rect_set_mid,  //使用类Rect的set方法
            cb->rect[0], cb->rect[1], cb->rect[2], cb->rect[3]);
    // Set android.graphics.Rect object to ObjectTrackingResult.Rect.
    env->SetObjectField(callbackObject, c->mRectOfTrackedObject_fid, rect_obj);
    env->DeleteLocalRef(rect_obj); //将数据传给java mRectOfTrackedObject变量
    // Set isLost boolean to ObjectTrackingResult.boolean.
    env->SetBooleanField(callbackObject, c->mIsLost_fid, cb->isLost);
    if(mObjectObjectTrackingResult != NULL) { //将isloat信息传给java mIsLost变量
        env->DeleteGlobalRef(mObjectObjectTrackingResult);
        mObjectObjectTrackingResult = NULL;
    }
    mObjectObjectTrackingResult = env->NewGlobalRef(callbackObject); //结果返回
    env->DeleteLocalRef(callbackObject);
    return mObjectObjectTrackingResult;
}

文章来源: blog.csdn.net,作者:简一商业,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/liwei16611/article/details/51315890

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。