您的位置:首页 > 编程语言 > Java开发

JNI调用java接口函数

2016-05-04 16:17 363 查看
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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: