Android JNI编程学习笔记(二)——深入了解NDK
来源:互联网 发布:lamb动作数据百度云 编辑:程序博客网 时间:2024/06/05 03:21
在上一章我们主要讲解了Android NDK开发环境及相关工具的配置,大家都知道Android NDK是一套原生代码开发的工具集,帮助开发人员能够使用原生编程语言(如C/C++/汇编)实现一些对代码性能要求比较高的模块,并将其嵌入到Android应用程序中。
本章的内容主要深入探讨Android NDK的组成,及一些Android Makefile文件的编写知识。(本章的内容主要参考:《Android C++ 高级编程-使用NDK》 和Android NDK官网主页)
Android NDK是一套综合工具集,包含API、交叉编译器、链接程序、调试器、构建工具、文档和示例应用。主要包含以下组件:
ARM 、X86 和 MIPS的交叉编译器
构建系统 (GUN Make)
Java原生接口头文件
C库
Math库
POSIX线程
最小的C++库
ZLib压缩库
动态链接库
Android日志库
Android像素缓冲区库( Android 2.2及以上版本)
Android原生应用APIs
OpenGL ES 3D图像库
OpenSL ES原生音频库
OpenMAX AL最小支持
Android NDK目录下一些重要的文件以及子目录:
ndk-build: 改shell脚本是Android NDK构建系统的起始点。ndk开发用的最多的脚本,每一次的构建都会用到它。
ndk-gdb: 改shell脚本允许用GNU调试器调试原生组件。 调试章节中会着重介绍。
ndk-stack:改shell脚本可以帮助分析原生组件崩溃时的堆栈追踪。 非常有用的脚本,在后续的调试章节中会着重介绍。
build:该目录包含了Android NDK构建系统的所有模块。
platforms: 该目录包含了支持不同Android 目标版本的头文件和库文件。
samples:该目录包含了一些示例应用程序,这些程序帮助你了解NDK开发,体验NDK的强大。
sources:该目录包含了可供开发人员导入到现有的Android NDK项目的一些共享模块。
toolchains:该目录包含目前Android NDK支持的不同目标机体系结构的交叉编译器。 目前支持:ARM X86 MIPS体系结构。
docs:该目录主要包含了一些介绍文档 以及参考资料。
Android NDK构建系统:
Android NDK的构建系统基于多种GUN Make片段构成。其主要目的使开发人员能够用很短的构建文档来描述原生的Android 应用程序;包括替开发人员制定的工具链,平台,CPU和ABI等很多细节。
组成NDK构建系统的片段可以在build/core子目录找到,知道它们的位置为以后构建系统的相关故障解决很有帮助。
Android.mk
Android.mk 隶属于GUN Makefile.向NDK编译器描述Android JNI项目的源码结构.是每一个NDK项目的必备组件.其位于jni子目录中.
经典的hello-jni项目下的Android.mk文件内容:
<pre name="code" class="html"># Copyright (C) 2009 The Android Open Source Project## Licensed under the Apache License, Version 2.0 (the "License");# you may not use this file except in compliance with the License.# You may obtain a copy of the License at## http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an "AS IS" BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License.#LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := hello-jniLOCAL_SRC_FILES := hello-jni.cinclude $(BUILD_SHARED_LIBRARY)
这是一个GUN Makefile片段,和其它Makefile基本是一样的. 以"#"开头的是注释行,GUN Make工具并不会处理.根据命名规范,变量名要大写.
LOCAL_PATH := $(call my-dir) 定义LOCAL_PATH变量.Android.mk文档必须以LOCAL_PATH变量的定义开头.
Android编译系统利用LOCAL_PATH定位源文件位置.Android提供了一个名为my-dir的宏功能.通过my-dir获取当前目录位置.
include $(CLEAR_VARS) 用于清除除了LOCAL_PATH以外的LOCAL_<name>变量,例如LOCAL_MODULE, LOCAL_SRC_FILES等等.
这样做主要是因为Android编译时 在单次执行中解析多个makefile文件 和 模块定义,而LOCAL_<name>是全局变量.清除它们可以避免冲突.
LOCAL_MODULE := hello-jni 利用LOCAL_MODULE给模块设定唯一的名称 hello-jni.本例中生成的是一个共享库,Android会为生成的文件添加适当的前缀 和 后缀.hello-jni模块最后会生成一个名为libhello-jni.so的文件.
LOCAL_SRC_FILES := hello-jni.c 指定了生成此模块所需要的源文件.
include $(BUILD_SHARED_LIBRARY) 指出模块最后生成的文件类型为动态库. Android NDK会将BUILD_SHARED_LIBRARY变量设置成build-shared-library.mk文件的存放位置.该makefile文件将源代码编译 和 组装成共享库的必要过程.
include $(BUILD_STATIC_LIBRARY) 最后生成静态库.Android应用程序并不直接使用静态库且应用程序包中也不包含静态库. 静态库主要用于提供功能,最后编译到其它动态库中.
include $(BUILD_EXCEUTABLE) 生成可执行文件,虽然会拷贝到libs目录下,但是并不会打包到apk文件中.可拷贝到android设备作为常规的linux应用程序执行.
Prebuilt库作用:
想在不发布源码情况下将模块发布给其他人使用.
提前编译好一些共享库,方便加速之后编译.
使用Prebuilt库:
虽然已经使用好,但是仍然需要提供一个Android.mk文件.
例如:
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := aLOCAL_SRC_FILES := liba.soinclude $(PREBUILT_SHARED_LIBRARY)此时并未做任何编译操作,只是把Prebuilt库复制到ndk 项目的libs目录下.ndk就可以像普通共享库一样使用Prebuilt库了.
LOCAL_SHARED_LIBRARIES := a
Application.mk
Application.mk是ndk中一个可选的文件. 和 Android.mk文件一样,也存放在jni目录下.Application.mk的目的是描述应用程序需要哪些模块;定义所有模块的通用变量等.
以下是Application.mk文件支持的变量:
APP_ABI:默认情况下,编译生成armeabi ABI的二进制文件,使用此变量可以为其它ABI生成二进制文件. 例如APP_ABI := x86 为x86设备生成二进制文件.
APP_MODULES:默认情况下,Android NDK编译Android.mk文件声明的所有模块. 该变量覆盖Android.mk的声明模块并提供一个用空格分开的,需要编译的模块列表.
APP_OPTIM:该变量可以设置为release 或 debug 以改变生成二进制文件的优化级别.默认是release模式,生成的二进制文件被高度优化. 此变量被设置为debug时生成更容易调试的未优化二进制文件.
APP_CPPFLAGS:此变量列出了一些编译器标志,在编译任何模块的C++源文件时标志会传给编译器.
APP_BUILD_SCRIPT:默认情况下,Android NDK会在项目的jni目录下查找Android.mk 然后编译. 可以使用改变量改变上述行为,并使用不同的生成文件.
APP_STL:默认情况下,Android NDK使用最小的STL运行库. 可以使用该变量选择不同的STL.
APP_GNUSTL_FORCE_CPP_FEATURES:声明所有模块都依赖于具体的C++特性,如RTTI, exceptions等.
APP_SHORT_COMMANDS:在大量的源文件情况下,使编译系统使用更短的命令.
使用NDK-BUILD脚本命令
执行ndk-build脚本启动编译Android jni项目. 该命令提供了一组参数方便维护 和 控制编译过程.
-C:默认情况下,nkd-build应该在主项目目录下执行.-C可以指定命令行中NDK项目的位置.使ndk-build命令可以在任何位置开始. ndk-build -C /path/to/the/project
-B:如果源码未修改,Android NDK就不会重编项目.可以用-B强制重新编译所有源码. ndk-build -B
clean: 清理生成的二进制文件和目标文件. ndk-build clean
-j n : 使在编译时并行编译. n代表了并行编译的命令总数 ndk-build -j 4
NDK_LOG=1 :启用内部状态日志功能.在编译时产生大量的日志,日志信息前缀是:Android NDK. 用于排除编译错误.
V=1 : 实际执行的构建命令.
NDK_DEBUG=1 : 生成可调试的本地代码.
- Android JNI编程学习笔记(二)——深入了解NDK
- Android JNI编程学习笔记(一)——NDK环境搭建
- Android JNI NDK 编程学习
- NDK---JNI学习步步深入之二
- 深入了解android平台的jni(二)
- 深入了解android平台的jni(二)
- 深入了解android平台的jni(二)
- 深入了解android平台的jni(二)
- 深入了解android平台的jni(二)
- 深入了解android平台的jni(二)
- JNI学习系列——深入了解JNI
- JNI学习系列——深入了解JNI
- NDK开发学习笔记—JNI入门
- Android NDK(学习笔记四)—— 在NDK开发中JNI打印Log信息
- JNI编程基础(二)——Android Studio NDK开发
- Android JNI + NDK 编程
- Android NDK (学习笔记二) —— 开发第一个Android NDK项目
- 深入了解android平台的jni(二)
- FFMPEG结构体分析 AVFrame
- 什么时间,开个博客
- ajaxfileupload文件上传返回值处理 ajaxfileupload.js + spring mvc文件上传
- hdu 4915 括号匹配+巧模拟
- hdu2203 KMP水题
- Android JNI编程学习笔记(二)——深入了解NDK
- Android中怎么使图片显示
- 数据结构之广义表(扩展线性链表)的基本操作
- Linux命令--ps
- MATLAB 基础
- js的语法
- 反转链表
- 【cocos2d-x游戏开发】坐标系详解
- VS调试技巧