全面认识Android OS

缘起

前几天CSDN有篇讲鸿蒙OS的文章,我觉得它是最近讨论自主开发OS的文章里很中肯的一篇了(链接不给了,…..)。我曾经在2012年介绍过Android OS的情况,现在来看依然不过时。作为一个技术人,我们探讨某个东西的前景的时候总该对它有一些了解。 本篇就是一个非常简单的对Android OS的介绍。注意,本篇涉及的很多知识严格意义上都不会太严谨,主要还是把意思传达到位就行了。

在Android刚起步的那几年(2011年前及左右),我们同时下注了 Android 、Intel联合几个厂商搞的 Meego 、还有基于 Linux的嵌入式OS 。那时,中移动的OMS也很火,甚至OMS搞出了一个叫播思的公司。播思里边有非常多的人才,其中很多人来自中国手机界的黄埔军校——摩托罗拉。从这个角度看,Android OS在早期也是看不准,没人觉得它一定会成。

Android最终还是成功了,我个人感觉这个不全是技术的因素,但有几个关键因素还是和技术有关:

  1. 使用Java作为开发语言绝对是很关键的因素之一——毕竟,迎合开发者非常重要。Java终归是比C++/C要简单,容易上手。

  2. 另外,Android底层是Linux,这一块就把绝大部分做外设的厂商吸引过来了。它们本来就为Linux开发驱动或者相关模块,迁移到Android没太大工作量。

  3. 最后,还有关键的芯片厂商——高通的支持。如果当时只有Intel一家做芯片的话,Meego保不齐还能多蹦跶几年。

以前CSDN《程序员》杂志里经常有一位作者的投稿,我看他的个人介绍就很有意思,说是要 为Linux摇旗呐喊 。所以,Android之所以成功,就在于太多人为它摇旗呐喊了。搞软硬件开发的,搞培训的…..真是人心齐泰山移呀!

Android彻底占据市场之后,基于H5的OS又来了一波小高潮。2013-2014年左右有个Firefox OS,还在国外装了不少机器。FireFox OS是全兼容Android的。所谓的兼容,就是原来归属Android OS的功能都保留,然后再对H5的APP提供了一些功能扩展而已。

相比Android,给Firefox OS摇旗呐喊的人就少多了。而且还要兼容Android OS——那么,每次Android OS更新,Firefox都要去适配,更改。这工作量就非常非常大了。最后Firefox OS就歇菜了。

以上是历史情况——它说明了一个事实:没有哪个OS天生就是赢家,形势是变化的。另外, 我们很多人要感谢Android,可以亲历一个OS从零到如此强大的过程,时间跨度非常短,七八年就搞起来了

现在 开始我们关于对Android OS的一些科普性介绍。

整体视频

由PPT转换而来的视频

上面视频里介绍了5个部分,分别是:

  1. Android系统架构——垂直角度来看

  2. Android Framework——没有层次关系

  3. Android OS是微内核的OS

  4. Android手机发布和更新的过程示意

每个部分都不长。大家可以先看下面的内容,等整体看完后,再来看上面的PPT视频。

Android系统架构——垂直角度来看

下图是Android OS的整体架构。99.999%搞Android的人都知道:

从垂直角度来看,Android OS分为四个层次(这是我的划分,别家的说法大同小异,其中有些内容比较老了,比如Dalvik虚拟机已经换成了ART,但不影响我们对这个架构的认识):

  • 最底层是Linux Kernel层 。请各位看官特别注意这一点,它再强调一万次也不为过——Android OS的基石是Linux kernel。除了Kernel层,User Space中围绕Linux Kernel相关的东西也被Android OS照搬了过来,比如ueventd,wpa_supplicant等。

  • 中间两层由下到上是 Native Framework 层和 Java Framework 层。这两个是Android独有的。我们统称这两层为 Android Framework

  • 最上层是 应用层 正是基于Android Framework,才使得Android上的应用如此与众不同 ——作为对比,如果写个无界面的比如ls,find这样的程序,它们在所有基于Linux/Unix的系统上都是一样的运行。这样的程序我们一般认为是Linux应用程序——肯定不会把ls当做Android应用。

上述四个层次中,Kernel历史最悠久,到今天就剩下大概 Windows,Linux、MacOS三个巨头了(Unix和Linux、Mac有亲缘关系,在消费类电子产品中见得少,所以不讨论Unix):

  • Windows归微软所有 ,搞了几十年,参与一起玩的设备厂商,软件开发商几十万家。

  • Linux :和Unix有亲缘关系,开源的Kernel,上面有好多发行版,比如Ubuntu,CentOS等,国产的优麒麟也是。

  • MacOS :也和Unix有一定亲缘关系,苹果独有。参与一起玩的设备厂商,软件开发商也有几十万家。

以上唯有Linux不归某个公司独有。所以,Android使用Linux是必然的选择。如果我们要搞国产自主OS的话,最大可能性也是基于Linux,比如现在的优麒麟,以前的红旗都是这样。

这并非技术牛不牛的问题,而是 Linux Kernel可看做是全人类共有的软件财富 。遵守它的要求,不要搞独立王国,一起用好它即可。再说,Linux Kernel发展了几十年下来,很多国人(包括国内很多公司)为它做出过许多大大小小甚至卓越的贡献。俗话说,前人栽好树,后人好乘凉。如果从头到尾,从上到下都要“自主 ,干脆连计算机编程语言都不要用国外发明的了

继续我们的讨论。

Android Framework——没有层次关系

大部人眼里,Android OS的架构都是上面那样的垂直关系——这个认识没有错,但是并不完全准确。如果我们以功能模块为单位来观察其中的 Android Framework (Native Framework和Java Framework的统称)的话,你会得到大概下面这样的图:

以功能为单位来观察Android Framework的话:

  • J ava Framework包含几大类的服务 ,比如和应用中四大组件调度功能有关的组件,专门管理窗口的组件,应用程序安装有关的功能组件。还有和网络有关,蓝牙功能有关的组件等等。我在《深入理解Android 卷2》里将它们大概分了七大类。现在的最新版本里这个类别有所增加,比如对Android Auto(针对车载系统)里增加了几个和车载有关的功能模块。另外,请注意,上述划分纯属我个人的分类,并不存在什么标准。

  • Native Framework也可以像这样按功能来进行划分 ,比如和音频相关的AudioFlinger、AudioPolicyService等。

通过这一节,你知道了:

  • Android Framework里其实是有很多功能模块的。

  • 这些功能模块有可能是放在Java Framework里,也有可能是Native Framework里。

  • 更有甚者,这些功能模块可以分布在多个进程中,彼此之间,或 对应用层以Binder方式进行进程间交互。

知道上面这些东西有什么用呢?接着看。

Android OS是微内核的OS

关于内核,一直有 微内核 宏内核 之分。使用微内核的有Windows和Mac、使用宏内核的是Linux。那么,什么微内核,什么是宏内核?下图简单解释了微内核:

我里简单描述下微内核和宏内核的差异( 点到即止,非技术严格

  • 微内核就是内核只做一些基本的服务(比如操作CPU,进程调度,内存管理、设备管理等)。然后将其它功能独立为除内核之外的多个进程。 微内核最大的诟病就是其它进程和内核之间的交互属于进程间通信,开销比较大

  • 宏内核就是把上图中的所有东西都塞到内核里。这样大家都运行在一个进程里(主要是指共享同一个内存空间——内核地址空间),如此可极大减少模块间交互的开销,但 问题就是一旦有一个模块出问题,整个kernel都可能挂掉

了解微内核和宏内核的差异后,我们再来看Android。如果我们认为Android是一个OS的话(后面会讲为什么可以将Android看成是一个OS),它是微内核还是宏内核呢?接着看下图:

上面这个图展示了Android 四个层级间的交互:

  • Native Framework、Java Framework均有和Linux交互。

  • Java Framework中的部分模块和Native Framework中的部分模块有交互。

  • APP和Java Framework有交互。某些情况下也可以和Native Framework模块交互(图中并未画出相关的箭头线)。

结合我们上文提到的, Android Framework中的功能模块并非都挤在一个进程里,而是分散在不同进程中,功能模块之间通过进程间通信的手段交互 。所以,从应用的角度看,Android OS肯定是一个微内核。

现在,我们再看看为什么可以把Android称之为一个OS——这个问题的答案其实在上面已经隐含得回答过了,就是上面说的那句话“ 正是基于Android Framework,才使得Android上的应用如此与众不同 ”。

是的,Android之所以可以说自己是个OS,在于它新搞了一套应用开发及交互规则。

关于这个规则,下面举两个非常简单的例子。一个是启动应用时,源Activity和Android Framework的交互过程:

对于这个图,我并不是让大家去了解具体交互的细节。一看这个图,你就发现这玩意为Android独有。

当然,在Android中你也可以做一个不遵守这样的应用程序。比如手机中的开机动画,就是Linux应用程序——程序名叫bootanimation,它就没有什么四大组件,也不需要Manifest,纯纯得一个播放动画/图片的Linux程序。

我曾经在2010年左右实践过直接使用libskia来做UI控件相关的应用——Android中的那些控件其内部就是使用 libskia 为二维图形库(3维绘制则使用OpenGLES)。libskia也就是现在的 Flutter 底层绘制引擎。

我当时想法很简单,就是想对一些使用Android系统的非手机设备(用在场景比较简单的设备上,比如刷卡买个汽水之类的。那个时候,这些设备的性能都非常简陋,跑不动全套Android,必须裁剪),完全可以使用自定义的基于 libskia 图像库的控件来画UI。因为大部分情况下,只要把UI画出来就好,剩下的调用驱动就行了。什么四大组件,统统都不需要。

拜Flutter所赐, libSkia 现在有一些知名度了,但它的价值依然被大部分人低估。目前我知道还没有哪本专业书籍是介绍这个的。 车载系统 (对时延要求很高,使用全套Android对速度影响很大,往往需要裁减)或者 哪个公司想搞OS ,开发一套二维绘制引擎非常关键——说白了,应用开发中很大部分比例都是UI。我记得还有好几个Linux发行版让界面看起来和Windows一样。BTW,3D绘制引擎反而不用在意,因为太难,怕各家瞎搞,所以早就有OpenGL标准…..

接着来看另外一个例子——播放视音频:

Android上,一个应用要播放视音频的话,依赖 MediaPlayerService SurfaceFlinger AudioFlinger 、硬件编解码模块等。这套东西也不是Linux带过来的,而是Android搞出来的。

我记得以前在Windows上做播放器的时候,应用程序需要自己加上编解码和播放的功能,使用DirectX。这就是每个应用的独家秘籍,谁家支持得格式多,谁就厉害了。

放到Android上来,编解码,播放功能均由系统提供了,应用程序再也不用操心这些东西。这无疑是一个很大的进步。

上面举了两个非常简单的例子,想必现在我们确实可以大大方方将Android称之为OS了。 因为它在Linux Kernel之上做了大量的非同一般,独立自主的功能。 说实话,对Android应用来说,它是不是与运行在Linux上都不重要,只要有Android Framework就足够了 ——早在2011年,我的CSDN博客文章“ 移植之乱谈

https://blog.csdn.net/Innost/article/details/6954556 )中,有个哥们把Android  Framework整个移植到了Windows上。注意,并不是现在模拟器那样的使用虚拟机喔!上面的视频好像还可以看,大家可以看一下。

Android手机发布和更新的过程示意

很多人不了解Android手机系统发布和更新的过程,总吐槽AOSP新版本发布后还要过好久自己的手机才能更新到新版本。这个问题的解释见下图:

上图是Android手机系统的发布和更新过程,图比较久了,现在情况会好点,但大致如此:

  • 谷歌首先发布版本,我们称之为AOSP原生代码。AOSP原生代码只支持极少数几款手机。

  • 然后是芯片厂商在AOSP基础上发布自己的版本。比如高通,华为,MTK。 ①和② 的过程有重叠,主要还是为了加快发版速度。在 这个阶段,每个芯片厂商会在AOSP原生代码上叠加自己的功能,比如以前AOSP没有双卡双待功能,这些功能有一些是芯片厂商自己加的。另外,芯片厂商还要针对自己发的版本做大量稳定性测试。

  • 华米OV等终端厂商并不直接使用谷歌的原生代码,它们其实使用的是所用芯片厂商提供的Android代码。然后,设备厂商还得魔改一下,加上终端厂商自己的特性。这就是MIUI,EMUI,ColorOS等的功能。

  • 现在大部分终端厂商使用芯片厂商的Turnkey方案,主要是CPU+通讯模组,芯片+软件打包卖给终端厂商。少数公司比如魅族使用的CPU是三星,而通信模组不知道哪一家,那么魅族就需要把三星的CPU和别家的通讯模组整合到一起,难度比使用Turnkey方案得大一些。

  • 终端厂商集成完后,还需要考虑运营商定制的情况,然后加上对应的运营商定制功能,并做对应的测试。

了解上面的情况后, 光从测试角度看,源码从谷歌发布到最终的手机上,测试的工作量都非常大——所以到终端消费者手里的速度会慢多了。厂商的解决办法就是在新款手机上直接使用新版系统,老款手机往往要等一段时间才会发布新版升级包。

总之,在Android手机世界里,谷歌、芯片厂商、终端厂商,运营商都是生态链里的关键玩家,四者互相影响。从终端厂商角度看,我觉得芯片厂商对终端厂商的影响力更关键和致命。最简单来说,高通要是不更新更好的芯片,很多手机商的产品也就停滞不前了。

对比苹果,人家从芯片到OS都自己搞,也不太拿运营商当回事。所以苹果发版和覆盖速度都相对较快,碎片化问题绝对是比Android低好几个数量级。当然,通信芯片是苹果的大问题,所以老有人吐槽iphone的信号不好。这个问题能靠苹果自己开发通信芯片来解决吗?理论上可以,但是不现实,因为其中有很多专利问题不好搞。

再说下我对国产自主OS的一些看法和判断。

  • 不出意外的,中长期(十几年之内,如果量子计算机还没有普及的话)看,依然会以Linux Kernel为核心(这里不考虑那些特殊场景的OS,比如工控机用的实时OS等)。只要使用Linux Kernel,绝大部分硬件厂商都能适应。否则来个新OS,硬件厂商又得开发驱动,还要做大量测试,这个所需的时间和金钱成本都非常巨大。

  • 如果这个国产自主OS兼容Android的话,说明Android那套东西大概率会保留。这是从应用角度来看的。当然,也可以魔改Anndroid Framework,把内部实现都换成自己写的。 但是要做到兼容的话,就必须对应用没有影 ——这就回到软件界的一句老话, 如果一个东西叫起来,走起路来都像鸭子的话,那它就是鸭子 。从这个角度看,自主实现只是为了搞成看起来和之前一样的话,这个意义并不重大,这种自主也很难被认可。当然,如果能提升原有系统的性能则另当别论,这属于优化和改善,和我们讨论的不是同一个东西。

  • 所以,国产自主OS要么像Android一样搞个基于Linux的,但是套路和Android完全不一样的。比如像Meego、Tizen这样的。要么就是拓展Android OS,搞一个H5 OS或者什么之类的。

  • 最后,如果抛弃Linux的话,可参考谷歌的Fuchsia了,据说那是一个微内核的新OS架构。不过,这个OS的前途并不明朗。OS从来就不是一个纯软件的事情,还涉及到海量硬件厂商。它们甚至是一个OS生死存亡的决定者。

《深入理解Android ART》宣传

加一个《深入理解Android ART》一书的宣传。这本书是目前我花费心血最多,也是最难的一本书。有几个印象深刻的记忆:

  • 时间跨度长达三年,非常孤独,幸好有几位审稿专家的陪伴。

  • 中间无数次想放弃。反正也没签合同,也没承诺什么,甚至也没几个人知道我在干这事。放弃就放弃了。好在坚持下来了。

  • dex2oat一章曾经写到了100多页,实在是写不下去了。因为发现如果没有搞明白编译技术的话,后面根本没法玩。所以只能暂时放下dex2oat,花了8个多月研究编译技术,写完第六章,然后才逐步完成后续章节。

顺带把我们这个“深入理解Android系列”做个宣传,八年Android之旅,九本书的作者都是精益求精,为基业长青付出了坚实可见的努力。感谢大家的认可。

下一步

开公众号以后得到很多朋友的关注,所以很想回报下大家。打算和出版社搞一个签名送《深入理解Android  ART》一书的活动。获奖的朋友可以把要说的话告诉我,我亲自写到书上快递给你。快递费不收,但是要想通过打赏或者点广告方式给我也行。本人的字很丑,请不要嫌弃

精华文章

我们神农教立教的三篇基石文章 比任何传授具体技术知识的内容都要有长远价值 ,它们是:

  1. “深入理解”的目标是什么?

  2. 关于Android学习的三个终极问题

  3. 一专多能、刻意练习和终身成长

最后的最后

  • 我期望的结果不是朋友们从我的书、文章、博客后学会了什么知识,干成了什么,而应该是说, 神农,我可是踩在你的肩膀上得喔

  • 关于学习方面的问题,我已经讨论完了。 后面这个公众号将对一些基础的技术,新技术做一些学习和分享。也欢迎你的投稿 。不过,正如我在公众号“联系方式”里说的那样——郑渊洁在童话大王《智齿》里有一句话令我印象深刻,大意是“我有权保持沉默,但你说的每一句话都可能成为我灵感的源泉”。 所以,影响不是单向的,很可能我从你那学到的东西更多

神农和朋友们的杂文集

长按识别二维码关注我们