一.介绍
NDK其实是提供了一系列的工具,帮助开发者快速开发C(或C++)的动态库,并能自动将so和java应用一起打包成apk。至于为什么要用NDK,一般都是出于一下几个原因:
1.代码的保护。由于apk的java层代码很容易被反编译,而C/C++库反汇难度较大。
2.可以方便地使用现存的开源库。大部分现存的开源库都是用C/C++代码编写的。
3.提高程序的执行效率。将要求高性能的应用逻辑使用C开发,从而提高应用程序的执行效率。
4.便于移植。用C/C++写得库可以方便在其他的嵌入式平台上再次使用。
二.准备
NDK包下载地址请参考此贴:http://www.cnblogs.com/yaotong/archive/2011/01/25/1943615.html
我选择的是 http://dl.google.com/android/ndk/android-ndk32-r10-windows-x86_64.zip
下载完ndk的zip包,我解压到D:\Android这个目录下了:
有了这个包包,就不用再安装什么cygwin了,因为这个ndk包里面集成了linux的编译功能。
三.步骤
1.在android studio里新建一个新项目,或者新建一个module
具体如何操作,本文不做详细介绍了。我是在已有的项目里面添加了一个新的android library类型的module,名称为cloudNDKTest。
2.环境配置
依次点击菜单栏File-->ProjectStructure,或者使用快捷键ctrl+alt+shift+s,然后如图操作
完成之后,会在local.properties文件中生成一下一个配置:
3.编写native方法
新建一个java文件,声明一个静态的native方法,方法红名也没有关系:
4.编译工程
执行make project,目的是编译成对应的class文件,后面生成.h文件的时候需要用上。
5.创建jni目录
将视图由Android切换成Project,在src/main目录下创建jni目录,和java目录同级
6.生成c++的.h文件
点击菜单栏View-->Tool Windows --> Terminal,或者快捷键Alt+F12,呼出终端窗口:
然后在Terminal窗口里执行以下命令:
cd cloudndktest/src/main
javah -d jni -classpath D:/Android/android-sdk/platforms/android-22/android.jar;../../build/intermediates/classes/debug com.tencent.XXX.XXX.cloudndktest.CloudNdkTest
其中,javah是生成头文件需要的工具,-d是指定文件创建的目录位置,-classpath是指定SDK文件下android.jar所在的文件位置。英文;后面的就是指定了步骤4生成的class文件
最后会生成:
7.编写cpp文件
在jni目录下创建cpp文件,不要勾选下面标红的部分,因为.h文件已经存在了。
编写cpp文件,include上边创建过的.h文件,实现具体函数。
8.编译
a. 先在module的build.gradle里面添加如下内容:
以上配置代码指定的so库名称为CloudNdkTest;链接时使用到的库,对应android.mk文件中的LOCAL_LDLIBS;以及最终输出指定三种abi体系结构下的so库。
b. 配置gradle.properties文件,添加
android.uesDeprecatedDNK=true
c. 在步骤3编写的java的class里面添加静态库的引用:
d. 如果遇到如下报错,请在jni目录下创建一个util.c的空文件,这据说是ndk的一个bug
e. 执行make project编译工程
四.注意事项
如果cpp的实现里面用到了stl的库,需要在8.a的步骤里添加:
目前支持以下几种编译链接方式:
stlport_static --> 以静态链接的方式使用stlport版本的STL
stlport_shared --> 以动态链接的方式使用stlport版本的STL
gnustl_static --> 以静态链接的方式使用gnu版本的STL
需要注意的是尽量通过静态库编译,这样不会造成多个module之间的so文件冲突,还能减小最后的包文件大小。
(本文作者:孙小阳)