Android 开篇

alleyway 7年前
   <h3>一、引言</h3>    <p>Android系统非常庞大、错中复杂,其底层是采用Linux作为基底,上层采用包含虚拟机的Java层以及Native层,通过系统调用(Syscall)连通系统的内核空间与用户空间。用户空间主要采用C++和Java代码,通过JNI技术打通用户空间的Java层和Native层(C++/C),从而融为一体。</p>    <p>Google官方提供了一张经典的四层架构图,从下往上依次分为Linux内核、系统库和Android运行时环境、框架层以及应用层这4层架构,其中每一层都包含大量的子模块或子系统。这只是如垒砖般地分层,并没有表达Android整个系统的内部架构、运行机理,以及各个模块之间是如何衔接与配合工作的。 为了更深入地掌握Android整个架构思想以及各个模块在Android系统所处的地位与价值,计划以Android系统启动过程为主线,以进程的视角来诠释Android M系统全貌 ,全方位的深度剖析各个模块功能,争取各个击破。这样才能犹如庖丁解牛,解决、分析问题则能游刃有余。</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/caee07ad9295be3d40456c0b100d174c.png"></p>    <h3>二、Android架构</h3>    <p>Google提供的4层架构图很经典,但为了更进一步透视Android系统架构,本文更多的是以进程的视角,以分层的架构来诠释Android系统的全貌,阐述Android内部的环环相扣的内在联系。</p>    <p>系统启动架构图</p>    <p>点击查看大图</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/509bfcda03769166047694f84079bcc9.jpg"></p>    <p>图解:Android系统启动过程由上图从下往上的一个过程: Loader -> Kernel -> Native -> Framework -> App ,接来下简要说说每个过程:</p>    <p>2.1 Loader层</p>    <ul>     <li>Boot ROM: 当手机处于关机状态时,长按Power键开机,引导芯片开始从固化在 ROM 里的预设出代码开始执行,然后加载引导程序到 RAM ;</li>     <li>Boot Loader:这是启动Android系统之前的引导程序,主要是检查RAM,初始化硬件参数等功能。</li>    </ul>    <p>2.2 Kernel层</p>    <p>Kernel层是指Android内核层,到这里才刚刚开始进入Android系统。</p>    <ul>     <li>启动Kernel的swapper进程(pid=0):该进程又称为idle进程, 系统初始化过程Kernel由无到有开创的第一个进程, 用于初始化进程管理、内存管理,加载Display,Camera Driver,Binder Driver等相关工作;</li>     <li>启动kthreadd进程(pid=2):是Linux系统的内核进程,会创建内核工作线程kworkder,软中断线程ksoftirqd,thermal等内核守护进程。 kthreadd进程是所有内核进程的鼻祖 。</li>    </ul>    <p>2.3 Native层</p>    <p>这里的Native层主要包括init孵化来的用户空间的守护进程、HAL层以及开机动画等。启动init进程(pid=1),是Linux系统的用户进程, init进程是所有用户进程的鼻祖 。</p>    <ul>     <li>init进程会孵化出ueventd、logd、healthd、installd、adbd、lmkd等用户守护进程;</li>     <li>init进程还启动 servicemanager (binder服务管家)、 bootanim (开机动画)等重要服务</li>     <li>init进程孵化出Zygote进程,Zygote进程是Android系统的第一个Java进程, Zygote是所有Java进程的父进程 ,Zygote进程本身是由init进程孵化而来的。</li>    </ul>    <p>2.4 Framework层</p>    <ul>     <li>Zygote进程,是由init进程通过解析init.rc文件后fork生成的,Zygote进程主要包含:      <ul>       <li>加载ZygoteInit类,注册Zygote Socket服务端套接字;</li>       <li>加载虚拟机;</li>       <li>preloadClasses;</li>       <li>preloadResouces。</li>      </ul> </li>     <li>System Server进程,是由Zygote进程fork而来, System Server是Zygote孵化的第一个进程 ,System Server负责启动和管理整个Java framework,包含ActivityManager,PowerManager等服务。</li>     <li>Media Server进程,是由init进程fork而来,负责启动和管理整个C++ framework,包含AudioFlinger,Camera Service,等服务。</li>    </ul>    <p>2.5 App层</p>    <ul>     <li>Zygote进程孵化出的第一个App进程是Launcher,这是用户看到的桌面App;</li>     <li>Zygote进程还会创建Browser,Phone,Email等App进程,每个App至少运行在一个进程上。</li>     <li>所有的App进程都是由Zygote进程fork生成的。</li>    </ul>    <p>2.6 Syscall && JNI</p>    <ul>     <li>Native与Kernel之间有一层系统调用(SysCall)层,</li>     <li>Java层与Native(C/C++)层之间的纽带JNI,见Android JNI原理分析。</li>    </ul>    <h3>三、通信方式</h3>    <p>无论是Android系统,还是各种Linux衍生系统,各个组件、模块往往运行在各种不同的进程和线程内,这里就必然涉及进程/线程之间的通信。对于IPC(Inter-Process Communication, 进程间通信),Linux现有管道、消息队列、共享内存、套接字、信号量、信号这些IPC机制,Android额外还有Binder IPC机制,Android OS中的Zygote进程的IPC采用的是Socket机制,在上层system server、media server以及上层App之间更多的是采用Binder IPC方式来完成跨进程间的通信。对于Android上层架构中,还多时候是在同一个进程的线程之间需要相互通信,例如同一个进程的主线程与工作线程之间的通信,往往采用的Handler消息机制。</p>    <p>想深入理解Android内核层架构,必须先深入理解Linux现有的IPC机制;对于Android上层架构,则最常用的通信方式是Binder、Socket、Handler,当然也有少量其他的IPC方式,比如杀进程Process.killProcess()采用的是signal方式。下面说说Binder、Socket、Handler:</p>    <p>3.1 Binder</p>    <p>Binder作为Android系统提供的一种IPC机制,无论从系统开发还是应用开发,都是Android系统中最重要的组成,也是最难理解的一块知识点,想了解 为什么Android要采用Binder作为IPC机制? 可查看我在知乎上的回答。深入了解Binder机制,最好的方法便是阅读源码,借用Linux鼻祖Linus Torvalds曾说过的一句话:Read The Fucking Source Code。下面简要说说Binder IPC原理。</p>    <p>Binder IPC原理</p>    <p>Binder通信采用c/s架构,从组件视角来说,包含Client、Server、ServiceManager以及binder驱动,其中ServiceManager用于管理系统中的各种服务。</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/9d1fe17cdee49b646e60856633b97098.jpg"></p>    <ul>     <li>想进一步了解Binder,可查看Binder系列—开篇,Binder系列花费了13篇文章的篇幅,从源码角度出发来,讲述Driver、Native、Framework、App四个层面的整个完整流程。根据有些读者反馈这个系列还是不好理解,这个binder涉及的层次跨度比较大,知识量比较广, 建议大家先知道binder是用于进程间通信,有个大致概念就可以.先去学习系统基本知识,等后面有一定功力再进一步深入研究Binder.</li>    </ul>    <p>Native层面:</p>    <ul>     <li><a href="/misc/goto?guid=4959738967395360268" rel="nofollow,noindex">Binder系列3—启动Service Manager</a></li>     <li><a href="/misc/goto?guid=4959738967482466502" rel="nofollow,noindex">Binder系列4—获取Service Manager</a></li>     <li><a href="/misc/goto?guid=4959669985317934411" rel="nofollow,noindex">Binder系列5—注册服务(addService)</a></li>     <li><a href="/misc/goto?guid=4959738967597819712" rel="nofollow,noindex">Binder系列6—获取服务(getService)</a></li>    </ul>    <p>Driver层面:</p>    <ul>     <li><a href="/misc/goto?guid=4959738967681491726" rel="nofollow,noindex">Binder系列1—Binder Driver初探</a></li>     <li><a href="/misc/goto?guid=4959738967763434463" rel="nofollow,noindex">Binder系列2—Binder Driver再探</a></li>    </ul>    <p>Framework层面:</p>    <ul>     <li><a href="/misc/goto?guid=4959738967848318470" rel="nofollow,noindex">Binder系列7—framework层分析</a></li>     <li><a href="/misc/goto?guid=4959738967935129719" rel="nofollow,noindex">Binder系列8—如何使用Binder</a></li>    </ul>    <p>App层面</p>    <ul>     <li><a href="/misc/goto?guid=4959738968013369017" rel="nofollow,noindex">Binder系列9—如何使用AIDL</a></li>     <li><a href="/misc/goto?guid=4959738968097690579" rel="nofollow,noindex">Binder系列10—总结</a></li>    </ul>    <p>全栈架构型:从Java framework到Native层,再到Linux层的一条线的串通</p>    <ul>     <li><a href="/misc/goto?guid=4959738968181205011" rel="nofollow,noindex">彻底理解Android Binder通信架构</a></li>    </ul>    <p>3.2 Socket</p>    <p>Socket通信方式也是C/S架构,比Binder简单很多。在Android系统中采用Socket通信方式的主要:</p>    <ul>     <li>zygote:用于孵化进程,系统进程system_server孵化进程时便通过socket向zygote进程发起请求;</li>     <li>installd:用于安装App的守护进程,上层PackageManagerService很多实现最终都是交给它来完成;</li>     <li>lmkd:lowmemorykiller的守护进程,Java层的LowMemoryKiller最终都是由lmkd来完成;</li>     <li>adbd:这个也不用说,用于服务adb;</li>     <li>logcatd:这个不用说,用于服务logcat;</li>     <li>vold:即volume Daemon,是存储类的守护进程,用于负责如USB、Sdcard等存储设备的事件处理。</li>    </ul>    <p>等等还有很多,这里不一一列举,Socket方式更多的用于Android framework层与native层之间的通信。Socket通信方式相对于binder非常简单,所以一直没有写相关文章,为了成一个体系,下次再补上。</p>    <p>3.3 Handler</p>    <p>Binder/Socket用于进程间通信,而Handler消息机制用于同进程的线程间通信,Handler消息机制是由一组MessageQueue、Message、Looper、Handler共同组成的,为了方便且称之为Handler消息机制。</p>    <p>有人可能会疑惑,为何Binder/Socket用于进程间通信,能否用于线程间通信呢?答案是肯定,对于两个具有独立地址空间的进程通信都可以,当然也能用于共享内存空间的两个线程间通信,这就好比杀鸡用牛刀。接着可能还有人会疑惑,那handler消息机制能否用于进程间通信?答案是不能,Handler只能用于共享内存地址空间的两个线程间通信,即同进程的两个线程间通信。很多时候,Handler是工作线程向UI主线程发送消息,即App应用中只有主线程能更新UI,其他工作线程往往是完成相应工作后,通过Handler告知主线程需要做出相应地UI更新操作,Handler分发相应的消息给UI主线程去完成,如下图:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/cf71d08f14650059783003c19cfd5e41.jpg"></p>    <p>由于工作线程与主线程共享地址空间,即Handler实例对象 mHandler 位于线程间共享的内存堆上,工作线程与主线程都能直接使用该对象,只需要注意多线程的同步问题。工作线程通过 mHandler 向其成员变量 MessageQueue 中添加新Message,主线程一直处于loop()方法内,当收到新的Message时按照一定规则分发给相应的 handleMessage ()方法来处理。所以说,而Handler消息机制用于同进程的线程间通信的核心是线程间共享内存空间,而不同进程拥有不同的地址空间,也就不能用handler来实现进程间通信。</p>    <p>上图只是Handler消息机制的一种处理流程,是不是只能工作线程向UI主线程发消息呢,其实不然,可以是UI线程想工作线程发送消息,也可以是多个工作线程之间通过handler发送消息。更多关于Handler消息机制文章:</p>    <ul>     <li><a href="/misc/goto?guid=4959738968271659627" rel="nofollow,noindex">Android消息机制-Handler(framework篇)</a></li>     <li><a href="/misc/goto?guid=4959738968349625119" rel="nofollow,noindex">Android消息机制-Handler(native篇)</a></li>     <li><a href="/misc/goto?guid=4959738968435758804" rel="nofollow,noindex">Android消息机制3-Handler(实战)</a></li>    </ul>    <p>要理解framework层源码,掌握这3种基本的进程/线程间通信方式是非常有必要,当然Linux还有不少其他的IPC机制,比如共享内存、信号、信号量,在源码中也有体现,如果想全面彻底地掌握Android系统,还是需要对每一种IPCd机制都有所了解。</p>    <h3>四、计划提纲</h3>    <p>2016年新的一年刚开始,首先祝大家、也祝自己在新的一年诸事顺心,事业蒸蒸日上。在过去的一年,对于Android从底层一路到上层有不少自己的理解和沉淀,但总体较零散,未成体系。借着今天(元旦假日的最后一天),给自己的新的一年提前做一个计划,把知识进行归档整理与再学习,从而加深对Android架构的理解。通过前面对系统启动的介绍,相信大家对Android系统有了一个整体观,接下来需要抓核心、理思路,争取各个击破。</p>    <p>计划:不少文章还没来得及进一步加工,大篇章的源码,有读者跟我反馈看着发困,先别急,文章还会不断更新和升级。前期计划先将系统所有核心技术点的边整理边写博客;后期工作有时间再根据大家的反馈以及自己的校验,再不断修正和完善所有文章,争取给文章,再进一步精简非核心代码,增加可视化图表以及文字的结论性分析。</p>    <p>博客定位:基于 Android 6.0的源码 ,专注于分享Android系统原理、架构分析的原创文章。 <strong>建议阅读群体</strong> : 适合于正从事或者有兴趣研究Android系统的工程师或者爱好者,也适合Android app高级工程师; 对于尚未入门或者刚入门的app程序员阅读可能会困难些,可能不是很适合。</p>    <p>4.0 学习篇</p>    <p>看到Android整个系统架构是如此庞大的, 该问如何学习Android系统, 以下是我自己琢磨的Android的学习和研究论,仅供参考:</p>    <ul>     <li><a href="/misc/goto?guid=4959738968515502263" rel="nofollow,noindex">如何自学Android</a></li>    </ul>    <p>4.1 进程篇</p>    <p>进程对于系统非常之重要,系统运转,各种服务、组件的载体都依托于进程,对进程理解越深刻,越能掌握系统整体架构。那么先来看看进程相关:</p>    <ul>     <li><a href="/misc/goto?guid=4959720056802377481" rel="nofollow,noindex">理解Android进程创建流程</a></li>     <li><a href="/misc/goto?guid=4959721128704999414" rel="nofollow,noindex">Android四大组件与进程启动的关系</a></li>     <li><a href="/misc/goto?guid=4959738968658820924" rel="nofollow,noindex">理解杀进程的实现原理</a></li>     <li><a href="/misc/goto?guid=4959722057247834240" rel="nofollow,noindex">Android进程绝杀技–forceStop</a></li>     <li><a href="/misc/goto?guid=4959738968780201638" rel="nofollow,noindex">理解Android线程创建流程</a></li>     <li><a href="/misc/goto?guid=4959722918545606425" rel="nofollow,noindex">理解Binder线程池的管理</a></li>     <li><a href="/misc/goto?guid=4959738968181205011" rel="nofollow,noindex">彻底理解Android Binder通信架构</a></li>     <li><a href="/misc/goto?guid=4959738968897851714" rel="nofollow,noindex">Android进程整理</a></li>     <li><a href="/misc/goto?guid=4959738968979270078" rel="nofollow,noindex">Android进程生命周期与ADJ</a></li>     <li><a href="/misc/goto?guid=4959738969067370253" rel="nofollow,noindex">进程优先级</a></li>     <li><a href="/misc/goto?guid=4959716594579781481" rel="nofollow,noindex">Android进程调度之adj算法</a></li>    </ul>    <p>4.2 系统启动篇</p>    <p>Android系统启动-概述): Android系统启动过程中,有几个非常重要的进程: init 、 Zygote 、 system_server 进程:</p>    <ul>     <li><a href="/misc/goto?guid=4959738969180069719" rel="nofollow,noindex">Android系统启动—init篇</a></li>     <li><a href="/misc/goto?guid=4959738969262119824" rel="nofollow,noindex">Android系统启动—Zygote篇</a></li>     <li>Android系统启动—SystemServer篇      <ul>       <li><a href="/misc/goto?guid=4959673005241344691" rel="nofollow,noindex">SystemServer上篇</a></li>       <li><a href="/misc/goto?guid=4959673006861276674" rel="nofollow,noindex">SystemServer下篇</a></li>      </ul> </li>     <li>守护进程(进程名一般以d为后缀,比如logd)      <ul>       <li><a href="/misc/goto?guid=4959738969405249332" rel="nofollow,noindex">debuggerd</a></li>       <li><a href="/misc/goto?guid=4959738969494647483" rel="nofollow,noindex">installd</a></li>       <li><a href="/misc/goto?guid=4959716553019018183" rel="nofollow,noindex">lmkd</a></li>      </ul> </li>    </ul>    <p>4.3 系统服务篇</p>    <p>再则就是在整个架构中有大量的服务,都是基于Binder来交互的,计划针对部分核心服务来重点分析:</p>    <ul>     <li>Android服务篇-ActivityManagerService      <ul>       <li><a href="/misc/goto?guid=4959673002239464124" rel="nofollow,noindex">AMS启动过程(一)</a></li>       <li><a href="/misc/goto?guid=4959716594579781481" rel="nofollow,noindex">Android进程调度之adj算法</a></li>      </ul> </li>     <li>Input系统      <ul>       <li><a href="/misc/goto?guid=4959738969646390262" rel="nofollow,noindex">Input系统—启动篇</a></li>       <li><a href="/misc/goto?guid=4959738969723390867" rel="nofollow,noindex">Input系统—InputReader线程</a></li>       <li><a href="/misc/goto?guid=4959738969802710098" rel="nofollow,noindex">Input系统—InputDispatcher线程</a></li>       <li><a href="/misc/goto?guid=4959738969908035133" rel="nofollow,noindex">Input系统—UI线程</a></li>       <li><a href="/misc/goto?guid=4959738969993521226" rel="nofollow,noindex">Input系统—进程交互</a></li>       <li><a href="/misc/goto?guid=4959733901667901356" rel="nofollow,noindex">Input系统—ANR原理分析</a></li>      </ul> </li>     <li>Android服务篇-PackageManagerService      <ul>       <li><a href="/misc/goto?guid=4959738970106610515" rel="nofollow,noindex">PackageManager启动篇</a></li>       <li><a href="/misc/goto?guid=4959738969494647483" rel="nofollow,noindex">Installd守护进程</a></li>      </ul> </li>     <li>Android服务篇-WindowManagerService      <ul>       <li><a href="/misc/goto?guid=4959738970195727614" rel="nofollow,noindex">WindowManagerService启动篇</a></li>      </ul> </li>     <li>Android服务篇-BatteryService      <ul>       <li><a href="/misc/goto?guid=4959738970284121701" rel="nofollow,noindex">Android耗电统计算法</a></li>      </ul> </li>     <li>Android服务篇-PowerManagerService</li>     <li>Android服务篇-DropBoxManagerService      <ul>       <li><a href="/misc/goto?guid=4959738970371882012" rel="nofollow,noindex">DropBoxManager启动篇</a></li>      </ul> </li>     <li>Android多用户服务-UserManagerService      <ul>       <li><a href="/misc/goto?guid=4959738970454765714" rel="nofollow,noindex">多用户管理UserManager</a></li>      </ul> </li>     <li>更多服务介绍, 敬请期待…</li>    </ul>    <p>4.4 四大组件篇</p>    <p>对于App来说,Android应用的四大组件Activity,Service,Broadcast Receiver, Content Provider最为核心,那么我们需要分别展开对其他的分解:</p>    <ul>     <li>Android组件-Activity      <ul>       <li><a href="/misc/goto?guid=4959673759475425891" rel="nofollow,noindex">startActivity启动过程分析</a></li>       <li><a href="/misc/goto?guid=4959738970568426831" rel="nofollow,noindex">简述Activity生命周期</a></li>      </ul> </li>     <li>Android组件-Service      <ul>       <li><a href="/misc/goto?guid=4959673002407051523" rel="nofollow,noindex">startService启动过程分析</a></li>       <li><a href="/misc/goto?guid=4959738970686846136" rel="nofollow,noindex">bindService启动过程分析</a></li>       <li><a href="/misc/goto?guid=4959738968181205011" rel="nofollow,noindex">以Binder视角来看Service启动</a></li>      </ul> </li>     <li>Android组件-Broadcast Receiver      <ul>       <li><a href="/misc/goto?guid=4959720056933178880" rel="nofollow,noindex">Android Broadcast广播机制分析</a></li>      </ul> </li>     <li>Android组件-Content Provider      <ul>       <li><a href="/misc/goto?guid=4959713441761390939" rel="nofollow,noindex">理解ContentProvider原理</a></li>       <li><a href="/misc/goto?guid=4959738970836481936" rel="nofollow,noindex">ContentProvider引用计数</a></li>      </ul> </li>    </ul>    <p>4.5 系统分析篇</p>    <p>Android往往会有一些crash, anr等异常抛出, 只有先明白整个处理流程,才能再进一步分析具体问题. 这里先展开原理篇.</p>    <ul>     <li>Android ANR系列      <ul>       <li><a href="/misc/goto?guid=4959738970930744494" rel="nofollow,noindex">理解Android ANR的触发情景</a></li>       <li><a href="/misc/goto?guid=4959729107224413534" rel="nofollow,noindex">理解Android ANR的处理过程</a></li>       <li><a href="/misc/goto?guid=4959729107394427033" rel="nofollow,noindex">ART虚拟机之Trace原理</a></li>       <li><a href="/misc/goto?guid=4959729107304836911" rel="nofollow,noindex">Native进程之Trace原理</a></li>      </ul> </li>     <li>Android Crash系列      <ul>       <li><a href="/misc/goto?guid=4959738971090711875" rel="nofollow,noindex">理解Java Crash处理流程</a></li>       <li><a href="/misc/goto?guid=4959738971188132273" rel="nofollow,noindex">理解Native Crash处理流程</a></li>       <li><a href="/misc/goto?guid=4959738971271086350" rel="nofollow,noindex">WatchDog工作原理</a></li>      </ul> </li>    </ul>    <p>4.6 内存&&存储篇</p>    <ul>     <li>内存篇      <ul>       <li><a href="/misc/goto?guid=4959716553019018183" rel="nofollow,noindex">Android LowMemoryKiller原理分析</a></li>       <li><a href="/misc/goto?guid=4959738971370058031" rel="nofollow,noindex">Linux内存管理</a></li>      </ul> </li>     <li>存储篇      <ul>       <li><a href="/misc/goto?guid=4959738971454421747" rel="nofollow,noindex">Android存储系统之源码篇</a></li>       <li><a href="/misc/goto?guid=4959738971540114281" rel="nofollow,noindex">Android存储系统之架构篇</a></li>      </ul> </li>     <li>Linux驱动篇      <ul>       <li>敬请期待</li>      </ul> </li>     <li>dalvik/art      <ul>       <li><a href="/misc/goto?guid=4959729107394427033" rel="nofollow,noindex">ART虚拟机之Trace原理</a></li>       <li>敬请期待</li>      </ul> </li>    </ul>    <p>4.7 工具篇</p>    <p>最后,说说Android相关的一些常用命令和工具以及调试手段.</p>    <ul>     <li><a href="/misc/goto?guid=4959738971640655951" rel="nofollow,noindex">理解Android编译命令</a></li>     <li><a href="/misc/goto?guid=4959738971721470356" rel="nofollow,noindex">性能工具Systrace</a></li>     <li><a href="/misc/goto?guid=4959738971803920835" rel="nofollow,noindex">Android内存分析命令</a></li>     <li><a href="/misc/goto?guid=4959669985203848160" rel="nofollow,noindex">ps进程命令</a></li>     <li><a href="/misc/goto?guid=4959738971922446033" rel="nofollow,noindex">Am命令用法</a></li>     <li><a href="/misc/goto?guid=4959738972013096634" rel="nofollow,noindex">Pm命令用法</a></li>     <li><a href="/misc/goto?guid=4959738972102838811" rel="nofollow,noindex">dumpsys命令用法</a></li>     <li><a href="/misc/goto?guid=4959738972189565551" rel="nofollow,noindex">调试系列1:bugreport源码篇</a></li>     <li><a href="/misc/goto?guid=4959738972281215406" rel="nofollow,noindex">调试系列2:bugreport实战篇</a></li>    </ul>    <p> </p>    <p> </p>    <p>来自:http://gityuan.com/android/</p>    <p> </p>