Android JNI学习笔记(二)-动态注册native函数
来源:互联网 发布:中原农险数据脱敏 编辑:程序博客网 时间:2024/06/07 23:57
1.前言
在很久之前的一篇Android 开发艺术探索的笔记当中,学习了简单的jni开发流程,但是那会的步骤极其繁琐复杂,而且生成的头文件函数太长,那么,有没有方法能解决呢,让开发过程变得简单易懂。当然是有的,那就是今天的主角。JNI_OnLoad函数。顺便说一下,现在as对 jni开发的支持是越来越好了。
2. 首先声明native函数
现在,我在activity里声明了一个native函数。
public native String getStringFromC();
然后我们build一下,为啥要build呢,这个马上就说的。
3. 创建并编写 .h头文件
创建jni目录,并且右键->new c++class,会生出相应的.h 和.cpp 文件,我们需要稍微修改下.h 文件。
#ifndef NDK_CORE_H#define NDK_CORE_H#define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))#include <jni.h>#include <stdlib.h>__BEGIN_DECLSJNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved);JNIEXPORT void JNICALL JNI_OnUnload(JavaVM* vm, void* reserved);__END_DECLS#endif //TEXT_HELLO_H
代码说明如下:
- 我们定义了一个宏NELEM,后面会用到
- 我们用JNIEXPORT和JNICALL关键字,告诉虚拟机,这是jni函数,
4. 编写cpp文件
代码如下:
jstring returnString(JNIEnv *env,jobject jobj){ char* str = "I come from C++"; return env->NewStringUTF(str);}static JNINativeMethod gMethods[] = { {"getStringFromC","()Ljava/lang/String;",(void *)returnString }};JNIEXPORT int JNICALL JNI_OnLoad(JavaVM *vm,void *reserved) { JNIEnv *env; if (vm->GetEnv((void **) &env,JNI_VERSION_1_6) != JNI_OK){ return JNI_ERR; } jclass javaClass = env->FindClass("com/example/hello_jni/MainActivity"); if (javaClass == NULL){ return JNI_ERR; } if (env->RegisterNatives(javaClass,gMethods,NELEM(gMethods)) < 0) { return JNI_ERR; } return JNI_VERSION_1_6;}
先看JNI_OnLoad方法,这是注册native函数的地方。
- 首先判断jni版本是不是JNI_VERSION_1_6
- FindClass方法找到我们对应生命native函数的类,返回一个jclass
- RegisterNatives 注册native函数,我这里用这个三个参数的方法,第一个表示对应jclass,第二个表示JNINativeMethod的数组,第三个,这个就是我们先前命名的宏,
就这样,我们就注册了native函数了。接下来我们看下gMethods。
5. JNINativeMethod数组
这个数组里存放着这样的元素。
{"getStringFromC","()Ljava/lang/String;",(void *)returnString }
- 第一个参数对应的native方法名
- 第二个参数对应 native方法的描述,我们通过javap -s class文件路径来获取。
- 第三个参数对应的是我嗯c++代码里对应的实现
最后就是android.mk 和 application.mk的编写以及gradle的配置,最后编译,这里就不多说了,相关的内容下篇说明。现在给出文件内容。
android.mk
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := hello-jniLOCAL_C_INCLUDES += $(LOCAL_PATH)LOCAL_SRC_FILES := hello.cppinclude $(BUILD_SHARED_LIBRARY)
application.mk
APP_ABI := armeabi x86APP_PLATFORM := android-14APP_STL := stlport_staticAPP_OPTIM := debug
gradle 配置
最后就会生出so文件了。(会自动打包进apk里)
4 0
- Android JNI学习笔记(二)-动态注册native函数
- Android JNI学习笔记(二)-动态注册native函数
- Android JNI学习之动态注册native函数
- Android Studio Jni开发(三)Native方法动态注册
- android 动态注册Jni函数
- Android 动态注册JNI函数
- Android 动态注册JNI函数
- Android平台的jni---注册native函数
- [Android]JNI动态注册Java函数教程
- Android开发值JNI函数动态注册
- 动态注册native函数
- 动态注册jni函数
- Android JNI动态注册Native 方法(实现IDA中改名)
- 深入了解android平台的jni---注册native函数
- 深入了解android平台的jni---注册native函数
- 深入了解android平台的jni---注册native函数
- 深入了解android平台的jni---注册native函数
- 深入了解android平台的jni---注册native函数
- 7.Spring学习笔记_Bean的作用域(by尚硅谷_佟刚)
- shiro整合cas多次验证或者重复重定向问题
- 项目管理过程组
- JavaFX常用样式
- android 通过socket连接服务器与客户端
- Android JNI学习笔记(二)-动态注册native函数
- hihocoder1104(Dfs预处理+树形DP)
- 欢迎使用CSDN-markdown编辑器
- opencv鼠标操作
- ASP文件操作(FSO)详解
- JSONObject.toBean 报java.lang.ClassCastException: java.lang.Class cannot be cast to **
- 10.uboot的源码目录分析
- Leedcode
- Spring Boot+JPA+Mysql+ThymeLeaf快速构建CURD系统(二)搭建SpringBoot工程