【JNI方法命名规则】http://book.51cto.com/art/201305/395887.htm
2.4.2 JNI方法命名规则
Log系统中,JNI实现方法与Java声明方法是不同的。例如,Java层声明的Native方法名是isLoggable,而其对应的JNI实现方法的方法名却是android_util_Log_isLoggable。可见,除了数据类型有对应关系外,方法名也有对应关系。
JNI 接口指针是JNI实现方法的第一个参数,其类型是JNIEnv。第二个参数因本地方法是静态还是非静态而有所不同。非静态本地方法的第二个参数是对Java对象的引用,而静态本地方法的第二个参数是对其 Java 类的引用。其余的参数都对应于Java 方法的参数。
JNI规范里提供了JNI实现方法的命名规则,方法名由以下几部分串接而成:
Java_前缀
全限定的类名
下划线(_)分隔符
增加第一参数JNIEnv* env
增加第二个参数jobject
其他参数按类型映射
返回值按类型映射
继续以Log系统为例讲解。Java部分方法声明如下:
- public static native boolean isLoggable(String tag, int level);
- static jboolean android_util_Log_isLoggable(JNIEnv* env, jobject clazz,jstring tag, jint level){……}
注意 Android在框架层采用函数注册的方式,建立Java层声明方法与JNI层实现方法之间的对应关系,可以不遵守上述命名规则。
//------------------------------------------------------------------------------------------------------------
http://blog.csdn.net/pandarick/article/details/7611668
转自
http://mysuperbaby.iteye.com/blog/915425
个人认为下面这篇转载的文章写的很清晰很不错. 注意Android平台上的JNI机制使用包括Java代码中调用Native模块以及Native代码中调用Java模块.
http://www.ophonesdn.com/article/show/263
众所周知,OPhone平台上的应用开发主要基于Java语言,但平台完全支持且提供了一定的Native开发能力(主要是C/C++),使得开发者可以借助JNI更深入的实现创意。本文主要介绍OPhone平台的JNI机制和Native模块开发与发布的方法。
JNI简介 Java Native Interface(JNI)是Java提供的一个很重要的特性。它使得用诸如C/C++等语言编写的代码可以与运行于Java虚拟机(JVM)中的Java代码集成。有些时候,Java并不能满足你的全部开发需求,比如你希望提高某些关键模块的效率,或者你必须使用某个以C/C++等Native语言编写的程序库;此时,JNI就能满足你在Java代码中访问这些Native模块的需求。JNI的出现使得开发者既可以利用Java语言跨平台、类库丰富、开发便捷等特点,又可以利用Native语言的高效。 图1 JNI与JVM的关系 实际上,JNI是JVM实现中的一部分,因此Native语言和Java代码都运行在JVM的宿主环境(Host Environment),正如图1所示。此外,JNI是一个双向的接口:开发者不仅可以通过JNI在Java代码中访问Native模块,还可以在Native代码中嵌入一个JVM,并通过JNI访问运行于其中的Java模块。可见,JNI担任了一个桥梁的角色,它将JVM与Native模块联系起来,从而实现了Java代码与Native代码的互访。在OPhone上使用Java虚拟机是为嵌入式设备特别优化的Dalvik虚拟机。每启动一个应用,系统会建立一个新的进程运行一个Dalvik虚拟机,因此各应用实际上是运行在各自的VM中的。Dalvik VM对JNI的规范支持的较全面,对于从JDK 1.2到JDK 1.6补充的增强功能也基本都能支持。 开发者在使用JNI之前需要充分了解其优缺点,以便合理选择技术方案实现目标。JNI的优点前面已经讲过,这里不再重复,其缺点也是显而易见的:由于Native模块的使用,Java代码会丧失其原有的跨平台性和类型安全等特性。此外,在JNI应用中,Java代码与Native代码运行于同一个进程空间内;对于跨进程甚至跨宿主环境的Java与Native间通信的需求,可以考虑采用socket、Web Service等IPC通信机制来实现。 在OPhone开发中使用JNI 正如我们在上一节所述,JNI是一个双向的接口,所以交互的类型可以分为在Java代码中调用Native模块和在Native代码中调用Java模块两种。下面,我们就使用一个Hello-JNI的示例来分别对这两种交互方式的开发要点加以说明。 Java调用Native模块 Hello-JNI这个示例的结构很简单:首先我们使用Eclipse新建一个OPhone应用的Java工程,并添加一个com.example.hellojni.HelloJni的类。这个类实际上是一个Activity,稍后我们会创建一个TextView,并显示一些文字在上面。 要在Java代码中使用Native模块,必须先对Native函数进行声明。在我们的例子中,打开HelloJni.java文件,可以看到如下的声明: view plain copy to clipboard print ?
- /* A native method that is implemented by the
- * 'hello-jni' native library, which is packaged
- * with this application.
- */
- public native StringstringFromJNI();
文章图片
- /* A native method that is implemented by the
- * 'hello-jni' native library, which is packaged
- * with this application.
- */
- public native StringstringFromJNI();
- #include
- #include
- jstring
- Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
- jobject thiz ) {
- return (*env)->NewStringUTF(env, "Hello from JNI !");
- }
文章图片
- #include
- #include
- jstring
- Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
- jobject thiz ) {
- return (*env)->NewStringUTF(env, "Hello from JNI !");
- }
从函数名可以看出,这个Native函数对应的正是我们在 com.example.hellojni.HelloJni 这个中声明的Native函数String stringFromJNI()的具体实现。 从上面Native函数的命名上我们可以了解到JNI函数的命名规则: (1)、 Java代码中的函数声明需要添加native关键字 ; (2)、 Native的对应函数名要以“Java_”开头,后面依次跟上Java的“package名”、“class名”、“函数名”,中间以下划线“_”分割,在package名中的“.”也要改为“_”。 (3)、 此外,关于函数的参数和返回值也有相应的规则。对于Java中的基本类型如int、double、char等,在Native端都有相对应的类型来表示,如jint、jdouble、jchar等;其他的对象类型则统统由jobject来表示(String是个例外,由于其使用广泛,故在Native代码中有jstring这个类型来表示,正如在上例中返回值String对应到Native代码中的返回值jstring) 。 (4)、 而对于Java中的数组,在Native中由jarray对应,具体到基本类型和一般对象类型的数组则有jintArray等和jobjectArray分别对应(String数组在这里没有例外,同样用jobjectArray表示)。 (5) 、 还有一点需要注意的是,在JNI的Native函数中,其前两个参数 JNIEnv *和 jobject 是必需的——前者是一个 JNIEnv 结构体的指针,这个结构体中定义了很多JNI的接口函数指针,使开发者可以使用JNI所定义的接口功能;后者指代的是调用这个JNI函数的Java对象,有点类似于C++中的 this 指针。在上述两个参数之后,还需要根据Java端的函数声明依次对应添加参数。在上例中,Java中声明的JNI函数没有参数,则Native的对应函数只有类型为 JNIEnv *和 jobject 的两个参数。 当然,要使用JNI函数,还需要先加载Native代码编译出来的动态库文件( 在Windows上是.dll,在Linux上则为.so )。这个动作是通过如下语句完成的: view plain copy to clipboard print ?
- static {
- System.loadLibrary("hello-jni");
- }
文章图片
- static {
- System.loadLibrary("hello-jni");
- }
- TextView tv = new TextView(this);
- tv.setText( stringFromJNI() );
- setContentView(tv);
文章图片
- TextView tv = new TextView(this);
- tv.setText( stringFromJNI() );
- setContentView(tv);
- package com.example.hellojni;
- public class SayHello {
- public String sayHelloFromJava(String nativeMsg) {
- String str = nativeMsg + " But shown in Java!";
- return str;
- }
- }
文章图片
- package com.example.hellojni;
- public class SayHello {
- public String sayHelloFromJava(String nativeMsg) {
- String str = nativeMsg + " But shown in Java!";
- return str;
- }
- }
- jstring helloFromJava( JNIEnv* env ) {
- jstring str = NULL;
- jclass clz = (*env)->FindClass(env, "com/example/hellojni/SayHello");
- jmethodID ctor = (*env)->GetMethodID(env, clz, "
", "()V"); - jobject obj = (*env)->NewObject(env, clz, ctor);
- jmethodID mid = (*env)->GetMethodID(env, clz, "sayHelloFromJava", "(Ljava/lang/String; )Ljava/lang/String; ");
- if (mid) {
- jstring jmsg = (*env)->NewStringUTF(env, "I'm born in native.");
- str = (*env)->CallObjectMethod(env, obj, mid, jmsg);
- }
- return str;
- }
文章图片
- jstring helloFromJava( JNIEnv* env ) {
- jstring str = NULL;
- jclass clz = (*env)->FindClass(env, "com/example/hellojni/SayHello");
- jmethodID ctor = (*env)->GetMethodID(env, clz, "
", "()V"); - jobject obj = (*env)->NewObject(env, clz, ctor);
- jmethodID mid = (*env)->GetMethodID(env, clz, "sayHelloFromJava", "(Ljava/lang/String; )Ljava/lang/String; ");
- if (mid) {
- jstring jmsg = (*env)->NewStringUTF(env, "I'm born in native.");
- str = (*env)->CallObjectMethod(env, obj, mid, jmsg);
- }
- return str;
- }
- LOCAL_PATH := $(call my-dir)
- include $(CLEAR_VARS)
- LOCAL_MODULE:=hello-jni
- LOCAL_C_INCLUDES :=$(LOCAL_PATH)/include
- LOCAL_SRC_FILES:=src/call_java.c \
- src/hello-jni.c
- include $(BUILD_SHARED_LIBRARY)
文章图片
- LOCAL_PATH := $(call my-dir)
- include $(CLEAR_VARS)
- LOCAL_MODULE:=hello-jni
- LOCAL_C_INCLUDES :=$(LOCAL_PATH)/include
- LOCAL_SRC_FILES:=src/call_java.c \
- src/hello-jni.c
- include $(BUILD_SHARED_LIBRARY)
推荐阅读
- JniHelper的再说明
- Android|Android C/C++开发指南
- JNI技术基础(1)——从零开始编写JNI代码
- Android|JNI子线程FindClass失败
- Android|giflib加载GIF
- android|Android GpioService从app到驱动
- android|Android通过JNI调用驱动程序(完全解析实例)
- #|我的第一个Android 驱动程序,驱动层 到framworks层
- android|android通过JNI控制GPIO