JNI是Java Native Interface的缩写,通过JNI可以方便我们在Android平台上进行C/C++编程。要用JNI首先必须安装Android的NDK,配置好NDK环境之后就可以在Eclipse下进行C/C++开发了。

其实JNI的原理很容易理解,其本质就是在Java层定义一个接口,同时在C层用C/C++代码实现该接口的功能并编译成动态链接库,这样 Activity就可以通过Java层接口调用生成的动态链接库,完成相应的功能。简单地说就是两点:(1)定义Java接口(JNI),(2)用 C/C++实现接口功能并打包成库文件以供调用。

在这里,我将假设读者已经在Linux环境下安装好了NDK,并且会使用Eclipse。下面以C++为例一步一步说明JNI开发过程。

1 创建Android工程

新建一个TestJNI目录,用Eclipse在该目录下创建一个名为TestJNI的Android工程,包名为com.TestJNI.jni。创建完成后在工程的src目录下会自动创建一个名为TestJNIActivity.java的文件。

2 设计Java接口
   
先不用管这个文件,在该文件的位置再创建一个名为TestJNI.java文件:

打开TestJNI.java,我们将在这个文件里创建一个JNI接口类,该Java类提供一个加法运算的接口:

这里的函数声明一定要加native修饰。

3 编译JNI

将TestJNI.java文件复制到工程的bin目录下,在终端中进入该工程的bin目录,输入javac
TestJNI.java,这时会生成一个TestJNI.class文件。

在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

有了JNI的C/C++头文件,就可以在C层实现JNI接口了。首先在工程目录下创建一个jni目录,这个目录就是专门用来放C/C++代码的。把com_TestJNI_jni_TestJNI.h文件复制到jni目录下,并在这里创建一个com_TestJNI_jni_TestJNI.cpp文件。

由于我想用C++来实现JNI,所以上面两个文件我只是用来作为动态链接库的接口,具体的实现我希望放在一个类里面来完成,因此我再添加两个文件:Add.h和Add.cpp。

下面我们就来实现CAdd类和JNI接口。首先实现CAdd类:

Add.h

Add.cpp

然后我们来写com_TestJNI_jni_TestJNI.cpp,实现JNI:

到此我们的C/C++部分就全部实现了。

5 创建mk文件

JNI实现了之后就要把C/C++代码编译成动态链接库.so文件,这样Java程序才能调用JNI的接口。要编译so文件,需要写Android.mk和Application.mk两个文件。我们先来写Android.mk。

先在工程目录的jni下创建一个Android.mk文件:

然后打开文件在里面输入如下内容:

其中LOCAL_PATH是C/C++代码所在目录,也就是我们的jni目录。

LOCAL_MODULE是要编译的库的名称。编译器会自动在前面加上lib,在后面加上.so。

LOCAL_SRC_FILES是要编译的C/C++文件。

现在我们在工程的根目录下创建一个Application.mk文件,并输入如下内容:

6 编译动态链接库

写完了mk文件就可以开始编译C/C++代码了。在终端里进入工程的根目录,输入ndk-build即可:

编译成功后会在工程目录的libs/armeabi目录下生成一个libTestJNI.so文件。

7 在Java中调用JNI

大家应该还记得在创建工程的时候就已经生成了一个TestJNIActivity.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,如下图:

现在编译工程,就可以顺利通过了。程序运行结果如下:

这个例子只是为了显示JNI的用法,只要写好了JNI接口,其他的编程就跟C/C++一样了。编译动态链接库的时候,除了使用ndk-build命令之外,也可以在Eclipse工程中配置一个Builder,直接在Eclipse下编译。

Android平台下的JNI开发的更多相关文章

  1. <2014 05 14> Android平台下2D/3D开发攻略

    Android通过OpenGL包含了对高性能2D和3D图形的支持,尤其支持OpenGLES API.OpenGL是一个跨平台的图形API,提供了软件操作3D图形硬件的接口.OpenGLES是一个专用于 ...

  2. Android平台下的TCP/IP传输(客户端)

    在工科类项目中,嵌入式系统与软件系统或后台数据库之间的信息传输是实现“物联网”的一种必要的途径,对已简单概念的物联网,通常形式都是一个单片机/嵌入式系统实现数据的采集及其处理,通过蓝牙,wifi或者是 ...

  3. Android平台下Dalvik层hook框架ddi的研究

    通过adbi,可以对native层的所有代码进行hook.但对于Android系统来说,这还远远不够,因为很多应用都还是在Dalvik虚拟机中运行的. 那么,有没有什么办法可以对Dalvik虚拟机中跑 ...

  4. Android Studio1.4.x JNI开发基础-基本环境配置

    从Eclipse时代到Android Studio普及,开发工具越来越好用.早些时候还需要安装Cygwin工具,从Android Studio1.3以后,在Android 环境开发JNI程序搭建开发环 ...

  5. [转帖]Android平台下OpenGL初步

    原文请看 Android平台下OpenGL初步 本文只关注于如何一步步实现在Android平台下运用OpenGl. 1.GLSurfaceView GLSurfaceView是Android应用程序中 ...

  6. Android平台下OpenCV移植与使用---基于C/C++

    在<Android Studio增加NDK代码编译支持--Mac环境>和<Mac平台下Opencv开发环境搭建>两篇文章中,介绍了如何使用NDK环境和Opencv环境搭建与测试 ...

  7. Android Studio1.4.x JNI开发基础 - 简单实例

    接上一篇,搭建好基于Android Studio的环境之后,编写native代码相对来说也比较简单了.在Android上编写Native代码和在Linux编写C/C++代码还是有区别,Native代码 ...

  8. 【android 开 发 】 - Android studio 下 NDK Jni 开发 简单例子

    Android 开发了一段时间,一方面 ,感觉不留下点什么.有点对不起自己, 另一方面,好记性不如烂笔头,为了往后可以回头来看看,就当做是笔记,便决定开始写博客.废话不多说 ! 今天想搞一搞 ndk ...

  9. Android平台下OpenGL初步

    Android OpenGL ES 开发教程 从入门到精通 http://blog.csdn.net/zhoudailiang/article/details/50176143 http://blog ...

随机推荐

  1. 使用windows远程桌面连接Windows Azure中的Ubuntu虚拟机

    1.创建ubuntu虚拟机,这里同样不再赘述,创建过程和创建Windows虚拟机基本一样,只是登录可以选择密钥注入或者用户名密码(为了方便我选择了用户名密码认证),创建完成后,查看虚拟机详情中的端口信 ...

  2. centos虚拟机,环境配置

    yum安装 yum -y install 包名(支持*) :自动选择y,全自动yum install 包名(支持*) :手动选择y or n 1.安装vim Centos默认自带VI,功能没VIM丰富 ...

  3. 《Java7中 下划线的新特性》

    //Java7引入了一个新功能:程序员可以在数值中使用下画线,不管是 //整形数值,还是浮点型数值,都可以自由地使用下划线.通过下划线 //分隔,可以更直观的分辨数值中到底有多少位. public c ...

  4. 转:Java面试题集(51-70) http://blog.csdn.net/jackfrued/article/details/17403101

    Java面试题集(51-70) Java程序员面试题集(51-70) http://blog.csdn.net/jackfrued/article/details/17403101 摘要:这一部分主要 ...

  5. tableviewcell的取消选中,高亮

    1.取消多余cell的分割线 UIView *view = [UIView new]; view.backgroundColor = [UIColor clearColor]; [tableView ...

  6. IIS使用问题

    1.System.Data.SQLite”或它的某一个依赖项.试图加载格式不正确的程序:修改IIS应用程序池的高级设置将32位设置成true

  7. droidbox官网

    droidbox官网,droidbox已经移植到github上了 https://github.com/pjlantz/droidbox

  8. C++11 std::copy

    这个函数并不是简单的 while(first != last) { *result = *first; result++; first++; } 事实上这种写法是最具普适性的,值要求inputIter ...

  9. Squid代理之透明代理

    二.透明代理 1.检测squid是否安装

  10. 后序/中序--->前序

    preOrder 5 3 2 4 8 6 9   midOrder 2 3 4 5 6 8 9  postOrder 2 4 3 6 9 8 5 #include <iostream> # ...