[笔记分享] [Android] Android底层库和程序

4.1 介绍
主要介绍Android底层库和程序结构,以及C语言基础库、init可执行程序、shell工具、C++基础库、Android系统进程等内容。
Android是跨Java和native(c/c++)的框架,native部分除了做底层支持外,也做了上层支持。如binder和servicemanager部分,Android就针对native和Java分别提供了同样功能的接口。
Android基本的库和程序包括:
1.标准C/C++库 bionic
2.C语言工具库 libcutils
3.init进程
4.Shell工具
5.C++工具库

在介绍这些库和程序之间,我们先看看如何增加本地程序和库。

4.2 增加本地库和程序
增加本地库和程序,与其路径无关系,值和它们各自的Android.mk文件有关。
Android.mk和普通Makefile不同,前者具有统一的写法,主要包含一些系统宏。
Android.mk选项参考文件路径:
build/core/config.mk
而这些选项的默认值在以下文件路径:
build/core/base_rules.mk
一个Android.mk中可以生成多个可执行程序、动态或者静态库。模板如下:
[笔记分享] [Android] Android底层库和程序

LOCAL_SRC_FILES: 需要编译的文件
LOCAL_MODULE: 生成的文件名
LOCAL_C_INCLUDES:包含的头文件
LOCAL_STATIC_LIBRARIES: 要包含的静态文件
LOCAL_SHARED_LIBRARIES: 要包含的动态文件
include $(BUILD_EXECUTABLE):生成何种类型的文件,包括可执行程序、静态和动态库。

下面在看静态和动态库如何生成:
静态库生成:
[笔记分享] [Android] Android底层库和程序

动态库生成:

[笔记分享] [Android] Android底层库和程序
注意,在Android中不需要对C或C++源文件进行区分,统一加入LOCAL_C_FILES即可。

生成的目标文件放在以下目录:
[笔记分享] [Android] Android底层库和程序

前面我们讲了目标程序的编译方法,如下:
[笔记分享] [Android] Android底层库和程序
我们再看看主机程序的编译方法,如下:
[笔记分享] [Android] Android底层库和程序

我们也可以指定最后的目标安装路径,使用LOCAL_MODULE_PATH和LOCAL_UNSTRIPPED_PATH这两个宏,分别代表最终目标路径和未经符号分离的目标路径。
不同文件系统路径用下面宏选择:
[笔记分享] [Android] Android底层库和程序
然后我们再看例子:
[笔记分享] [Android] Android底层库和程序

当未指定LOCAL_MODULE_PATH时,默认宏为TARGET_ROOT。对于静态库,不会在目标文件系统中出现,也不存在指定目标路径的问题。

另外,我们也可用Android.mk来创建或复制文件。下面例子实现了system/下创建目录txt和将A.txt和B.txt复制到system/txt目录下。
[笔记分享] [Android] Android底层库和程序

4.3 标准C/C++库bionic
Bionic相对于传统的标准库如glibc来说体积和内存占用更小,支持数学库和NTPL线程库,还实现了自己的linker及loader,用于动态库的创建和加载。
此外,它还加入一些Android一些特有功能,如Log底层支持。还实现了property系统,这是整个Android全局变量的存储区域,bionic使用共享内存的方式实现property系统。

4.4 C语言工具库 libcutils
基本上所有本地库和程序都连接了这个库。主要头文件如下:
[笔记分享] [Android] Android底层库和程序

以上功能一般都是调用Linux标准库封装,如套接字调用Linux标准的socket,线程调用POSIX线程pthread实现。

4.5 init可执行程序和init.rc
init进程是Android启动后第一个系统执行的可执行程序,以守护进程的方式运行。提供了以下功能:
1. 设备管理
2. 解析启动脚本init.rc

目录: /system/core/init/
关于init执行的流程大家可自行分析,这里就不介绍了,不过有一点要注意的是,在做设备开发时,其中我们需要修改的地方就是devperms数组,如下:
[笔记分享] [Android] Android底层库和程序
如果在系统需要增加新的驱动程序的时候,并且设备节点需要自动创建,那么也需要在这个数组中增加相应的内容。

另外一个要说的是init.rc,在init程序执行的过程中会解析这个脚本。这个脚本可以在系统初始化过程中进行一些简单的初始化操作。
目录: /system/core/rootdir/init.rc
下面是脚本包含的语法:
1. 命令
如 mount yaffs2 [email protected] /system中,mount就是命令。
命令的关键字可从/system/core/init/keyword.h中获取。
2. 动作
如 on init
Mkdir /system
中, on init是触发条件, mkdir是动作
3. 触发
如上所述。
4. 服务
如service bootsound /system/bin/playmp3中, boot表示服务名称, 后者表示可执行程序。
5. 选项
如service bootsound /system/bin/playmp3
Oneshot
中, oneshot表示只启动一次
6. 属性

4.6 C++工具库 libutils
Android层次的本地C/C++程序和库,大都基于libutils开发。

4.7 系统进程
几个重要系统进程为/init、 /system/bin/servicemanager、 /system/bin/mediaserver、 system_server及zygote。
后面的进程都是通过init解析init.rc启动的,system_server通过zygote复制出来。