android jni 的编写一(JNI的静态注册)
2016-08-31 12:08
363 查看
使用ndk开发需要编写jni.jni函数注册有两种方法。第一种静态注册,第二种动态注册。在NDK开发中使用第一种方法比较多,第二种方法在framework开发中使用的比较多,但是依赖android的一些特定的函数库。在ndk中不能使用。jni的静态注册需要生成对应的native头问题件,我们以ndk中hell-jni 为例进行说明:
按照网上的攻略
root@ubuntu12:/work/android-ndk-r8b/samples/hello-jni# javah -classpath bin -d jni com.example.hellojni.HelloJni
错误:无法访问 com.example.hellojni.HelloJni
未找到 com.example.hellojni.HelloJni 的类文件
javadoc: 错误 - 找不到类 com.example.hellojni.HelloJni。
Error: 未在命令行中指定任何类。请尝试使用 -help。
搜索一下javah 的用法:wanghuan@ubuntu:~/android-ndk-r8b/samples/hello-jni/src/com/example/hellojni$ javah
Usage: javah [options]
where [options] include:
-help Print this help message and exit
-classpath Path from which to load classes
-bootclasspath Path from which to load bootstrap classes
-d
-classpath Path from which to load classes
-bootclasspath Path from which to load bootstrap classes这两个选项就是javah的操作对象的路径,现在项目里没有class文件,出错。但是如果javac
编译HelloJni.java 的话,编译报错,不识别Android的特有类。把重新改写HelloJni.java。全部标准java实现:public
class HelloJni
{
/* A native method that is implemented by the
* 'hello-jni' native library, which is packaged
* with this application.
*/
public native String stringFromJNI();
/* This is another native method declaration that is *not*
* implemented by 'hello-jni'. This is simply to show that
* you can declare as many native methods in your Java code
* as you want, their implementation is searched in the
* currently loaded native libraries only the first time
* you call them.
*
* Trying to call this function will result in a
* java.lang.UnsatisfiedLinkError exception !
*/
public native String unimplementedStringFromJNI();
/* this is used to load the 'hello-jni' library on application
* startup. The library has already been unpacked into
* /data/data/com.example.hellojni/lib/libhello-jni.so at
* installation time by the package manager.
*/
static {
System.loadLibrary("hello-jni");
}
}
root@ubuntu12:/work/android-ndk-r8b/samples/hello-jni/src/example/hellojni# ls
HelloJni.class HelloJni.java
这次生成了class文件。但是javah 始终找不到这个类,加入调试选项:
root@ubuntu12:/work/android-ndk-r8b/samples/hello-jni# javah -verbose -classpath bin -d jni com.example.hellojni.HelloJni
错误:无法访问 com.example.hellojni.HelloJni
未找到 com.example.hellojni.HelloJni 的类文件
javadoc: 错误 - 找不到类 com.example.hellojni.HelloJni。
[ Search Path: /usr/lib/jvm/java-6-sun-1.6.0.30/jre/lib/resources.jar:/usr/lib/jvm/java-6-sun-1.6.0.30/jre/lib/rt.jar:/usr/lib/jvm/java-6-sun-1.6.0.30/jre/lib/sunrsasign.jar:/usr/lib/jvm/java-6-sun-1.6.0.30/jre/lib/jsse.jar:/usr/lib/jvm/java-6-sun-1.6.0.30/jre/lib/jce.jar:/usr/lib/jvm/java-6-sun-1.6.0.30/jre/lib/charsets.jar:/usr/lib/jvm/java-6-sun-1.6.0.30/jre/lib/modules/jdk.boot.jar:/usr/lib/jvm/java-6-sun-1.6.0.30/jre/classes/bin
]
Error: 未在命令行中指定任何类。请尝试使用 -help。
显示CLASSPATH路径不对。配置CLASSPATHexport JAVA_HOME=/usr/lib/jvm/java-6-sun-1.6.0.30/bin
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:./
export PATH=$JAVA_HOME/bin:$PATH
换一种思路,在windows eclipse 下面:首先在一个工程中加入HelloJni.java或者新建一个工程 . HelloJni.java 为ndk自带的java文件。生成HelloJni.class 文件。然后进入bin\classes 在环境变量中配置CLASS_PATH为:.;
D:\workspace\SPlayer\bin\classes>javah -d . com.example.hellojni.HelloJni
D:\workspace\SPlayer\bin\classes>ls
com com_example_hellojni_HelloJni.h
D:\workspace\SPlayer\bin\classes>/* DO NOT EDIT THIS FILE - it is machine
generated */
#include
/* Header for class com_example_hellojni_HelloJni */
#ifndef _Included_com_example_hellojni_HelloJni
#define _Included_com_example_hellojni_HelloJni
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_example_hellojni_HelloJni
* Method: stringFromJNI
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_example_hellojni_HelloJni_stringFromJNI
(JNIEnv *, jobject);
/*
* Class: com_example_hellojni_HelloJni
* Method: unimplementedStringFromJNI
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_example_hellojni_HelloJni_unimplementedStringFromJNI
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
总结一下:1.javah
生成native头文件依赖于对应的class文件 。因此应该先生成class 文件,不然巧妇难为无米之炊。2. javah 寻找类路径的时候 依赖于CLASSPATH环境变量,要正确的配置CLASSPATH。3.javc
编译class文件只支持java标准的API,不支持android API 。如果java文件中有androidAPI 应该使用android的编译环境或者EClipse生成class文件。javah 生成头文文件只是根据class文件中的native 方法,和是否是标准的java 标准无关
按照网上的攻略
root@ubuntu12:/work/android-ndk-r8b/samples/hello-jni# javah -classpath bin -d jni com.example.hellojni.HelloJni
错误:无法访问 com.example.hellojni.HelloJni
未找到 com.example.hellojni.HelloJni 的类文件
javadoc: 错误 - 找不到类 com.example.hellojni.HelloJni。
Error: 未在命令行中指定任何类。请尝试使用 -help。
搜索一下javah 的用法:wanghuan@ubuntu:~/android-ndk-r8b/samples/hello-jni/src/com/example/hellojni$ javah
Usage: javah [options]
where [options] include:
-help Print this help message and exit
-classpath Path from which to load classes
-bootclasspath Path from which to load bootstrap classes
-d
-classpath Path from which to load classes
-bootclasspath Path from which to load bootstrap classes这两个选项就是javah的操作对象的路径,现在项目里没有class文件,出错。但是如果javac
编译HelloJni.java 的话,编译报错,不识别Android的特有类。把重新改写HelloJni.java。全部标准java实现:public
class HelloJni
{
/* A native method that is implemented by the
* 'hello-jni' native library, which is packaged
* with this application.
*/
public native String stringFromJNI();
/* This is another native method declaration that is *not*
* implemented by 'hello-jni'. This is simply to show that
* you can declare as many native methods in your Java code
* as you want, their implementation is searched in the
* currently loaded native libraries only the first time
* you call them.
*
* Trying to call this function will result in a
* java.lang.UnsatisfiedLinkError exception !
*/
public native String unimplementedStringFromJNI();
/* this is used to load the 'hello-jni' library on application
* startup. The library has already been unpacked into
* /data/data/com.example.hellojni/lib/libhello-jni.so at
* installation time by the package manager.
*/
static {
System.loadLibrary("hello-jni");
}
}
root@ubuntu12:/work/android-ndk-r8b/samples/hello-jni/src/example/hellojni# ls
HelloJni.class HelloJni.java
这次生成了class文件。但是javah 始终找不到这个类,加入调试选项:
root@ubuntu12:/work/android-ndk-r8b/samples/hello-jni# javah -verbose -classpath bin -d jni com.example.hellojni.HelloJni
错误:无法访问 com.example.hellojni.HelloJni
未找到 com.example.hellojni.HelloJni 的类文件
javadoc: 错误 - 找不到类 com.example.hellojni.HelloJni。
[ Search Path: /usr/lib/jvm/java-6-sun-1.6.0.30/jre/lib/resources.jar:/usr/lib/jvm/java-6-sun-1.6.0.30/jre/lib/rt.jar:/usr/lib/jvm/java-6-sun-1.6.0.30/jre/lib/sunrsasign.jar:/usr/lib/jvm/java-6-sun-1.6.0.30/jre/lib/jsse.jar:/usr/lib/jvm/java-6-sun-1.6.0.30/jre/lib/jce.jar:/usr/lib/jvm/java-6-sun-1.6.0.30/jre/lib/charsets.jar:/usr/lib/jvm/java-6-sun-1.6.0.30/jre/lib/modules/jdk.boot.jar:/usr/lib/jvm/java-6-sun-1.6.0.30/jre/classes/bin
]
Error: 未在命令行中指定任何类。请尝试使用 -help。
显示CLASSPATH路径不对。配置CLASSPATHexport JAVA_HOME=/usr/lib/jvm/java-6-sun-1.6.0.30/bin
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:./
export PATH=$JAVA_HOME/bin:$PATH
换一种思路,在windows eclipse 下面:首先在一个工程中加入HelloJni.java或者新建一个工程 . HelloJni.java 为ndk自带的java文件。生成HelloJni.class 文件。然后进入bin\classes 在环境变量中配置CLASS_PATH为:.;
D:\workspace\SPlayer\bin\classes>javah -d . com.example.hellojni.HelloJni
D:\workspace\SPlayer\bin\classes>ls
com com_example_hellojni_HelloJni.h
D:\workspace\SPlayer\bin\classes>/* DO NOT EDIT THIS FILE - it is machine
generated */
#include
/* Header for class com_example_hellojni_HelloJni */
#ifndef _Included_com_example_hellojni_HelloJni
#define _Included_com_example_hellojni_HelloJni
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_example_hellojni_HelloJni
* Method: stringFromJNI
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_example_hellojni_HelloJni_stringFromJNI
(JNIEnv *, jobject);
/*
* Class: com_example_hellojni_HelloJni
* Method: unimplementedStringFromJNI
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_example_hellojni_HelloJni_unimplementedStringFromJNI
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
总结一下:1.javah
生成native头文件依赖于对应的class文件 。因此应该先生成class 文件,不然巧妇难为无米之炊。2. javah 寻找类路径的时候 依赖于CLASSPATH环境变量,要正确的配置CLASSPATH。3.javc
编译class文件只支持java标准的API,不支持android API 。如果java文件中有androidAPI 应该使用android的编译环境或者EClipse生成class文件。javah 生成头文文件只是根据class文件中的native 方法,和是否是标准的java 标准无关
相关文章推荐
- android jni 的编写二 (NDK 开发中动态注册Jni)
- Android == JNI静态注册
- Android深入理解JNI(一)JNI原理与静态、动态注册
- AndroidJNI实践(1)-使用.h头文件-静态注册JNI方法
- Android jni 静态注册 和动态注册
- Android深入理解JNI(一)JNI原理与静态、动态注册
- Android JNI静态和动态注册 、Java Reflect(C或C++层反射和JAVA层反射)、Java 可变参数(JNI实现)
- Android深入理解JNI(一)JNI原理与静态、动态注册
- android开发——关于编写JNI
- 在Ubuntu为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口
- 在Ubuntu为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口
- 在Ubuntu为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口
- 在Ubuntu为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口
- 在Ubuntu为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口
- Android静态注册内部类广播BroadcastReceiver
- 在Ubuntu为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口
- Android硬件抽象层编写JNI方法提供Java访问硬件服务接口
- 在Ubuntu为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口
- (四)在Ubuntu为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口
- android jni代码编写规则--整理总结