第10章AndroidNDK开发本章学习目标:了解AndroidNDK的用途掌握AndroidNDK编译环境的安装与配置方法掌握AndroidNDK的开发方法10.1NDK简介AndroidNDK(AndroidNativeDevelopmentKit)是一系列的开发工具,允许程序开发人员在Android应用程序中嵌入C/C++语言编写的非托管代码AndroidNDK优势解决了核心模块使用托管语言开发执行效率低下的问题允许程序开发人员直接使用C/C++源代码,极大的提高了Android应用程序开发的灵活性AndroidNDK不足增加程序的例如信号处理或物理仿真)使用非托管代码运行效率最高,复杂性,增加了程序调试的难度CPU运算量大和内存消耗较少的部分(因此并不是所有的核心部分都适合使用C/C++语言编写10.1NDK简介AndroidNDKAndroidNDK的版本是1.5,集成了交叉编译器,支持ARMv5TE处理器指令集、JNI接口和一些稳定的库文件AndroidNDK仅支持AndroidSDK1.5版本,因此1.0和1.1版本的应用程序不能够使用AndroidNDKAndroidNDK提供一系列的说明文档、示例代码和开发工具,指导程序开发人员使用C/C++语言进行库文件开发,并提供便捷工具将库文件打包到apk文件中10.2NDK编译环境AndroidNDK编译环境支持WindowsXP、Linux和MacOS,本书仅介绍Windows系统的编译环境配置方法Windows系统的编译环境配置方法下载AndroidNDK的安装包下载并安装Cygwin配置Cygwin的NDK开发环境测试开发环境是否可以正常工作10.2NDK编译环境下载AndroidNDK的安装包在Google的官方网站下载AndroidNDK的安装包,下载地址是,打开下载页面后选择的下载文件为android-ndk-1.5_r1-windows.zip10.2NDK编译环境下载AndroidNDK的安装包将下载的ZIP文件解压缩到用户的Android开发目录中,作者将AndroidNDK解压到E:\Android目录中,ZIP文件中包含一层目录,因此AndroidNDK的最终路径为E:\Android\android-ndk-1.5_r110.2NDK编译环境下载并安装CygwinAndroidNDK目前还不支持在Windows系统下直接进行交叉编译,因此需要在Windows系统下安装一个Linux的模拟器环境Cygwin,完成C/C++代码的交叉编译工作AndroidNDK要求GNUMake的版本高于或等于3.18,之前的版本并没有经过测试,因此需要安装较新版本的CygwinCygwin的最新版本可以到官方网站下载,也可以到中文的映像网站编译环境下载并安装Cygwin在Cygwin的安装过程中,需要将Devel下的gcc和make的相关选项选上,否则Cygwin将无法编译C/C++代码文件10.2NDK编译环境配置Cygwin的NDK开发环境在缺省情况下,Cygwin安装在C盘的根目录下,修改C:\cygwin\home\username\.bash_profile文件,username会根据用户使用的用户名称而变化在.bash_profile文件的结尾处添加如下代码上面的代码说明了AndroidNDK所在的目录,目录是e盘android/android-ndk-1.5_r1如果AndroidNDK安装在c盘的TestAndroid/android-ndk-1.5_r1中,则上面的代码则应该为ANDROID_NDK_ROOT=/cygdrive/e/android/android-ndk-1.5_r1exportANDROID_NDK_ROOTANDROID_NDK_ROOT=/cygdrive/c/TestAndroid/android-ndk-1.5_r1exportANDROID_NDK_ROOT10.2NDK编译环境测试开发环境是否可以正常工作首先启动Cygwin,然后切换到AndroidNDK/build目录中,运行host-setup.sh文件如果运行结果如下图,说明AndroidNDK的开发环境已经可以正常工作了AndroidNDK的编译环境已经安装配置完毕10.2NDK编译环境AndroidNDK的目录结构在android-ndk-1.5_r1目录中,包含5个子目录和2个文件apps目录是Android工程的保存目录,子目录hello-jni和tow-libs是NDK自带的两个示例目录build目录保存了交叉编译工具、编译脚本和配置文件docs目录是帮助文档的保存目录out目录是交叉编译的输出目录,保存输出的so文件(+)apps(+)hello-jni(+)tow-libs(+)build(+)docs(+)out(-).gitignore(+)sources(+)samples(+)hello-jni(+)tow-libs(-)Android.mk(-)GNUmakefile(-)README.TXT10.2NDK编译环境AndroidNDK的目录结构sources目录是C/C++源代码文件的保存目录,其下的hello-jni和tow-libs子目录,分别保存了NDK自带示例所需要的C/C++源代码文件GNUmakfile文件和README.TXT文件分别是make工具的配置文件和NDK的说明文件(+)apps(+)hello-jni(+)tow-libs(+)build(+)docs(+)out(-).gitignore(+)sources(+)samples(+)hello-jni(+)tow-libs(-)Android.mk(-)GNUmakefile(-)README.TXT10.2NDK编译环境AndroidNDK的目录结构docs目录中的帮助文件说明文件名说明INSTALL.TXTNDK的安装与配置说明文档OVERVIEW.TXTNDK的用途和使用范围的说明文档ANDROID-MK.TXTAndroid.mk文件的说明文档,Android.mk文件定义了需要编译的C/C++源代码APPLICATION-MK.TXTApplication.mk文件的说明文档,Application.mk文件定义了Android工程需要调用的C/C++源代码HOWTO.TXT关于NDK开发的一般性信息SYSTEM-ISSUES.TXT使用NDK开发时所需要注意的问题STABLE-APIS.TXTNDK头文件所支持的稳定的API类表10.2NDK编译环境AndroidNDK自带两个示例hello-jni和tow-libshello-jni是一个非常简单的例子,非托管代码实现了一个可以返回字符串的共享库,Android工程调用这个共享库获取字符串,然后显示在用户界面上tow-libs是稍微复杂一些的例子,使用非托管代码实现了一个数学运算的共享库,Android工程动态加载这个共享库,并调用其中的函数,函数功能是通过使用静态库实现的10.3NDK开发示例在进行NDK开发时,一般需要同时建立Android工程和C/C++工程,然后使用NDK编译C/C++工程,形成可以被调用的共享库,最后共享库文件会被拷贝到Android工程中,并被直接打包到apk文件中后面的内容将AndroidNdkDemo示例说明如何进行AndroidNDK开发AndroidNdkDemo是一个进行加法运算的示例,程序会随机产生两个整数,然后调用C语言开发的共享库对这两个整数进行加法运算,最后将运算结果显示在用户界面上10.3NDK开发示例AndroidNdkDemo示例的界面进行AndroidNDK开发一般要经过如下的步骤建立Application.mk文件建立Android工程建立Android.mk文件建立C源代码文件编译共享库模块10.3NDK开发示例建立Application.mk文件建立步骤在apps目录中建立应用程序目录,AndroidNdkDemo示例的应用程序目录为ndk-demo在ndk-demo目录中建立一个空目录project,这个目录以后会用来存放Android工程在ndk-demo目录中建立一个名为Application.mk的文件,用来描述Android工程将调用的共享库AndroidNdkDemo示例的目录结构(+)apps(+)ndk-demo(+)project(-)Application.mk10.3NDK开发示例建立Application.mk文件在进行NDK开发时,在应用程序目录中一定要有Application.mk文件,用来声明Android工程需要调用的非托管模块(如静态库或共享库)AndroidNdkDemo示例的Application.mk的代码如下第1行的变量APP_PROJECT_PATH表示Android工程所在的目录,在生产共享库文件后,APK将自动将共享库文件拷贝到app\libs\armeabi目录中,本示例将共享库文件拷贝到apps\ndk-demo\project\libs\armeabi目录中1.APP_PROJECT_PATH:=$(callmy-dir)/project2.APP_MODULES:=add-module10.3NDK开发示例建立Application.mk文件第2行代码中的变量APP_MODULES表示Android工程需要调用的非托管模块,如果存在多个非托管模块,使用空格进行分隔。本示例调用的非托管模块为add-module,对应在后面涉及的Android.mk文件Application.mk的变量说明变量强制使用说明APP_PROJECT_PATH是Android工程所在的目录APP_MODULES是Android工程需要调用的非托管模块APP_OPTIM否指定优化等级,包含两个等级debug和release,release是缺省设置。debug生产非优化代码,更加易于调试APP_CFLAGS否编译C代码时所传递的编译器标志APP_CXXFLAGS否编译C++代码时所传递的编译器标志APP_CPPFLAGS否编译C/C++代码时所传递的编译器标志10.3NDK开发示例建立Android工程在project目录中建立Android工程时,需要取消复选框“Usedefaultlocation”,并指定预先建立的project文件夹作为工程文件夹在建立AndroidNdkDemo工程后,修改main.xml文件,添加一个id为display的TextView和一个id为add_btn的Button按钮10.3NDK开发示例建立Android工程程序中的生产随机数和调用的代码在AndroidNdkDemo.java文件中,下面是AndroidNdkDemo.java文件的核心代码1.publicclassAndroidNdkDemoextendsActivity{2.@Override3.publicvoidonCreate(BundlesavedInstanceState){4.super.onCreate(savedInstanceState);5.setContentView(R.layout.main);6.finalTextViewdisplayLable=(TextView)findViewById(R.id.display);7.Buttonbtn=(Button)findViewById(R.i