
同为Linux系操作系统,安卓与其他的兄弟姐妹们大相径庭。安卓是为嵌入式设备设计的,这些设备的各种资源比如内存、算力、电量都很紧张,这使得安卓除了系统内核外有着独特的软件架构
安卓系统层级结构
安卓可以被抽象成一个简略的层级结构
- 内核层:针对嵌入式设备修改过的Linux内核,有特权的代码
- 系统服务层:一大堆服务于系统的软件,比如驱动、内核模块、守护进程,以及一些编程常用的标准库
- ARE层(Android Runtime Environment):提供安卓应用的运行环境,包括安卓开发用到的库
- 应用层:用户能直接使用的应用
安卓应用解剖
和桌面应用的不同,安卓应用并不是一个简单的进程,也没有类似Javapublic static void main
以及C++int main
的程序入口。其结构更像是一个Web应用,由一堆散装的组件蓝图构成,然后由一个系统服务 – Zygote – 根据需要进行生成、管理以及销毁。
四大组件类型
Activity
每个Activity组件负责一个单独的可交互的UI页面,这些页面由一个个小部件构成。安卓只保证Activity在对应页面可见时存在。
Activity的生命周期长这样
onCreate
:这个时间点页面刚刚被生成,适合初始化页面相关变量以及视图onDestroy
:页面实例被销毁,安卓不保证App退出的时候这个方法一定被调用,因为有时应用是直接被kill -9
干掉的onStart
:页面已被绘制出来但无法接受用户输入,比如中间跳出弹窗或者其他app页面的时候onResume
:页面被聚焦且开始和用户交互了
Service
Service可以被看作成一个没有UI的Activity,但没有除了onCreated
以及onDestroyed
之外的方法
Service有两个子类 – Bounded Service 和 Started Service
Started Service
多用于完成一次性的任务,比如放个东西进数据库或者发个信息到网上
Bounded Service
类似Linux的pipe,安卓专属的IPC机制,提供一个半双工信道(支持双向传输但两个方向不能同时)– Binder – 来支持两个端点的通信,可跨应用
Broadcast Receiver
类似JS的事件侦听器,可以捕获重要的系统事件,比如可以在系统启动后广播的android.intent.action.BOOT_COMPLETED
注册一个Receiver来实现开机自启
Content Provider
本质上是数据源(内容)上方的一层REST API,可以被用来共享一个打开的文件到另一个组件,有增删改查四个接口insert(), delete(), update(), query()
外加一个内容数据类型查询getType()
Manifest文件
所有组件必须在一个叫AndroidManifest.xml
的文件里声明,比如
1 | <manifest ...> |
Context
Context是容纳Component或者是App的容器,可以在传参的时候用来指定组件和应用
Component Context
Activity和Service都继承于Context类,可以通过this
直接获取目前组件实例对应的Context。此外,还可以通过startActivity()
以及startService()
等方法来唤醒其他的Activity或是Service
Application Context
在应用启动后会产生一个ApplicationContext单例,其生命周期与应用的生命周期相绑定,且在任意其他Context下都可以调用Context.getApplicationContext()
被获取到。但与组件Context不同的是,其startActivity方法一般无法被用来唤醒Activity,强行调用会出现报错。
可以新建一个类去继承Application Context
1 | class MyApp : Application() { |
修改一下Manifest文件让系统知道这个class代表Application
1 | <manifest ...> |
Intent
Intent可以被看作是组件之间交换信息的数据包,包含了发送方期望请求方完成的操作以及一些参数。比如在一个组件Context里唤醒另一个组件时就需要构建一个Intent
1 | this.startActivity( |
Intent可分为显式和隐式。显式Intent明确指定了需要互动的组件,比如在上面的例子里系统收到该请求后会找到并唤醒当前Context(this)从属的App中的TargetActivity组件。隐式Intent则不会对AppContext以及组件进行限定,而是通过其他组件在Manifest文件里声明的IntentFilter来发送给匹配的组件
1 | this.startActivity( Intent(Intent.ACTION_EDIT) ) // 这里没有传入Context |
1 | <activity |
MyActivity只响应操作为EDIT的Intent
隐式Intent的应用场景很常见,比如点开一个txt文件时安卓会弹窗询问要用哪个编辑器打开,这些出现的编辑器都声明了相关的IntentFilter