Android JNI开发入门之二
来源:互联网 发布:联合国工作 知乎 编辑:程序博客网 时间:2024/06/05 23:48
Android JNI开发入门之二
- 2010十二月08
- 作者:Simon_fu
- 目录: Android, Java, ...
- 评论: 1 条评论
两套不同的API
C++实现HelloWorld共享库
#include <jni.h>#define LOG_TAG "HelloWorld"#include <utils/Log.h> JNIEXPORT jstring JNICALL Java_com_simon_HelloWorld_printJNI(JNIEnv *env, jobject obj){ LOGI("Hello World From libhelloworld.so!"); return env->NewStringUTF("Hello World!");}static const char *classPathName = "com/simon/HelloWorld";static JNINativeMethod methods[] = { {"printJNI", "()Ljava/lang/String;", (void*)Java_com_simon_HelloWorld_printJNI },};static int registerNativeMethods(JNIEnv* env, const char* className, JNINativeMethod* gMethods, int numMethods){ jclass clazz; clazz = env->FindClass(className); if (clazz == NULL) { LOGE("Native registration unable to find class '%s'", className); return JNI_FALSE; } if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) { LOGE("RegisterNatives failed for '%s'", className); return JNI_FALSE; } return JNI_TRUE;}static int registerNatives(JNIEnv* env){ if (!registerNativeMethods(env, classPathName, methods, sizeof(methods) / sizeof(methods[0]))) { return JNI_FALSE; } return JNI_TRUE;}typedef union { JNIEnv* env; void* venv;} UnionJNIEnvToVoid;jint JNI_OnLoad(JavaVM* vm, void* reserved){ UnionJNIEnvToVoid uenv; JNIEnv* env = NULL; LOGI("JNI_OnLoad!"); if (vm->GetEnv((void**)&uenv.venv, JNI_VERSION_1_4) != JNI_OK) { LOGE("ERROR: GetEnv failed"); return -1; } env = uenv.env;; if (registerNatives(env) != JNI_TRUE) { LOGE("ERROR: registerNatives failed"); return -1; } return JNI_VERSION_1_4;}
本例与上文《AndroidJNI开发入门之一》对比有如下几点不同需要注意:
1、C和C++实现共享库调用不同JNIAPI。前面已经提到Android系统JNI为C和C++提供了两套不同的API。请仔细对比NewStringUTF,GetEnv函数,就会发现JNIAPI不同。
2、C++版的helloworld共享库提供了函数映射表。前文《
Android JNI开发入门之一》也已经提到,JNIAPI为了避免丑陋的函数名,提供了方法向Java虚拟机注册函数映射表。这样当Java调用Native接口的时候,Java虚拟机就可以不用根据函数名来决定调用哪个函数了,直接通过查询表格就可以找到需要调用的函数了。
3、我们注意到RegisterNatives第一个参数(C语言接口中是第二个参数)为调用该函数的Java类。这也和标准JNI函数名包含类名(包名和类名)的作用一样——声明那个Java类可以调用这个方法。
4、函数映射表的定义非常的怪异。你可以参考
Android JNI使用的数据结构JNINativeMethod详解和JNI标准手册相关类型的部分。
LOCAL_PATH:= $(call my-dir)include $(CLEAR_VARS)LOCAL_SRC_FILES:=com_simon_Helloworld.cppLOCAL_C_INCLUDES := $(JNI_H_INCLUDE)LOCAL_MODULE := libhelloworldLOCAL_SHARED_LIBRARIES := libutilsLOCAL_PRELINK_MODULE := falseinclude $(BUILD_SHARED_LIBRARY)
JNI的进一步学习
1、我们并没有提到怎样在Native代码中回调Java的函数。
2、每个Native的函数中前两个参数是什么意思?
总结
参考资料:
Android JNI使用的数据结构JNINativeMethod详解
Android JNI实例
JNI Examples for Android
How to add a new module toAndroid
AndroidJNI(实现自己的JNI_OnLoad函数)
Android中JNI编程的那些事儿
Java Native Interface: Programmer’s Guideand Specification
Java Native InterfaceSpecification
- Android JNI开发入门之二
- Android JNI开发入门之二
- Android JNI开发入门之二
- Android JNI开发入门之二
- Android JNI开发入门之二
- Android JNI开发入门之二
- Android JNI开发入门之二
- Android JNI开发入门之二
- Android JNI开发入门之一
- Android JNI开发入门之一
- Android JNI开发入门之二(javah命令的补充)
- Android之JNI开发入门
- Android JNI环境搭建及开发入门
- android ndk开发之二 认识jni
- Android JNI开发入门
- Android JNI开发入门
- Android JNI开发入门
- Android JNI开发入门
- 第一个驱动helloworld module加载i…
- 第一个驱动helloworld module加载i…
- Android JNI开发入门之一
- Android JNI开发入门之一
- Android JNI开发入门之二
- Android JNI开发入门之二
- Android HAL实践(一):Mini6410…
- Android HAL实践(一):Mini6410…
- 解决lib只读的问题
- 解决lib只读的问题
- 在x86的机器上编译使用Andorid
- 在x86的机器上编译使用Andorid
- virtualbox 虚拟机 ubuntu中下添加…
- virtualbox 虚拟机 ubuntu中下添加…