在学习Android Framework源码时,发现部分类中声明了这个变量:
private int mPtr; // used by native code
那么native层是怎么使用这个变量的呢?
以Framework中的MessageQueue为例,它的Native模块源码为/frameworks/base/core/jni/android_os_MessageQueue.cpp
查看其中的代码,可以发现这几个调用:
// Java 层的MessageQueue构造函数中,会调用Native中的这个初始化函数
static void android_os_MessageQueue_nativeInit(JNIEnv* env, jobject obj) {
// 在Native中,创建了一个NativeMessageQueue对象
NativeMessageQueue* nativeMessageQueue = new NativeMessageQueue();
if (! nativeMessageQueue) {
jniThrowRuntimeException(env, "Unable to allocate native queue");
return;
}
// 调用set方法,把创建的Natvie对象传递进去
android_os_MessageQueue_setNativeMessageQueue(env, obj, nativeMessageQueue);
}
// set方法
static void android_os_MessageQueue_setNativeMessageQueue(JNIEnv* env, jobject messageQueueObj,
NativeMessageQueue* nativeMessageQueue) {
// 把native中的对象地址,赋值给Java层mPtr
env->SetIntField(messageQueueObj, gMessageQueueClassInfo.mPtr,
reinterpret_cast<jint>(nativeMessageQueue));
}
// get方法
static NativeMessageQueue* android_os_MessageQueue_getNativeMessageQueue(JNIEnv* env,
jobject messageQueueObj) {
// 取到Java中的mPtr值
jint intPtr = env->GetIntField(messageQueueObj, gMessageQueueClassInfo.mPtr);
// 由于之前是把native对象地址放进去,这次再次通过reinterpret_cast把地址转换回native对象引用
return reinterpret_cast<NativeMessageQueue*>(intPtr);
}
参考上面注释,可以发现

本文探讨了在Java中如何通过JNI保存Native对象引用,并以一个Demo为例,展示了从生成头文件、编写C++ Native代码到在Java层调用的过程。在Android Framework源码中,这种技术被用来保存Native层生成对象的引用,以便后续方法调用。随着系统从32位转向64位,使用long类型替换int类型以避免数据范围不足的问题。

403

被折叠的 条评论
为什么被折叠?



