Android NDK开发系列教程1:环境搭建及基本代码结构
终于建了一个自己个人小站:https://huangtianyu.gitee.io,以后优先更新小站博客,欢迎进站,O(∩_∩)O~~
JNI全称 Java Native Interface , java本地化接口。即JNI是定义了一系列接口,所有实现该接口的JVM虚拟机都可以通过该接口实现Java和C/C++的混合编程。java和C/C++不同 , 它不会直接编译成平台机器码,而是编译成虚拟机可以运行的java字节码的.class文件,通过JIT技术即时编译成本地机器码,所以有效率就比不上C/C++代码,JNI技术就解决了这一痛点,实现Java调用C/C++代码。
1. Eclipse NDK开发环境搭建
在开发NDK之前,Java的SDK,Android的NDK,以及Eclipse的ADT工具都需要大家先安装好,在SDK早期版本中没有ndk相关文件,当最近的AndroidSDK中包含了ndk相关文件,所以下载NDK工具的麻烦事这里就没有了。唯一要注意的是需要配置下NDK的环境变量。这样可以方便进行编译。AndroidSDK主要文件夹参考如下:
这里讲Eclipse的配置就将下如何添加External Tool来快速生成.h文件以及快速进行ndk_build编译。
1.1 配置快速生成.h头文件的命令
- 点击Eclipse上面的图标,打开External Tool Configurations。
- 然后打开如下界面,在如下界面中双击Program,在底下会生成一个New_configuration。
然后按照图片上面的格式填写相应的参数。
Location填写javah.exe的位置:C:\Program Files\Java\jdk1.8.0_91\bin\javah.exe
Working Directory填写当前的工作目录:${workspace_loc:/MyTest/src}
Arguments填写相应的参数:
-classpath ${workspace_loc:/MyTest/src/bin/classes} -d ${workspace_loc:/MyTest/jni} -jni com.scu.MyNDK
之后在External Tool的地方就会生成一个JavaH的命令工具,点击即可生成对应的.h头文件了。这里要注意的是生成都文件前要先编译出.class文件。
其实这个和用javah.exe命令是一样的,具体命令如下:
2. Android Studio的配置
AS太强大了,所有你想要的只需要简单的添加一个依赖,AS就会自动帮你下载,完全不用你去下载。最新的Android Studio在新建工程的时候,选中Include C++ Support后,即可进行NDK开发,这里注意下在AS中的编译换成了CMake工具,这个工具配置上稍微和Android.mk有些许不同。其配置文件在新建工程的CMakeLists.txt里面配置。
在build.gradle里面也会自动配置cmake工具,配置如下:
externalNativeBuild { cmake { path "CMakeLists.txt" } }
3. 基本代码结构
利用AS创建工程后,工程会自动生成如下代码:
package zqc.com.example; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } // Used to load the 'native-lib' library on application startup. static { System.loadLibrary("native-lib"); } /** * A native method that is implemented by the 'native-lib' native library, * which is packaged with this application. */ public native String stringFromJNI(); }
其中在static静态代码块中会加载动态链接库。在一个方法前加上native关键字即表明该方法是一个jni方法,因而只有声明,没有实现,其具体实现在c/c++代码中。
找到cpp文件,打开后内容如下:
#include <jni.h> #include <string> extern "C" JNIEXPORT jstring JNICALL Java_zqc_com_example_MainActivity_stringFromJNI( JNIEnv *env, jobject /* this */) { std::string hello = "Hello from C++"; return env->NewStringUTF(hello.c_str()); }
其中extern “C”表示在编译的时候导出为c语言的格式,JNIEXPORT表示该函数是可以导出的,可以由外部方法进行调用,这和dll类似,jstring表示返回值,JNICALL关键字表示这是一个jni方法,Java_zqc_com_example_MainActivity_stringFromJNI其中Java是固定格式,zqc_com_example_MainActivity是全类名,stringFromJNI是具体的方法名,具体参数:JNIEnv env为env指针,调用jni的很多方法都需要该指针,jobject / this */这个表示当前类的this指针,这里因为没用到就没有命名。
在以往开发中可能是把.h和.cpp分开了,这个是AS自动生成的,这里并没有单独生成.h文件。c/c++开发也有自己的结构,这里除了需要对外暴露接口的需要按照上面格式编写外,其他的都可以用古老的c/c++进行编写并遵循古老的结构。你可以先定义.h文件,然后在.cpp里面具体实现。
点击Build->Make Project(快捷键Ctrl+F9)即可生成动态链接库文件.so,其路径在:
AS自动生成了Debug版和Release版,并且在各个版本中又生成了不同平台的.so文件。只能说这个AS太牛叉了~
之后运行工程,安装到手机上时就把对应的so也拷贝到了手机中了。
总结
目前应该是绝大多数人都采用AndroidStudio进行开发,谷歌官方已经不再对Eclipse的ADT进行维护了。而AS是绝对强大的工具,当你选择Include C++ Support的时候,AS会将NDK开发的一切都下载下来。所以如果采用AS开发,那么你学NDK开发的话,只需要把Android开发需要安装的JDK,SDK,AS等工具安装好后,即可进行开发。这个系列教程我也采用AS进行讲解。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Android NDK开发系列教程2:基本方法调用及传参
终于建了一个自己个人小站:https://huangtianyu.gitee.io,以后优先更新小站博客,欢迎进站,O(∩_∩)O~~ 1. 简介 有时候我写了个Java层的方法,希望native层也能够调用(尤其是一个实体类的get,set方法在native一般都会用到)。这在jni开发中也很常见,jni.h中也提供了很多方法。下面利用具体实例进行说明。这里直接使用AS3.0里面的CMake进行编译了,之后会讲解下Android.mk和Application.mk的用法和含义。这里我主要介绍一下几个: 1. java向native传递常用基本数据类型和字符串类型 2. java向native传递数组类型 3. java向native传递自定义java对象 4. java向native传递List对象 5. native向java返回字符串类型 6. native向java返回java对象 7. native向java返回数组类型 8. native向Java返回List对象 对于上面的每个都给出对应的例子。 本节所有案例代码均已放到GitHub上,欢迎下载: https://gith...
- 下一篇
Android NDK开发系列教程5:局部引用,全局引用,弱全局引用
终于建了一个自己个人小站:https://huangtianyu.gitee.io,以后优先更新小站博客,欢迎进站,O(∩_∩)O~~ 1. 简介 从Java虚拟机创建的对象当传入到native层时会产生一个引用,在进行垃圾回收时如果有native的引用,改对象同样也不会被回收。在native引用中分局部引用和全局引用。 1.1 局部引用 局部引用又称本地引用,大多数见到的引用都是局部引用,例如通过NewLocalRef和各种JNI接口创建(FindClass、NewObject、GetObjectClass和NewCharArray等),局部引用只会在本次native调用中有效,当本次调用结束后该引用即被自动释放。局部引用会阻止GC进行回收。同时也可以调用DeleteLocalRef函数来手动释放(比如在循环里面用到了局部引用而退出循环没有使用该局部引用,那么就需要在循环中释放该局部引用)。通常使用NewObject创建的实例返回的也是局部引用。千万不要把局部引用保存为c++的全局变量或者把它定义为静态变量,局部引用的有效期是一次Java本地调用。 JNI提供了一系列函数来管理局部引...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- 设置Eclipse缩进为4个空格,增强代码规范
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS8编译安装MySQL8.0.19
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- CentOS6,CentOS7官方镜像安装Oracle11G