Android Camera 流程学习记录(零)—— 碎碎念以及 Android 框架初识
碎碎念
到公司入职了快两个月了。前一个月全是在公共培训,其中有半个月还到某个子公司(手机生产工厂)去实习,体验了生产最前线人民的日常生活……
8 月开始才正式分配到软件中心的工位上,然后又开始了新一轮的内部培训,培训的内容大概就是一些 Git 的使用,软件测试那边的一些知识,还有缺陷跟踪系统比如 JIRA 的使用规范等等。这里值得吐槽一下的就是这些操作性的东西居然还要背下来考试……考试完了以后,我们新来的又被放养了几天,然后才分到了具体的小组来。
而我分到了影像部,就是专门做 Android Camera 这方面项目的部门,具体的组是其中的框架组。于是从未接触 Android 方面知识的我便开始了漫长的 Android 开发学习之旅……
根据导师所介绍,小组的主要业务关注的是 Android Camera 架构中的 Frameworks
层。其实当时我是蒙比的,因为没看过 Android 系统的结构。于是导师让我先花点时间把 Android System 架构了解了解,然后再去熟悉 Camera 的整个流程。
花了大概一个多星期的时间,我才对 Camera 的整个控制流以及数据流有了一个比较清晰的了解。由于业务上的需要,我现在所了解的主要是 Camera API 1
的主要流程,而 API 2
最近也开始扩大使用的范围了,所以在整理好 API 1
的内容后,我还会继续跟进学习并整理 API 2
的内容。
Android 基本框架
在学习 Camera 框架之前,最基本的知识点应该就是 Android 的基本框架了。
这方面的内容我主要参考学习了这些文章:
Android 系统四层体系结构详解
Android 平台架构
以及参考了《Android 系统源代码情景分析(修订版)》的内容。
当然还有其它零零散散的一些文章,不过内容大同小异。
首先有一个很经典的架构图:
在我看的每一篇关于 Android 系统架构介绍的文章中,都少不了这张图,或者这张图的变种。
从图中可以很清楚得看出,整个架构可以分为五大层次:
- System Apps:即
系统应用层
,这一层中都是我们使用手机时都会直接接触到的各种应用。 - Java API Framework:即
Java 接口框架层
,这一层是为了上层应用提供各种接口。 - Native C/C++ Libraries && Android Runtime:分别是
原生 C/C++ 库
,安卓运行时环境
。这一层中,C/C++ 库集成了许多诸如OpenGL ES
这样的开源库,提供了很多封装好的方法。而运行时环境则是与一些核心库、Dalvik Virtual Machine
相关的东西,这方面暂时还没多少了解。 - HAL(Hardware Abstract Layer):这是一个
硬件抽象层
,它主要是在 Framework 层和 Linux Kernel 层之间起到一个链接作用。 - Linux Kernel:即
Linux 内核层
,整个 Android 系统实际上是基于 Linux 的内核搭建起来的。
- 系统应用层
- 它包含了一系列使用
Java
编写的核心程序包(Home,Phone,Browser...)
。 - 应用程序通过调用框架层的接口,或者
JNI (Java 原生接口)
来完成自己的业务逻辑。 - 值得注意的是,要使用
JNI
开发原生应用程序,需要与Android NDK
配合,NDK
使得Java
可以与C/C++
进行交互。
- 它包含了一系列使用
- Java 接口框架层
- 也有人称为应用程序框架层,实际上这一层主要是提供给上层应用一些访问核心功能的
API
框架。 - 框架是应用程序的核心,也是开发者需要共同遵守的一个约定,大家可以在这个约定的基础之上进行一些必要的扩展,但是主体结构需要保持一致。
- 框架层提供了大量的接口,当需要使用到某些接口的时候,可以去看看它对应的官方文档:
- 也有人称为应用程序框架层,实际上这一层主要是提供给上层应用一些访问核心功能的
- C/C++ 库 && Android 运行时环境
- 官方
API
不是万能的,开发者常常需要自己一些API
以实现自己的业务逻辑,这时候我们就可以通过调用C/C++ 本地库
的接口来进行个性化设计。 - 需要注意的是,这些
C/C++ 库
(第三方库)是独立于Android 系统架构
实现的,但是它与系统架构处于相同的地位:
- 他们都使用
Linux 内核层
提供服务,实现、封装模块,以供应用层调用。
- 他们都使用
- 运行时环境提供了一些核心链接库。
- 以及
Dalvik
虚拟机:
DVM
代替了JVM
,“.java”
文件编译为“.class”
文件后,再编译得到“.dex”
程序,最后又打包成为 Android 可执行文件“.apk”
。- 每个应用都运行在自己的进程上(一个应用程序对应一个虚拟机,一一对应关系),而
DVM
为它分配自有实例。 Dalvik
的好处是,使得一台设备可以运行多个虚拟机程序,并且消耗比较少的资源。
- 官方
- 硬件抽象层
- 向下屏蔽了硬件驱动模块的实现细节,并向上提供硬件访问服务。
- 这一层的存在,实际上主要是为了保护移动设备厂商的商业利益:
Linux 内核源码
遵循GPL 协议
,基于它所修改的源码需要完全公开,如果设备厂商通过修改内核源码来提供服务,就需要公开对应的代码,这就暴露了很多硬件相关的参数和实现的细节。- 为了保证
商业利益
,在Android 架构
中提供一个硬件抽象层给设备厂商对硬件做出具体实现,而 Linux 内核仅提供简单的硬件访问通道
。由于Android 源码
遵循商业友好的Apache License 协议
,这样设备厂商的利益就得到了保障。
- Linux 内核层
- Android 是基于
Linux 内核
开发的(官方给出的例子是,Android Runtime (ART)
依靠 Linux 内核来执行底层功能,例如线程和底层内存管理
)。 - 一个很重要的部分是
Linux 内核驱动
部分,在Camera 流程
中,我们的控制指令最终要通过内核驱动发送给Camera 设备
,同时也要通过它对设备返回的数据向上传输。 - 在 Android 中,增加了
YAFFS2(Yet Another Flash File System, 2nd edition)
文件系统。(这个系统没有去深入了解) - 增加了一个进程间通信的机制
IPC Binder
,通过Binder
,可以使不同进程可以访问同一块共享内存。Binder 机制在整个 Camera 流程中起到了十分重要的作用,它主要使用在CameraClient
与CameraServer
的交互中(Camera 架构中,采用了一个C/S 交互
的流程,在之后的学习中会有比较深入的了解)。
- Android 是基于
小结
到这里,我对 Android 框架就有了一个基本的认识。
从下到上,实际上是一个逐层封装的过程。在以往的开发中,我所接触到的往往都是上层的接口,实际上它们的内部有许多复杂的实现机制我并没有去探究过,正所谓“知其然,而不知其所以然”,这也许是我的实际开发能力总是无法有突破性的进步的原因之一。
通过一个多星期对源码的追溯学习,我开始尝试去探索学习从上层到底层的实现机制。当然这个过程还是挺痛苦的,Android 的源码虽然有大量清楚的注释,但是突然去阅读大量具有关联性的代码,时常还是会迷失方向,特别是在 C/C++
的部分,各种函数指针
经常不知道指到哪里去了,找了半天找不到,还把之前的一部分内容跟丢了……
废话说得有点多了…下一篇就先整理一下 Camera 的大体框架好了。