Android基本架构学习
希望通过这篇文档能够了解到,基于Android代码的开发过程中,什么是Android自带的文件夹,我们的开发在哪,我们开发的程序需要遵循哪些“规则”,架构?而且这些 资料可以从哪获取?
Android架构
Android系统架构从上到下分为五层:应用层、应用架构层、系统运行库层、硬件抽象层和Linux内核层。
应用层:直接与用户交互,可以是系统应用程序、第三方应用程序。Java开发。
应用框架层API:API.提供给基于安卓系统进行开发的开发人员一套API,也是Java写的。
系统运行层:分成两部分C/C++库、Android运行时库(ART环境)。
硬件抽象层HAL / HIDL:目的在于将硬件抽象化,为了保护硬件厂商的知识产权,它隐藏了特定平台的硬件接口细节,为操作系统提供虚拟硬件平台,使其具有硬件无关性,可在多种平台上进行移植。
Linux内核层:Android 的核心系统服务基于Linux 内核,在此基础上添加了部分Android专用的驱动。
Android源码目录
源码根目录
Android源码根目录 | 描述 |
---|---|
abi | 应用程序二进制接口 |
art | 全新的ART运行环境(Android运行时库的代码放在art/目录中) |
bionic | 系统C库 |
bootable | 启动引导相关代码 |
build | 存放系统编译规则及generic等基础开发包配置 |
cts | Android兼容性测试套件标准 |
dalvik | dalvik虚拟机 |
developers | 开发者目录 |
development | 应用程序开发相关 |
device | 设备相关配置 |
docs | 参考文档目录 |
external | 开源模组相关文件 |
frameworks | 应用程序框架,Android系统核心部分,由Java和C++编写 |
hardware | 主要是硬件抽象层的代码(硬件抽象层的代码在hardware/目录中,这部分是手机厂商改动最大的一部分) |
libcore | 核心库相关文件 |
libnativehelper | 动态库,实现JNI库的基础 |
ndk | NDK相关代码,帮助开发人员在应用程序中嵌入C/C++代码 |
out | 编译完成后代码输出在此目录 |
packages | 应用程序包 |
pdk | Plug Development Kit 的缩写,本地开发套件 |
platform_testing | 平台测试 |
prebuilts | x86和arm架构下预编译的一些资源 |
sdk | sdk和模拟器 |
system | 底层文件系统库、应用和组件 |
toolchain | 工具链文件 |
tools | 工具文件 |
Makefile | 全局Makefile文件,用来定义编译规则 |
应用层目录packages
开发者的程序、系统程序都在这个目录下。
packages目录 | 描述 |
---|---|
apps | 核心应用程序 |
experimental | 第三方应用程序 |
inputmethods | 输入法目录 |
providers | 内容提供者目录 |
screensavers | 屏幕保护 |
services | 通信服务 |
wallpapers | 墙纸 |
应用框架层目录
应用框架层是系统的核心部分,一方面向上提供接口给应用层调用,另一方面向下与C/C++程序库以及硬件抽象层等进行衔接。 应用框架层的主要实现代码在/frameworks/base和/frameworks/av目录下,其中/frameworks/base目录结构如表:
/frameworks/base目录 | 描述 |
---|---|
api | 定义API |
cmds | 重要命令:am、app_proce等 |
core | 核心库 |
data | 字体和声音等数据文件 |
docs | 文档 |
graphics | 图形图像相关 |
include | 头文件 |
keystore | 和数据签名证书相关 |
libs | 库 |
location | 地理位置相关库 |
media | 多媒体相关库 |
native | 本地库 |
nfc-extras | NFC相关 |
obex | 蓝牙传输 |
opengl | 2D/3D 图形API |
packages | 设置、TTS、VPN程序 |
sax | XML解析器 |
services | 系统服务 |
telephony | 电话通讯管理 |
test-runner | 测试工具相关 |
tests | 测试相关 |
tools | 工具 |
wifi | wifi无线网络 |
Android四大组件
Activity
Activity是什么
对应着应用的一个个界面。Activity实现了Window.Callback
和KeyEvent.Callback
两个接口,所以用户通过屏幕点击或点击按键可以和Activity交互。创建Activity就是继承Activity创建,必须在清单文件注册.
Activity调用
activity的切换:
intent.setClass(目前的acitivy.this, 目标activity.class);
Android通信机制
进程间通信:Binder
1 Binder是什么
Binder是一种进程间通信IPC的机制,Binder就是Android中的血管,在Android中我们使用Activity,Service等组件都需要和AMS(system_server)进行通信,这种跨进程的通信都是通过Binder完成。
2 为什么用Binder
- Binder相对于传统的Socket方式,更加高效.
- Binder数据拷贝只需要一次,而管道、消息队列、Socket都需要2次,共享内存方式一次内存拷贝都不需要,但实现方式又比较复杂。
3 Binder通信模型
- Client进程:使用服务的进程。
- Server进程:提供服务的进程。
- ServiceManager进程:ServiceManager的作用是将字符形式的Binder名字转化成Client中对该Binder的引用,使得Client能够通过Binder名字获得对Server中Binder实体的引用。
- Binder驱动:驱动负责进程之间Binder通信的建立,Binder在进程之间的传递,Binder引用计数管理,数据包在进程之间的传递和交互等一系列底层支持。
4 Binder运行机制
- 注册服务(addService):Server进程要先注册Service到ServiceManager。该过程:Server是客户端,ServiceManager是服务端。
- 获取服务(getService):Client进程使用某个Service前,须先向ServiceManager中获取相应的Service。该过程:Client是客户端,ServiceManager是服务端。
- 使用服务:Client根据得到的Service信息建立与Service所在的Server进程通信的通路,然后就可以直接与Service交互。该过程:Client是客户端,Server是服务端。
同一应用不同组件:广播
LocalBroadcastManager
LocalBroadcastManager是Android Support包提供了一个工具,用于在同一个应用内的不同组件间发送Broadcast。在LocalBroadcastManager构造函数中创建了一个Handler.LocalBroadcastManager 的本质上是通过Handler机制发送和接收消息的。
-
LocalBroadcastManager对象的创建
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance( this ) ; -
注册广播接收器
LocalBroadcastManager.registerReceiver( broadcastReceiver , intentFilter ); -
发送广播
LocalBroadcastManager.sendBroadcast( intent ) ;
注意UserHandle.ALL包含了所有用户,而OWNER仅仅是设备持有者(注意guest用户)。
.Stub
stub类是为了方便client,service交互而生成出来的代码。AIDL(Android Interface Definition Language Android接口定义语言)实现进程间通信,尤其是在涉及多进程并发情况下的进程间通信。aidl会在gen中自动生成一个同名的IaidlData.java接口文件,该接口文件包含一个抽象类stub,其继承了android.os.Binder、实现IaidlData接口故,我们实际需要实现的是Stub抽象类。
交互过程:client<–>proxy<–>stub<–>service
stub和proxy是为了方便client/service交互而生成出来的代码,这样client/service的代码就会比较干净,不会嵌入很多很难懂的与业务无关的代码
Activity之间的通信:传递Intent
通过Data只能传输比较简单的数据,Intent主要通过Extra完成组件之间的数据传递。我们分析Android代码可以发现,其实通过Exctra传递的是一个Bundle,我们可以把Bundle理解成一个键值对,他通过putXXX设置数据,通过getXXX读取数据。
Message是主线程和子线程之间的通信,比如通过UI界面来控制播放器,那UI界面就是主线程,播放器可能是另起的一个线程,通过检测UI的动作来控制播放器,就可以发送一个消息。