具体的使用方式都在代码里面了。

  • 首先准备一个 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;    }}

更多相关文章

  1. android ksoap2 中把XML(DataSet) 当做参数传递
  2. Android intent.Action 参数值及对应功能介绍
  3. Android的startActivityForResult()与onActivityResult()与setRe
  4. android (java) 网络发送get/post请求参数设置
  5. Android高手进阶教程(十六)---Android中Intent传递对象的两种方
  6. Android上在两个Activity之间传递Bitmap对象
  7. [置顶] Android 调用js,传对象到js里面使用addJavascriptInterfac

随机推荐

  1. Android学习之键盘事件
  2. MyBaseAdapter
  3. Android(安卓)Studio默认产生Fragment
  4. 百度地图API学习笔记(四)
  5. android中有这么些个SystemService,挨个儿
  6. AudioTrack&AudioFlinger
  7. Android模拟强制下线通知功能实例代码
  8. [Android]什么是OOB(Opaque binary blob)
  9. 一分钟解决Shape分割线及分割线圆角框
  10. android沉浸式状态栏和状态栏字体设置工