(一)本地方法处理java数组
1.数组分两种
(1)基本类型的数组
(2)对象数组(Object[])数组
2.一个通用取数组长度函数:
GetArrayLength(jarray array);
3.处理基本类型数组
(1)Get<TYPE>ArrayElements(<TYPE>Array arr,jboolean*isCopied);//取得数组
Release<TYPE>ArrayElements;//释放数组
(2)Get<TYPE>ArrayRegion(<TYPE>Array arr,jsize start,jsizelen,<TYPE>* buffer);//开辟内存,拷贝数组
(3)Set<TYPE>ArrayRegion(<TYPE>Array arr,jsize start, jsizelen, const <TYPE>* buffer);//将指定范围的元素用C/C++数组中的元
素赋值
(4)<TYPE>Array New<TYPE>Array(jsize sz)//创建java数组
4.处理对象数组类型
(1)Get/SetObjectArrayElement();//不需释放资源
(二)全局引用/局部引用/弱全局引用
从java虚拟机创建的对象传到本地C/C++代码时会产生引用。根据
Java的垃圾回收机制,只要有引用存在就不会触发该引用指向的Java对
象的垃圾回收
1.局部引用
基本通过JNI返回的引用都为局部引用
例如使用NewObject就会返回创建出来的实力的局部引用。
局部引用只在该native函数中有效,所有在该函数总产生的局部引用,
都会在函数返回的时候自动释放。也可以通过DeleteLocalRef函数手动
释放
2.全局引用
(1)其可以跨越当前线程,在多个native函数中有效,需要手动释放该引用。
(2)其非JNI自动创建
NewGlobalRef();//创建
ReleaseGlobalRef();//释放
3.弱全局引用
(1)可以跨越多线程有效,特点在于此种引用不会阻止垃圾回收器回
收这个引用所指向的对象
(2)函数
NewWeakGlobalRef();//创建
ReleaseWeakGlobalRef();//释放
3.函数
jboolean IsSameObject(jobject obj1,job);//把NULL传入要比较的对
象中,就能判断弱全局引用所指向的java对象是否被回收
(三)缓存jfieldID/jmethodID
1.缓存方式
(1)在用的时候缓存
在native code中使用static局部变量来保存已经查询过的id
(2)在java类初始化时缓存
在java第一次加载这个类的时候首先调用本地代码初始化所有的
jfieldID/jmethodID,当然,这些jfieldID/jmethodID是定义在C/C++全局
分享到:
相关推荐
要访问Java对象,需要先将其转换为特定的JNI类型,如`jclass`(表示类)、`jmethodID`(表示方法ID)和`jfieldID`(表示字段ID)。例如,要调用Java对象的方法,可以使用`CallVoidMethod()`函数,传入`JNIEnv *env`...
- **缓存ID**:为了提高性能,可以缓存`jfieldID`和`jmethodID`,但需要注意线程安全问题,可以使用静态初始化器或锁来保护这些ID。 讲师王泽佑的JNI系列教程涵盖了这些核心概念,并通过实例演示了如何实际应用。...
3. **JNI函数指针**:JNI提供了一套函数指针类型,如`jmethodID`、`jfieldID`等,它们分别用于表示Java方法和字段的ID,这些ID在调用本地方法时需要用到。 4. **数据类型映射**:JNI将Java数据类型映射到C/C++的...
当从Java传入一个数组到C代码中时,可以使用以下方式处理: ```c int sum = 0, i; int len = (*env)->GetArrayLength(env, array); jint* element = (*env)->GetIntArrayElements(env, array, 0); for (i = 0; i ; ...
Java 中创建一个对应的 Native 类,声明一个接受该结构体指针作为参数的本地方法: ```java public class DiskInfoJava { private native void getDiskInfo(DiskInfo diskInfo); static { System.loadLibrary(...
3. **方法 ID 和域 ID**:`jmethodID`和`jfieldID`分别用于表示Java方法和字段的标识,它们是C语言中的指针类型,用于在本地代码中调用Java方法或访问字段。 4. **值类型**:`jvalue`是一个联合类型,可以存储所有...
为了在 C/C++ 中访问 Java 类的属性和方法,需要先获取相应的 `jfieldID` 和 `jmethodID`。这些 ID 通过 JNI 提供的函数获取: - **`GetFieldID(jclass clazz, const char *name, const char *sign);`**: 获取实例...
`jobject`代表Java对象,`jclass`表示类,`jmethodID`和`jfieldID`分别对应方法ID和字段ID,这些都是JNI调用Java方法时所需的标识。 当我们调用`callNative`方法时,JNI会把控制权转移到C++代码,执行完毕后再返回...
JNI是一个接口,它允许Java应用程序调用本地(非Java)代码,同时也允许本地代码调用Java方法。在Android中,NDK(Native Development Kit)提供了一个工具集,用于在原生C/C++环境中编译和运行代码。 在Java层,...
5. **字段和方法ID**:在本地代码中访问Java对象的字段或调用方法需要使用字段ID(`jfieldID`)和方法ID(`jmethodID`)。这些ID可以通过`GetFieldID`和`GetMethodID`函数获得,需要类的`jclass`引用和相应的字段名...
JNI提供了丰富的API,使得Java代码可以轻松地调用本地方法,同时本地方法也可以调用Java的方法和访问Java对象。 首先,我们需要创建一个Java类,这个类将包含一个本地方法声明。本地方法使用`native`关键字标记,...
Java对象在本地代码中通常被表示为`jobject`指针,这是一个通用类型,可以指向任何Java对象,包括类实例、数组、接口实例等。但是,由于Java对象的内存管理是自动的,而C/C++中没有垃圾回收机制,所以在C代码中直接...
在Android NDK开发中,Java和C/C++之间的交互是至关重要的,它允许我们利用C/C++的高效性能处理计算密集型任务,同时保持Java的易用性和平台兼容性。以下是关于这一主题的详细解释: 1. **定义和加载 native 方法**...
这种方式避免了多线程并发时的缓存问题,且提高了性能,因为查找操作只在类加载时执行一次。 总结来说,Android JNI中的字段和方法ID缓存是优化性能的关键步骤。使用时缓存简单,但可能在多线程环境下导致额外开销...
Java层的回调接口通常定义为异步,通过`Handler`的`handleMessage`方法处理回调。 示例Java代码: ```java public class TestJNI { public interface CallBack { void onCallback(int value); } // 注册回调...
5. **JNI指针**:JNI使用几种特殊类型的指针来引用Java对象,如`JNIEnv*`指针代表Java环境,`jobject`表示Java对象,`jclass`表示Java类,`jmethodID`和`jfieldID`分别表示方法ID和字段ID。 6. **数据类型转换**:...
在Java代码中,你需要使用`System.loadLibrary("libraryName")`加载生成的.so库,然后通过`native`关键字声明本地方法,这样就可以在Java代码中调用C/C++实现的函数了。 总之,NDK开发中C语言调用Java方法和获取...
- `jmethodID`:用于标识Java类的方法。 - `jfieldID`:用于标识Java类的字段。 这两个ID都是不透明的数据结构,开发者不需要了解其内部细节。 ##### 4. 值类型 `jvalue`是一种联合体类型,用于传递Java值到本地...