Android基础知识六(JNI)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_36347817/article/details/78928618

来来了解一下JNI吧,也许工作中并不一定用得着,但是也得知道一下大概内容呀。

总结安卓中关于JNI的基础知识,有以下三个部分。

(第一部分)

A) 创建一个类(HelloWorld.java)或者在原来的类com.example.hellojni.HelloJNI中声明本地方法。

(1)使用关键字native声明本地方法,表明这两个函数需要通过本地代码C/C++实现。

public native String stringFromJNI();

(2)加载动态库libHelloJNI.so

static{
    System.loadLibrary(“HelloJNI”);
}

B) 使用javac编译源文件HelloWorld.java,生成HelloWorld.class。

(1)通过Eclipse编译代码,生成.class文件。

C) 使用javah –jni来生成头文件,这个头文件里面包含了本地方法的函数原型。

  (1)在新建成的工程根目录下,键入以下命令:

$javah –classpath bin/classes –d jni com.example.hellojni.HelloJNI

  (2)运行完之后,会在本地生成一个名为jni的目录,里面有一个名为com_example_hellojni_HelloJNI.h的头文件,这个文件就是我们需要的头文件,它包含了我们先前声明的两个函数,还加入了相应的包名作为前缀。

D) 编写C/C++代码(HelloWorld.c)来实现头文件中的函数原型。

按照com_example_hellojni_HelloJNI.h中声明的函数名,在jni目录下建立一个HelloJNI.c,实现其函数体。

E) 将HelloWorld.c编译成一个动态库,生成HelloWorld.so或HelloWorld.dll。

(1) 下载ndk,在jni目录下输入ndk-build命令。

(2) 将会在HelloJNI/libs/armeabi目录下生成一个名为libHelloJNI.so的动态库,生成apk时会把这个库一起打包。

(第二部分)

A)JNI的入口函数,当执行到System.loadLibray(“HelloJNI”)时,会在第一次使用该类的时候加载动态库libHelloJNI.so,当Android的VM执行到System.loadLibrary()这个函数时,首先会执行JNI_OnLoad()这个函数,执行这个函数的意图包括:

(1)告诉VM此C组件使用哪一个JNI版本。如果动态库中没有提供JNI_onLoad(),VM默认使用最老的JNI 1.1版本。

(2)初始化,例如预先申请资源等等。

B)使用ndk进行编译。

C)使用registerNativeMethods方法

(1)在jni目录下新建HelloJNI.c:

jstring stringFromJNI(JNIEnv* env, jobject this)

static JNINativeMethod gMethods[] = …

int register_location_methods(JNIEnv *env)

jint JNI_Onload(JavaVm* vm, void *reserved);

void JNI_Onload(JavaVm* vm, void *reserved);

(2)其中的JNI_OnLoad()函数包括以下步骤:获取JNI环境对象,登记本地方法,最后返回JNI版本。

(3)声明实例:

Static JNINativeMethod gMethods[] = {
    { “stringFromJNI”,“()Ljava/lang/String”,(void*)stringFromJNI}
}

D)使用registerNativeMethods的好处:

(1)不需要使用长方法名。

(2)提高效率。当Java类通过VM呼叫到本地函数时,通常是依靠VM去动态寻找动态库中的本地函数(因此才需要特定规则的命名格式),如果某方法需要连续呼叫许多次,则每次都要寻找一遍,所以使用registerNativeMethods将本地函数向VM登记,可以更有效率地找到函数。

(3)运行时动态调整本地函数与Java函数值之间的映射关系,只需要多次调用registerNativeMethods方法,并传入不同的映射表参数即可。

(第三部分:优缺)

(1)JNI的强大特性使我们在使用Java平台的同时,还可以重用原来的本地代码,作为虚拟机实现的一部分,JNI允许Java和本地代码间的双向交互,你可以使用JNI来实现本地方法,并在Java程序中调用它们。

(2)JNI的副作用

A)应用不再跨平台,要想跨平台,必须在不同的系统环境下重新编译本地语言部分。

B)程序不再是绝对安全的,本地代码的不当使用可能导致整个程序崩溃。

猜你喜欢

转载自blog.csdn.net/qq_36347817/article/details/78928618
今日推荐