对于JNI和NDK很多Android开发初学者没有搞明白这个问题,JNI是Java调用Native机制,是Java语言自己的特性全称为Java Native Interface,类似的还有微软.Net Framework上的p/invoke,可以让C#或Visual Basic.Net可以调用C/C++的API,所以说JNI和Android没有关系,在PC上开发Java的应用,如果运行在Windows平台使用JNI是是经常的,比如说读写Windows的注册表。
而NDK是Google公司推出的帮助Android开发者通过C/C++本地语言编写应用的开发包,包含了C/C++的头文件、库文件、说明文档和示例代码,我们可以理解为Windows Platform SDK一样,是纯C/C++编写的,但是Android并不支持纯C/C++编写的应用,同时NDK提供的库和函数功能很有限,仅仅处理些算法效率敏感的问题,所以Android123推荐初学者学好Java后再学习JNI。
说白了,JNI是JAVA特有的东西,是为了提升JAVA语言的性能,C/C++效率肯定比JAVA的高,JNI的作用就是将一些耗时耗内存的工作交给C/C++来做,然后通过JNI来调用,因为JAVA不能直接使用外部语言。本地方法的声明,实现以及调用接下来会一一介绍。
在PC端例如在windows中,通过VC等编译器可以将生成的本地方法(也就是.c文件)生成动态链接库(.dll),而在android中(基于Linux的系统)会生成.so文件,而NDK就起到了类似如VC编译器的作用,为了方面开发者将所编写的.c文件打包成.so文件之用。
下面写个小例子方面理解Android中JNI和NDK的使用。
1 创建Android工程
2 设计Java接口
打开TestJNI.java,我们将在这个文件里创建一个JNI接口类,该Java类提供一个加法运算的接口:
这里的函数声明一定要加native修饰。
3
在bin文件夹下,如果没有则创建目录:/com/TestJNI/jni,并把TestJNI.class复制到/bin/com/TestJNI/jni目录下。然后在终端里进入工程的bin目录,输入javah -jni com.TestJNI.jni.TestJNI,此时会生成一个com_TestJNI_jni_TestJNI.h文件。
com_TestJNI_jni_TestJNI.h文件就是对应于上面定义的Java接口的C/C++头文件。打开这个文件,可以看到系统已经为我们自动完成了接口函数的声明:
这三个函数分别对应于JNI的三个接口函数,命名方式只是在前面加上了Java包名。
4 用C/C++实现JNI
下面我们就来实现CAdd类和JNI接口。首先实现CAdd类:
Add.h
Add.cpp
然后我们来写com_TestJNI_jni_TestJNI.cpp,实现JNI:
到此我们的C/C++部分就全部实现了。
5
其中LOCAL_PATH是C/C++代码所在目录,也就是我们的jni目录。
LOCAL_MODULE是要编译的库的名称。编译器会自动在前面加上lib,在后面加上.so。
LOCAL_SRC_FILES是要编译的C/C++文件。
6 编译动态链接库
编译成功后会在工程目录的libs/armeabi目录下生成一个libTestJNI.so文件。
7 在Java中调用JNI
在这里我们首先用System.loadLibrary("TestJNI")加载了C/C++编译的so文件,然后创建了一个TestJNI对象,通过该对象调用了so库中的方法。现在的代码应该是编译不过去的,因为我们还没有给TextView添加ID,所以R.id.tv是无效的。那么我们来添加这个ID。找到res/layout目录下的main.xml文件:
双击打开该文件,在TextView标签下添加一行android:id="@+id/tv",这样就创建了一个名为tv的域并自动分配ID,如下图:
本文详细介绍了Android开发中JNI和NDK的使用方法,包括如何通过JNI在Java层调用C/C++代码,以及NDK在纯C/C++应用开发中的角色。通过创建Android工程、设计Java接口、编译JNI、实现C/C++代码、创建mk文件编译动态链接库,最终在Java中调用JNI接口。示例代码帮助开发者快速上手。

被折叠的 条评论
为什么被折叠?



