1.1、NDK简介
1.1、NDK概述
NDK全称是Native Development Kit。NDK的发布,使“Java+C”的开发方式终于转正,成为官方支持的开发方式。NDK将是Android平台支持C开发的开端。
1、NDK优势
1.代码的保护。由于apk的java层代码很容易被反编译,而C/C++库反编译难度较大。
2.可以方便地使用现存的开源库。大部分现存的开源库都是用C/C++代码编写的。
3.提高程序的执行效率。将要求高性能的应用逻辑使用C开发,从而提高应用程序的执行效率。
4.便于移植。用C/C++写得库可以方便在其他的嵌入式平台上再次使用。
2、NDK简介
1.NDK是一系列工具的集合
NDK提供了一系列的工具,帮助开发者快速开发C(或C++)的动态库,并能自动将so和java应用一起打包成apk。NDK集成了交叉编译器,
并提供了相应的mk文件隔离CPU、平台、ABI等差异,开发人员只需要简单修改mk文件(指出“哪些文件需要编译”、“编译特性要求”等),就可以创建出so。
2.NDK提供了一份稳定、功能有限的API头文件声明
Google明确声明该API是稳定的,在后续所有版本中都稳定支持当前发布的API。从该版本的NDK中看出,这些API支持的功能非常有限,包含有:
C标准库(libc)、标准数学库(libm)、压缩库(libz)、 Log库(liblog)。
3、NDK目录结构
build:该目录存放的使用NDK的mk脚本,mk脚本指定了编译参数
docs:该目录存放的是NDK的使用帮助文档
platforms:这里面存放的是与各个Android版本相关的平台(x86,arm,mips)相关C语言库和头文件
prebuilt:预编译工作目录
samples:存放的是演示程序
sources:存放的是NDK工具链的C语言源码
tests:测试相关的文件
toolchains:工具链,存放了三种架构的静态库等文件
ndk-build.cmd:Window平台使用NDK的命令
ndk-build:Linux平台使用NDK的命令
1.2、Jni入门
1.windows->preferences->Android->NDK(输入ndk路径),再确定。
2.创建Android工程JNI入门,右键工程,找到Android Tools->点击add native support输入动态库名再确定。
3.此时,工程目录会出现jni文件夹,中间包含两个文件,并且我们还需要一些用到的头文件jni.h等。
4.导入头文件有两种方式:
a)进入NDK的目录,找到:D:\android-ndk-r10d\platforms\android-21\arch-arm\usr\include,下面有很多头文件,直接拷贝到eclipse的jni文件夹下即可。
b)直接配置导入所有的头文件,右键工程->properties->C/C++ General->Paths and Symbols->add->输入路径
总结:NDK版本下有三种不同的架构:
5.在MainActivity中定义native方法
6.在hello.cpp或hello.c等源文件下输入如下代码,其中的语法便不叙述
7.C代码中的命名规则(叙)
这里的命名规则指用于跟java文件中native方法对应的C语言方法,而C语言中的其他方法命名只要符合C语言规则就行。
jstring Java_com_itheima_jnihello_MainActivity_helloC(JNIEnv* env, jobject obj) 中,jstring是方法返回值类型,我们可以把jstring看成是java中String跟
C语言中char*类型的一个中间转换类型,java跟C语言的数据类型是不一样的,他们之间要想互相调用就必须通过一种中介来实现,这个中介就是在jni.h头文件中定义的。
关于更多的转换类型,在本文档的第2章会有更详细的说明。方法名第一个字母必须是Java,首单词大写,然后下划线_,然后是将该方法所在的包、类、方法用“_”连接起来,
比如com.itheima.jnihello.MainActivity类中的helloC方法,转变成C语言中的方法名为Java_com_itheima_jnihello_MainActivity_helloC。方法的形参有两个是必须的也就是
不管java中的方法是否有形参,但是C语言中对应的方法必须有JNIEnv* env,和jobject obj,如果java方法中还用其他形参,那么在C语言中严格按照顺序排在jobject obj参数
的后面即可。上面的env代表指向JVM的指针,obj是调用该方法的java对象。
8.首先查看NDK命令是否设置了环境变量,未设置则在Path中加入:D:\android-ndk-r10d
9.我们需要在工程中的jni目录中添加Android.mk配置文件。
10.在cmd中,将当前目录切换到hello.c所在目录,然后重新执行ndk-build.cmd命令,这次成功编译
11.发现在libs目录中多了两个文件夹armeabi和x86,这两个文件夹下分别包含了一个libhello.so动态链接库。这也代表着当前工程中的动态库支持arm架构和x86架构的cpu。
12.可能你的并没有同时生成这两个文件,是因为我的工程中引入了Application.mk文件,因此你需要在jni文件夹下引入该文件。
注:该清单其实只有一行内容,第一行是注释。APP_ABI参数指定要生成的目标文件支持的平台都有哪些,默认是armeabi如果想支持多个平台只需要空一格然后写出其他平台名字即可。
13.在MainActivity中调用C或C++语言
14.每次运行工程就会编译一次so文件,如果我们调用了外部so库的时候,编译时会自动删除外部so库。解决方法可以配置预编译或修改配置文件
1.百度搜索:android ndk如何取消"add native support" http://jingyan.baidu.com/article/380abd0a7309181d91192c55.html
2.配置预编译文件
libappsign.so has text relocations. This is wasting memory and is a security risk. Please fix.
翻译是:这个so库存在文字搬迁,这是一种消耗内存的操作,请修复。
导致这个问题产生的原因是因为使用了低版本的NDK编译的so文件导致的,是NDK中的一个bug。(目前找不到合理的解释)