为IA上的NDK驱动的Android*应用程序创建和移植





4.00/5 (1投票)
本文档是对为Intel®架构(IA)设备创建原生(基于NDK)Android*应用程序的初学者介绍。
目标
本文档是对为Intel®架构(IA)设备创建原生(基于NDK)Android*应用程序的初学者介绍。我们还将讨论将为其他架构设备创建的NDK Android应用程序移植到IA设备。我们将通过两种场景进行介绍:一种是演示从头到尾创建基本NDK Android*应用程序的过程,另一种是展示将现有NDK Android应用程序移植到IA设备以供使用的简单过程。
目录
2. 为基于IA的设备创建基于NDK的Android应用程序 - 简单应用程序演练
a. 创建默认Android项目
b. 从Java源代码调用原生代码
c. 使用javah生成原生代码的JNI头文件存根
d. 使用NDK为IA构建原生代码
e. 重新构建、安装和运行基于IA的Android NDK应用程序
3. 使用x86 NDK工具集将现有NDK应用程序移植到基于IA的设备
引言
Android应用程序可以使用原生开发工具包(NDK)工具集来集成原生代码。它允许开发人员重用遗留代码、进行低级硬件编码,或通过利用其他方式不易实现或不可能实现的功能来区分其应用程序。
本文档是对如何从头到尾为IA创建基于NDK的应用程序的基本介绍,以及将现有基于NDK的应用程序移植到基于IA的设备的简单用例。我们将通过一个简单的分步应用程序开发场景来演示该过程。
我们假设您已经安装了Android开发环境,包括Android SDK、Android NDK,并配置了emulator-x86来测试应用程序。有关更多信息,请参阅Intel网站上的Android社区部分。为了保持我们的开发环境简单,我们将主要使用Linux*命令行工具。
为基于IA的设备创建基于NDK的Android应用程序 – 简单应用程序演练
假设我们有一些使用C和汇编语言解析CPUID的遗留代码(有关CPUID的更多信息,请参阅http://en.wikipedia.org/wiki/CPUID*)。下面是我们“遗留”示例C代码cpuid.c的源代码列表(仅用于演示)。
我们希望从Android应用程序中调用cpuid_parse(仅用于演示 - cpuid_parse函数需要预先分配的缓冲区),并在应用程序内显示输出。
下面将逐步介绍如何从头到尾创建一个Android应用程序,并使用上述遗留原生代码。
1. 创建默认Android项目
Android SDK提供了命令行工具来为典型的“hello world”应用程序生成默认项目结构。我们将首先创建一个默认项目,然后修改Java源代码以添加JNI调用和原生代码。
在上图所示的截图中,我们首先创建了一个名为labs/lab2的目录,并使用“android”命令行工具生成了默认项目。我们指定android-15作为API级别,并将应用程序命名为“CPUIdApp”,包名为com.example.cpuid。
然后,我们使用“ant”命令行工具以debug模式构建项目,并使用“adb”安装(如果模拟器或目标设备上已存在,则重新安装)。我们假设您已经连接了模拟器或设备,并且它是“adb devices”命令输出中唯一列出的设备。
下图显示了完成上述过程后,Android x86模拟器上运行的ICS。
点击应用程序,您可以看到应用程序的默认“hello world”输出。现在我们将修改该应用程序以使用原生代码。
2. 从Java源代码调用原生代码
默认的Android项目会生成一个典型的“hello world”项目的Java源代码,并提供指定的包命名空间(例如:com.example.cpuid)。下图显示了主Java源代码文件生成的源代码。
为了在我们的Java源代码文件中使用原生c/c++代码,我们首先需要声明JNI调用并加载原生库,如下图所示的黄色框突出显示的部分。
从声明中可以看到,原生调用返回一个Java字符串,我们可以在Java源代码中的任何位置使用它。如上图所示,我们修改了TextView以显示从原生调用中获得的字符串。这在框中用红色突出显示。
这是一个在Android应用程序Java源代码中声明和使用JNI原生调用的非常简单的例子。接下来,我们将使用“javah”工具生成原生代码的JNI头文件存根,并添加或修改原生代码以符合JNI原生头文件。
3. 使用“javah”生成原生代码的JNI头文件存根
现在我们需要修改我们的原生代码以符合JNI调用规范。“javah”工具可以帮助我们根据Java源文件自动生成适当的JNI头文件存根。“javah”工具需要编译后的Java类文件来生成头文件。因此,我们使用“ant”工具快速生成Java类文件,如下图所示(“ant debug”)。
使用“javah”生成jni头文件,如截图所示(第二个黄色高亮框)。它将创建一个“jni”目录以及基于Java类的头文件存根。下图显示了生成的JNI原生头文件存根。
为上述生成的头文件创建相应的C源代码文件(“com_example_cpuid_CPUIdApp.c”)。下面是源代码列表。
我们调用原生代码cpuid_parse,并将解析后的缓冲区作为JNI字符串返回。现在我们可以使用x86 NDK工具集来编译原生代码了。
4. 使用NDK为x86构建原生代码
有关NDK for IA安装和使用的更多信息,请参阅Intel网站上的Android社区部分(http://software.intel.com/en-us/android/articles/ndk-for-ia)。
Android NDK工具集使用一个构建系统,该系统要求在项目“jni”文件夹中存在一个自定义的、特定于Android的Makefile“Android.mk”来编译原生代码。Android.mk指定了所有要编译的原生C/C++源文件、头文件以及构建类型(例如:shared_library)。
下面是我们的项目(“jni/Android.mk”)的原生代码Android Makefile列表。
这是一个包含2个C源文件的简单场景,并指定构建一个共享库。
我们现在可以发出“ndk-build APP_ABI=x86”来构建我们的原生代码,并生成共享库。Android构建系统还提供了另一个补充Makefile“Application.mk”,我们可以用它来指定附加的配置选项。例如,我们可以在Application.mk文件中指定所有支持的ABI,然后ndk-build将为所有目标生成原生共享库。
上图显示了为x86成功编译原生代码,并显示了生成和安装的共享库。现在我们可以重新构建我们的Android应用程序,并在x86模拟器或目标设备上安装/运行。
5. 重新构建、安装和运行基于IA的Android NDK应用程序
我们可以使用“ant debug clean”来清除旧的构建文件,然后再次发出“ant debug”来开始对Android项目进行完全重建。使用“adb”将应用程序重新安装到目标设备或x86模拟器上,如以下截图所示。
下图显示了x86模拟器内的应用程序图标,以及在x86模拟器内运行该应用程序的结果。
我们已经成功地从头到尾构建了一个基于NDK的Android应用程序。
使用x86 NDK工具集将现有NDK应用程序移植到基于IA的设备
包含原生代码的Android应用程序通常具有标准的项目结构,“jni”文件夹包含原生源代码,以及相应的Android.mk/Application.mk构建文件。在上一节中,我们看到了一个包含原生源代码和相应Android.mk文件的简单示例。
Android NDK工具集允许我们在Application.mk中一次性指定所有目标ABI,并自动为所有目标生成原生共享库。Android构建系统将自动将所有目标原生库打包到APK中,并在安装时,Android包管理器将仅根据目标架构安装适当的原生库。
我们可以调用“ndk-build”或在Application.mk中指定
APP_ABI := all
或者
APP_ABI := armeabi armeabi-v7a x86
有关更多信息,请参阅https://developer.android.com.cn/sdk/ndk/index.html。
对于大多数情况(如上所述),将一个当前不针对x86的原生代码Android应用程序移植到支持IA的过程非常简单——除非该应用程序使用了特定于架构的汇编语言或构造。可能还会存在其他问题,如内存对齐或平台特定指令的使用。有关更多详细信息,请参阅http://software.intel.com/en-us/android/articles/ndk-android-application-porting-methodologies。
摘要
本文档讨论了创建和移植基于NDK的Android应用程序以针对IA。我们通过一个逐步过程来演示从头到尾创建基于NDK的应用程序以使用IA的过程。我们还讨论了NDK工具集提供的简单过程,以便将现有的基于NDK的Android应用程序移植到针对IA。
注意事项
Intel是Intel Corporation在美国和其他国家/地区的商标。
本文档中的信息是为配合Intel产品提供的。本文档不授予任何知识产权的任何明示或暗示、禁止反言或以其他方式的许可。除Intel产品销售条款和条件中另有规定外,Intel不承担任何责任,并且Intel不就Intel产品的销售和/或使用承担任何明示或暗示的保证,包括对特定用途的适用性、适销性或对任何专利、版权或其他知识产权的侵权责任或保证。
“关键任务应用程序”是指Intel产品故障可能直接或间接导致人身伤害或死亡的任何应用程序。如果您为任何此类关键任务应用程序购买或使用Intel的产品,您应赔偿Intel及其子公司、分包商和关联公司以及上述各方的董事、高级职员和员工,使其免受因产品责任、人身伤害或死亡索赔而直接或间接引起的所有索赔、成本、损害和费用以及合理的律师费,无论Intel或其分包商在Intel产品或其任何部件的设计、制造或警告方面是否存在疏忽。
Intel可能随时更改规格和产品说明,恕不另行通知。设计人员不得依赖未标记为“保留”或“未定义”的任何功能或指令的缺席或特性。Intel保留这些供将来定义的权利,并且不对因其未来更改而引起的任何冲突或不兼容性承担任何责任。此处的信息如有更改,恕不另行通知。请勿根据这些信息最终确定设计。
本文档中描述的产品可能包含已知为勘误的设计缺陷或错误,这可能导致产品偏离已发布的规范。当前的已表征勘误可应要求提供。
请联系您当地的英特尔销售办事处或您的经销商以获取最新的规范,并在下订单前进行咨询。
通过致电1-800-548-4725或访问http://www.intel.com/design/literature.htm,可以获取带有订单号并在此文件中引用的文档副本或其他Intel文献。
* 其他名称和品牌可能被声明为他人财产。
版权所有 © 2012 Intel Corporation。保留所有权利。