牛骨文教育服务平台(让学习变的简单)
博文笔记

Android开发 通过JNI实现JAVA与C/C++程序间的调用和回调

创建时间:2015-12-03 投稿人: 浏览次数:172

       在一些Android应用的开发中,需要通过JNI Android NDK工具实现JAVAC/C++之间的相互调用。

       Java Native Interface (JNI)标准是java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI是本地编程接口,它使得在 Java 虚拟机 (VM)内部运行的 Java代码能够与用其它编程语言( CC++和汇编语言)编写的应用程序和库进行交互操作。

       由于Android的应用层的类都是以Java写的,这些Java类编译为Dex型式的Bytecode之后,必须靠Dalvik虚拟机(VM: Virtual Machine)来执行。在执行Java类的过程中,如果Java类需要与C组件沟通时,VM就会去载入C组件,然后让Java的函数顺利地调用到C组件的函数。此时,VM扮演着桥梁的角色,让JavaC组件能通过标准的JNI介面而相互沟通。

       在实际应用中这两者之间的调用关系可以归纳为以下四种方式:

             1.       在应用的JAVA代码中调用NDKC/C++实现的函数。

             2.       在NDK开发中的C/C++代码调用应用中JAVA类的静态函数。

             3.       在NDK开发中的C/C++代码调用应用中JAVA类当前传入NDK中的实例的函数。

            4.       在NDK开发中的C/C++代码调用应用中JAVA类新建实例的函数。

 

下面我们就怎样在Eclipse中实现JNI编码和四种调用方式加以阐述。

 

一、Eclipse中建立一个包含JNI开发的工程。

在这里我们不直接导入NDK中的hello-jni来说明JNI的使用方法。而是新建立一个工程,来说明怎样建立一个包含JNI的工程。

第一步:建立一个Andriod工程JniDemo,在该工程的根目录下建立一个叫jni的目录,在jni目录下建立一个叫Android.mk的文件,(当然你也可以从其他地方,比如ndk样例代码hello-jni中将里面的Android.mk复制过来修改) Android.mk里面的内容如下所示

LOCAL_PATH :=$(call my-dir)

include$(CLEAR_VARS)

LOCAL_MODULE   := demo-jni

LOCAL_SRC_FILES := demo-jni.c

include$(BUILD_SHARED_LIBRARY)

关于这几句话的含义,在这里不再赘述。网上搜下,就可以很明白。

然后在jni目录下生成demo-jni.c文件。实现的接口的内容。

现在选中工程中的jni目录,点击鼠标右键,选Refreshjni目录中的文件就显示在工程的jni目录下了。

第二步:设置jni的编译环境。选中工程中的根目录JniDemo,点击鼠标右键,选Properties。弹出对话框,选中列表中的Builders。如图一所示:

图一:JniDemo特性设置对话框

点击对话框右端的new按钮,弹出“Choose configuration type”对话框,如图二,选择Program,点击对话框下面的OK按钮。

图二:选择配置类型

现在我们打开了”Edit Configuration”对话框,在Name对应的文本框中输入名字JniBuilder(当然也可是你喜欢的其他名字).Main选项下,Location中输入cygwin系统中bash.exe的绝对路径。我这里是c:cygwininash.exec:cygwin为我的系统中cygwin的安装目录,这里要根据你的电脑中cygwin的安装目录来确定),Working Directory中输入c:cygwinin.Arguments中输入--login -c "cd /cygdrive/d/study/JniDemo && /cygdrive/d/android-ndk-r6b/ndk-build"。这里/cygdrive/d/study/JniDemo为工程根目录, /cygdrive/d/android-ndk-r6bNDK的安装目录。这两个目录参数根据你的工程目录和ndk的安装目录而定。注意的是驱动器要采用cygwin的方式。(比如:Windows系统下的D:对应/cygdrive/d,其余类推)。设置结果如图三所示,然后点击 OK按钮即可。

图三:编辑JNI配置参数

 

二、演示四种调用方式

演示界面如图四所示,四个按钮分别测试四种调用方式。

图四:演示界面图

分别点击按钮Test1, Test2, Tes3, Test四的测试结果如图五、六、七、八所示。

图五:点击Test1的测试结果

图六:点击Test2的测试结果

图七:点击Test3的测试结果

 

图八:点击Test4的测试结果

 

Test1演示在应用中调用NDKC/C++实现的函数。JAVA代码和C代码分别为:

JAVA 代码: