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

-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 c 静态注册和动态注册

  • 2017年08月13日 23:42
  • 34.54MB
  • 下载

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 studio使用cmake 编写jni调用静态库、动态库的方式

最近在帮助项目的大神测试编译出来的安卓动态库,需要用到jni,但是使用ndk去编译有太麻烦(还是懒),毕竟库太多了。然后以前听说android studio被谷歌搞得可以使用cmake 去编译源码库,...

android stadio jni动态注册函数

  • 2016年04月06日 17:24
  • 3.65MB
  • 下载

Android JNI学习笔记(二)-动态注册native函数

1.前言在很久之前的一篇Android 开发艺术探索的笔记当中,学习了简单的jni开发流程,但是那会的步骤极其繁琐复杂,而且生成的头文件函数太长,那么,有没有方法能解决呢,让开发过程变得简单易懂。当然...

Android JNI动态注册Native 方法(实现IDA中改名)

1、Android应用层代码: import android.app.Activity; import android.os.Bundle; import android.widget.Text...
  • hk9259
  • hk9259
  • 2015年01月30日 17:21
  • 1252

Android Dalvik虚拟机JNI方法的注册过程分析

Dalvik虚拟机在调用一个成员函数的时候,如果发现该成员函数是一个JNI方法,那么就会直接跳到它的地址去执行。也就是说,JNI方法是直接在本地操作系统上执行的,而不是由Dalvik虚拟机解释器执行。...
  • rjdeng
  • rjdeng
  • 2015年09月17日 10:51
  • 411

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

注册native函数有两种方法:静态注册和动态注册。 1、静态注册方法 根据函数名找到对应的JNI函数:Java层调用函数时,会从对应的JNI中寻找该函数,如果没有就会报错,如果存在则会建立一个关...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:android jni 的编写一(JNI的静态注册)
举报原因:
原因补充:

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