您的位置:首页 > 移动开发 > Android开发

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 标准无关
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐