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 五层架构

在我看的每一篇关于 Android 系统架构介绍的文章中,都少不了这张图,或者这张图的变种。

从图中可以很清楚得看出,整个架构可以分为五大层次:

  1. System Apps:即系统应用层,这一层中都是我们使用手机时都会直接接触到的各种应用。
  2. Java API Framework:即 Java 接口框架层,这一层是为了上层应用提供各种接口。
  3. Native C/C++ Libraries && Android Runtime:分别是原生 C/C++ 库安卓运行时环境。这一层中,C/C++ 库集成了许多诸如 OpenGL ES 这样的开源库,提供了很多封装好的方法。而运行时环境则是与一些核心库、Dalvik Virtual Machine 相关的东西,这方面暂时还没多少了解。
  4. HAL(Hardware Abstract Layer):这是一个硬件抽象层,它主要是在 Framework 层和 Linux Kernel 层之间起到一个链接作用。
  5. 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 流程中起到了十分重要的作用,它主要使用在 CameraClientCameraServer 的交互中(Camera 架构中,采用了一个 C/S 交互的流程,在之后的学习中会有比较深入的了解)。

小结

到这里,我对 Android 框架就有了一个基本的认识。

从下到上,实际上是一个逐层封装的过程。在以往的开发中,我所接触到的往往都是上层的接口,实际上它们的内部有许多复杂的实现机制我并没有去探究过,正所谓“知其然,而不知其所以然”,这也许是我的实际开发能力总是无法有突破性的进步的原因之一。

通过一个多星期对源码的追溯学习,我开始尝试去探索学习从上层到底层的实现机制。当然这个过程还是挺痛苦的,Android 的源码虽然有大量清楚的注释,但是突然去阅读大量具有关联性的代码,时常还是会迷失方向,特别是在 C/C++ 的部分,各种函数指针经常不知道指到哪里去了,找了半天找不到,还把之前的一部分内容跟丢了……

废话说得有点多了…下一篇就先整理一下 Camera 的大体框架好了。

posted @ 2017-08-19 14:35  StoneDemo  阅读(633)  评论(0编辑  收藏  举报