Android JNI cpp文件创建 java bean 对象并返回
16lz
2021-01-23
具体的使用方式都在代码里面了。
- 首先准备一个 Student 和 Person
class Student { var name: String? = null; var age: Int? = 0;}class Person { constructor(){ Log.e("Person", "无参构造器"); } constructor(age: Int) { Log.e("Person", "age = $age"); }}
- MainActivity中调用 JNI 层的代码
class MainActivity : AppCompatActivity() { companion object { private const val TAG: String = "MainActivity"; init { System.loadLibrary("native-lib") } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) } fun onClick(view: View) { // JNI创建并返回 student 对象 val student = useObjectFromJNI(); Log.d(TAG, student.name); // JNI 通过构造器创建 Person 对象 useConstructorINI(); } private external fun stringFromJNI(): String private external fun useObjectFromJNI(): Student; private external fun useConstructorINI();}
- JNI 实现如下
- 创建 Student
// ------头文件#include #include #include #define TAG "ld"#define log_debug(...) __android_log_print(ANDROID_LOG_DEBUG,TAG,__VA_ARGS__)#define log_info(...) __android_log_print(ANDROID_LOG_INFO,TAG,__VA_ARGS__)// 创建并返回studentextern "C"JNIEXPORT jobject JNICALLJava_com_lu_jni_MainActivity_useObjectFromJNI(JNIEnv *env, jobject thiz) { // 使用 Java 类 // 创建 Student 对象 // student 文件路径 const char *student_path = "com/lu/jni/Student"; // 获取 class jclass student_class = env->FindClass(student_path); // 创建对象 AllocObject局部引用 分配新 Java 对象而不调用该对象的任何构造函数。返回该对象的引用。 // NewGlobalRef是全局引用 jobject student = env->AllocObject(student_class); // 获取 jmethodID (GetMethodID:第一个参数:jclass 第二个参数:要调用的方法名 // 第三个参数 "(Ljava/lang/String;)V" 传入 java/lang/String 参数 返回Void // V -> void (L ;)引用类型写法 如果是Int 可以写成 (I)V 也可以写成 "(Ljava/lang/Integer;)V" jmethodID studentMethodId = env->GetMethodID(student_class, "setName", "(Ljava/lang/String;)V"); jstring value = env->NewStringUTF("张三"); // 调用 student 的 setName 方法 env->CallVoidMethod(student, studentMethodId, value); // 通过构造方法创建 person 传入student const char *person_path = "com/lu/jni/Person"; jclass person = env->FindClass(person_path); return student;}
- 创建 Person
// 下面是创建 Person 并传入构造器参数jclass person;extern "C"JNIEXPORT void JNICALLJava_com_lu_jni_MainActivity_useConstructorINI(JNIEnv *env, jobject thiz) { if (person == NULL) { log_debug("进入创建方法"); const char *person_path = "com/lu/jni/Person"; jclass tmpClass = env->FindClass(person_path); // NewGlobalRef 创建一个新的全局的引用,只能使用DeleteGlobalRef()函数销毁这个全局引用 person = static_cast<jclass>(env->NewGlobalRef(tmpClass)); } // 代表构造器创建 const char *constructor = "" ; // 获取 jmethodID ()V 代表无参数的构造器 //jmethodID methodId = env->GetMethodID(person, constructor, "()V"); //env->NewObject(person, methodId); // 如果是有参数的构造器 Person中传入int类型参数 jmethodID methodId1 = env->GetMethodID(person, constructor, "(I)V"); jobject personObj = env->NewObject(person, methodId1, 100);}
- 使用结束后回收一下 即使是在栈中创建出栈会自动弹出,但是也建议手动删除
// 使用完记得主动回收 如果是通过 new 来创建的对象是在堆内存中 一定要回收掉void deleteClass(JNIEnv *env) { if (person != NULL) { // 释放全局对象 env->DeleteGlobalRef(person); person = NULL; }}
更多相关文章
- android ksoap2 中把XML(DataSet) 当做参数传递
- Android intent.Action 参数值及对应功能介绍
- Android的startActivityForResult()与onActivityResult()与setRe
- android (java) 网络发送get/post请求参数设置
- Android高手进阶教程(十六)---Android中Intent传递对象的两种方
- Android上在两个Activity之间传递Bitmap对象
- [置顶] Android 调用js,传对象到js里面使用addJavascriptInterfac