android jni 的编写一(JNI的静态注册)

原创 2016年08月31日 12:08:48
使用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 Output directory
-o Output file (only one of -d or -o may be used)
-jni Generate JNI-style header file (default)
-version Print version information
-verbose Enable verbose output
-force Always write output files

are specified with their fully qualified names (for
instance, java.lang.Object).

-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 标准无关
版权声明:本文为博主原创文章,转载请注明出处。

相关文章推荐

AndroidJNI实践(1)-使用.h头文件-静态注册JNI方法

一、环境和工具:   Ubuntu14.04   java version "1.7.0_95"   IDE(Android-studio/Eclipse)   android-ndk-r10b 二...

Android深入理解JNI(一)JNI原理与静态、动态注册

JNI不仅仅在NDK开发中应用,它更是Android系统中Java与Native交互的桥梁,不理解JNI的话,你就只能停留在Java Framework层。这一个系列我们来一起深入学习JNI。

深入了解android平台的jni---注册native函数

注册native函数有两种方法:静态注册和动态注册。 1、静态注册方法 根据函数名找到对应的JNI函数:Java层调用函数时,会从对应的JNI中寻找该函数,如果没有就会报错,如果存在则会建立一个关...

Android Studio JNI 的静动态注册开发以及C/C++ JNIEnv的理解

看到这个题目似乎有点啰嗦,分两块: 一是关于JNI开发的静动态注册,因为涉及到一点逆向上的安全问题,因此有必要进行细细的琢磨和加以区别; 二是在关于JNI的开发过程中对于用.c与.cpp不同文件时注意...

Android: JNI动态注册

之前的例子当Java层调用本地函数的时候,他会从我们加载的库中寻找固定格式与本地函数名字对应的函数,如果没有,就会报错。如果找到,就会为这个本地方法与本地函数建立一个关联关系,其实就是保存JNI层函数...

Android 动态注册JNI函数

1.JNI函数注册方式 在Android开发中,由于种种原因我们需要调用C/C++代码,在这个时候我们就需要使用jni了, jni在使用时要对定义的函数进行注册,这样java才能通过native关...

深入了解android平台的jni---注册native函数

注册native函数有两种方法:静态注册和动态注册。 1、静态注册方法 根据函数名找到对应的JNI函数:Java层调用函数时,会从对应的JNI中寻找该函数,如果没有就会报错,如果存在则会建...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)