JNI调用java接口函数
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
- 点赞
- 收藏
- 关注作者
评论(0)