在Android平台初学JNI踩过的几个小坑(续)
来源:互联网 发布:辽宁省人工智能协会 编辑:程序博客网 时间:2024/04/29 16:35
接上一篇博客:在Android平台初学JNI踩过的几个小坑
上一篇记录了初学JNI时踩得坑,终于是在JNI层成功调用了Android 的Java API 弹出了Toast, JNI的编写格式使用了传统的方式,这一篇记录一下动态注册JNI函数的过程。
直接在代码上注释含义。
只改动了native-lib.c的代码,其它代码没有改动:
#include <jni.h>#include "MLog.h"#define TAG "NativeActivity"// 这个是实际执行业务逻辑的函数,业务逻辑和上一篇提到的没有差别,只是函数名称可以随意写JNIEXPORT void JNICALLnative_showToast(JNIEnv* env, jobject instance,jstring str) { jclass Toast = (*env)->FindClass(env,"android/widget/Toast"); jmethodID makeText = (*env)->GetStaticMethodID(env,Toast, "makeText", "(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;"); jstring msg = (*env)->NewStringUTF(env, "太神奇了哈哈"); jobject Toast2 = (*env)->CallStaticObjectMethod(env,Toast, makeText, instance, msg); jmethodID show = (*env)->GetMethodID(env,Toast, "show", "()V"); (*env)->CallVoidMethod(env,Toast2, show); Android_LOG_I(TAG, "showToast:");}// 这个数组里面定义了Java中声明的native方法和JNI层方法的映射,可以声明多个函数映射,这里只写了一个static const JNINativeMethod methodTable[] ={
// 大括号{}里面是JNINativeMethod结构体类型的数据,依次是{"Java native方法名", "Java native方法签名", "JNI对应的函数的函数指针"} {"showToast", "(Ljava/lang/String;)V", (void*)native_showToast}};// 关联Java层和JNI层方法的逻辑,主要由jint RegisterNatives(jclass clazz, const JNINativeMethod* methods,jint nMethods)函数实现jint register_com_yolo_jnidemo_MainActivity(JNIEnv *env){ jclass MainActivity = (*env)->FindClass(env,"com/yolo/jnidemo/MainActivity");
// 注册函数的参数(JNIEnv类型指针,Java层方法所在类,函数映射列表,函数个数) return (*env)->RegisterNatives(env, MainActivity, methodTable, 1); }
// 该函数在System.loadLibrary()方法加载so库后回调JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved){ JNIEnv *env = NULL; // 通过JavaVM来获取JNIEnv实例,将获取结果传给env变量 if((*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_4) != JNI_OK) { Android_LOG_E(TAG, "get JNIEnv failed."); return -1; } // 获取JNIEnv成功后就可以调用注册函数进行Java层和JNI层关联,关联成功后我们在Java层调用native方法就会执行JNI层对应函数的逻辑 register_com_yolo_jnidemo_MainActivity(env); Android_LOG_D(TAG, "jni onload."); return JNI_VERSION_1_4;}
// 该函数在JNI库被卸载时回调,可以执行一些清理逻辑JNIEXPORT void JNI_OnUnload(JavaVM* vm, void* reserved){ Android_LOG_D(TAG, "jni onunload.");}
以上函数的书写顺序是由于C代码需要先声明后使用,因此一些后执行的逻辑写在了前面,实际的执行顺序是:
JNI_OnLoad -> register_com_yolo_jnidemo_MainActivity -> methodTable -> native_showToast
在这里很希望一些同学发现问题后能指出来,将不正确的知识点完善起来,共同进步。
阅读全文
0 0
- 在Android平台初学JNI踩过的几个小坑(续)
- 在Android平台初学JNI踩过的几个小坑
- android平台的jni
- Android平台AES对称加密踩过的坑
- 初学C的几个小程序之一
- android平台的jni,添加
- Android 初学JNI知识
- 初学Android JNI
- 初学android的小菜鸟
- 那些年在Android之路上踩过的坑
- JAVA初学的几个小错误(命令行)
- 初学c++时容易遇到的几个小问题
- 初学51单片,写的几个小程序
- 小轩在Linux中趟过的坑
- hive踩过的小坑
- 写JNI时要注意的几个小问题
- 兼容Android平台的JNI调用
- 深入了解android平台的jni(一)
- Spring Boot学习笔记-错误处理及自定义
- QT问题系列(3)
- linux基本命令及操作8(系统日志)
- idr 映射总结
- 百度2016研发工程师笔试题(六)
- 在Android平台初学JNI踩过的几个小坑(续)
- 【搜索入门专题练习1】hdu1241+hdu1312 C+D【DFS】
- 笔记本正版风扇与盗版风扇 ADDA区别
- Programming In Scala笔记-第二十八章、XML相关
- TCP拥塞控制
- Anaconda环境下OpenCV的安装方法
- CSU
- 2350: 彩排(二进制记录个数)
- QLabel 用法总结