序言

  Android 应用的启动到一个页面显示出来,这个过程涉及到点击事件的处理,以及如何启动一个Activity,启动一个Activity之后,如何将Activity中我们的设置的ContentView显示出来,显示的时候,如何添加窗口,如何在将View绘制到窗口上等一系列操作。涉及到的关键的三个服务,Ams,Wms还有Pms。分别是用来管理全局的Activity,Window,Package。整个过程中有哪些主要的类在里面起作用。

  Ams,Wms,Pms在SystemServer中都是在一个子线程中运行。

  带着一个主线,我们点击了Launcher中的一个图标,这个应用从未被启动过,那么这个应用从被点击到该应用的界面显示出来的整个过程。

  流程

  输入事件的处理

  查找到指定的Activity

  创建相应的进程然后运行

  启动指定的Activity

  为该Activity创建窗口,然后将视图绘制上去

  接收触摸点击事件

  输入事件处理消息的获取过程,InputReader线程会持续调用输入设备的驱动,读取所有用户输入的消息,该线程和InputDispatcher线程都是在system_process空间中运行,第一种是经过管道派发给客户进程。Wms创建一个InputManager对象的时候,然后启动InputDispatcher线程,Native层有两个重要的对象,一个是InputDispatcher,一个是InputReader,从线程的角度来看,只有两个线程存在,一个是InputDispatcher还有一个是InputReaderTread线程,他们运行在system_process进程中。

  查找指定的ActivityPms使用两个目录下的XML文件保存相关的包管理信息,一个是用来管理permissions,一个是packaegs.xml该文件保存了安装程序的基本包信息,比如包名称,安装包路径,程序使用了那些权限,像是系统的注册表,Pms启动后,会从两个目录解析相关的xml文件,建立一个庞大的包信息树,应用程序可以从这个信息树种查找自己所需要的程序包信息。当进行App的跳转的时候。Pms在初始化的时候,会从AndroidManifest.xml文件中提取值,然后建立一个内部数据结构,以后应用可以通过PackageManager提供query方法查询不同的组件的包信息。

  创建相应的进程然后运行检测对应Activity的进程是否存在 - > 不存在则启动对应的进程 - > 进程启动完成通知AMS - > 调用AMS attachApplication(请求AMS给自己attach一个具体的Activity)- > 继续调用resumeTopActivity - > 进程处理(handleLaunchActivity,handleResumeActivity)应用程序执行的时候,首先执行的是创建一个ActivityThread,然后调用prepareMainLooper为UI线程创建一个消息队列,然后创建一个ActivityThread对象,会创建一个Handler和一个ApplicationThread(Binder对象),其负责接收远程的Ams的IPC调用,UI主线程会调用Looper.Loop进入消息循环体,接收到创建指定Activity的来自AMS的消息后,会创建指定的Activity对象,Activity对象会创建PhoneWindow类,DecorView类,相应的View和ViewGroup,调用WindowManager,创建一个ViewRoot和W类,ViewRoot包含一个W类对象,WindowManager和Wms进行交互并将窗口显示到屏幕上

  启动指定的Activity每一个应用程序对应了一个ActivityThread,其负责启动Activity,构造好Activity之后,会调用Activity的attach方法,顾名思义,就是为Activity添加上一些东西,上下文,创建它的线程,创建窗口对象,在Ams中记录的ActivityRecord引用,然后创建窗口,通过PolicyManager的makeNewWindow来创建,归根结底是创建了一个PhoneWindow对象,将创建的Window对象赋值给内部变量mWindow,并设置Window的Callback接口为当前的Activity对象,将用户消息传递给Activity,Window中包含WindowManager对象,Activity中也包含一个WindowManger和其相同,WindowManager的具体功能实现是在WindowManagerImpl中,配置好之后,给窗口中添加显示元素View或者ViewGroup。调用performLaunchActivity内部的callActivityOnCreate,然后辗转调用Activity的onCreate。调用setContentView,实际是调用了其内部的Window的setContentView。

  为该Activity创建窗口,然后将视图绘制上去PhoneWindow的installDecor方法为Window类安装窗口装饰,然后把内容View装载进来,给Window类设置完其视图后,剩下的就是把创建这个窗口告诉给Wms,Wms把窗口显示到屏幕,Ams进行一系列的条件判断后,最终调用Activity的makeVisible方法,调用WindowManager的addView,LocalWindowManager相比于WindowManagerImpl多了一层包裹,可以用来进行一些窗口参数的配置等。调用了LocalWindowManager的addView之后,又要调用WindowManagerImpl的addView方法,一个应用程序只有一个WindowManagerImpl对象,WindowManagerImpl中持有三个数组,其分别为Views(每一个窗口),ViewRoot(每一个窗口对应的ViewRoot),WindowLayoutParams,每一个窗口对应的LayoutParams。调用了addView之后,检查窗口是否已经被添加,然后创建ViewRoot对象,ViewRoot中创建了一个Surface对象,只是一个空壳Surface,没有为其分配具体的地址,调用ViewRoot的setView,给ViewRoot的变量进行赋值,调用requstLayout,发出界面重绘的消息。调用sWindowSession.add()通知Wms添加窗口, mWinsowsession每一个应用程序对应一个,是一个Binder引用,该引用对应Wms的子类。同时对于Surface对象进行了赋值。当一个应用程序需要创建窗口时,首先在本地创建一个Surface对象,然后调用WindowManager类向Wms服务发起请求,请求参数包含Surface对象,Surface类是一个壳,其初始化的本质是给Surface对象分配一段屏幕缓冲区内存。Wms收到请求,调用Surface类的JNI调用SurfaceFlinger——client驱动,通过该驱动为请求sf进程创建指定的窗口,sf创建一块屏幕缓冲区,并在sf内部记录下该窗口,然后sf会把缓冲区地址传递给Wms,Wms在用这个地址去初始化Surface对象。有了平面,但是我们还是不可以在上面进行绘制,Android使用了一个Skia的绘图驱动库,程序中用Canvas类来表示这个功能对象,surface类包含一个函数lockCanvas,可以返回一个Canvas对象。为Canvas指定了一块内存,绘制的结果是给该块内存地址填充不同的像素值。

  Surface的构造函数首先创建一个Canvas对象,该对象作为对于底层的JNI函数的一个外部引用,然后调用init函数,创建一个真正的surface,首先是获得一个SurfaceComposerClient对象,该类是Native层面上SurfaceFlinger服务的客户端对象,然后调用该对象的createSurface函数,创建一个真正的Surface对象,参数包含了当前进程的pid,请求窗口的宽和高。Drawable类,我们可以给它传递一个Canvas,然后就可以进行绘制。

  Pms的作用

  提供根据Intent匹配具体的Component,根据参数中指定的intent转化成一个具体的程序包名和具体组件名称的信息,方便Java类加载器的转载

  权限检查

  提供安装,删除接口

  Ams的作用

  统一调度应用程序的Activity

  内存管理,对于Activity并不会立即杀死,而是对其进行缓存

  进程管理,提供对于运行进程的相关信息的管理

  创建应用进程

  Ams通过调用Process进程类启动一个新的应用进程,新的应用进程会从ActivityThread的main函数开始执行,目标进程启动后,会报告给Ams,然后Ams通知目标进程启动目标Activity。当启动进程的事情结束了,目标进程会通过IPC调用AMS的attachApplication请求Ams给指定目标Activity去执行。

  attachApplication过程,对app对象内部的变量进行赋值,同时根据指定的Activity加载相应的dex文件,根据Intent中的信息,然后查询ApplicaitonInfo,这个时候就已经执行了Application类,然后根据指定的Activity,去启动目标Activity。此时进程中的文件是Framework中的ActivityThread基类。

  新启动的进程在Ams提供的ApplicationInfo的信息加载具体的Activity,ApplicationInfo可以用来进程间的通信。

  attachApplication过程

  handleBindApplication

  重新设置时区和区域,装载相应的系统资源

  是否存在Instrumentation类

  调用makeApplication创建Application类的对象,调用APK文件中的类对象,

  启动Provider,在Activity之前启动

  调用Application的onCreate方法

  handleLaunchActivity

  应用进程launch指定的Activity

  加载目标Activity类

  创建一个ContextImpl对象,每一个Activity都包含一个ContextImpl对象,是一个轻量类,创建后,调用Activity.attach方法,用ContextImpl来初始化Activity对象,同时将其作为Activity的baseContext。

  然后调用Activity的四个声明周期函数。

  把新建的Activity对象家督到ActivityThread的activity列表中,存放是目标Activity和ActivityRecord的对应

  Activity对象找到自己的DecorView显示到屏幕上

Android系统学习小记的更多相关文章

  1. Android系统中的广播(Broadcast)机制简要介绍和学习计划

    在Android系统中,广播(Broadcast)是在组件之间传播数据(Intent)的一种机制:这些组件甚至是可以位于不同的进程中,这样它就像Binder机制一样,起到进程间通信的作用:本文通过一个 ...

  2. [转]Android系统Surface机制的SurfaceFlinger服务简要介绍和学习计划

    转自:Android系统Surface机制的SurfaceFlinger服务简要介绍和学习计划 前面我们从Android应用程序与SurfaceFlinger服务的关系出发,从侧面简单学习了Surfa ...

  3. 在Ubuntu上为Android系统编写Linux内核驱动程序(老罗学习笔记1)

    这里,我们不会为真实的硬件设备编写内核驱动程序.为了方便描述为Android系统编写内核驱动程序的过程,我们使用一个虚拟的硬件设备,这个设备只有一个4字节的寄存器,它可读可写.想起我们第一次学习程序语 ...

  4. Android入门学习:Android 系统框架及应用程序执行过程

    Android基础知识学习 新手上路,还请多多帮助.由于初学,博客内容难免有不正确的地方,还请各位多多指教,相互学习! 主要内容: 1.Android层次架构及主要功能 2.Android编程模型,程 ...

  5. Android系统Surface机制的SurfaceFlinger服务简要介绍和学习计划

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/8010977 前面我们从Android应用程序与 ...

  6. Android开发学习之路--Android系统架构初探

    环境搭建好了,最简单的app也运行过了,那么app到底是怎么运行在手机上的,手机又到底怎么能运行这些应用,一堆的电子元器件最后可以运行这么美妙的界面,在此还是需要好好研究研究.这里从芯片及硬件模块-& ...

  7. Android系统源码学习步骤

    Android系统是基于Linux内核来开发的,在分析它在运行时库层的源代码时,我们会经常碰到诸如管道(pipe).套接字(socket)和虚拟文件系统(VFS)等知识. 此外,Android系统还在 ...

  8. Android系统源代码学习步骤

    目前,互联网行业正在朝着移动互联网方向强劲地发展,而移动互联网的发展离不开背后的移动平台的支撑.众所周知,如今在移动平台市场上,苹果的iOS.谷歌的Android和微软的Windows Phone系统 ...

  9. 如何学习Android系统源码(转)

    一. Android系统的源代码非常庞大和复杂,我们不能贸然进入,否则很容易在里面迷入方向,进而失去研究它的信心.我们应该在分析它的源代码之前学习好一些理论知识,下面就介绍一些与Android系统相关 ...

随机推荐

  1. 阿里云centos安装svn和submin

    概述 没有找到可以让团队方便使用的云盘,暂时搭建一个svn凑合用一下 svn有三种安装方式 安装方式 服务程序 服务协议 用户和密码 授权 系统配置 svn独立安装 svnserve svn pass ...

  2. wordpress-4.4.1 数据库表结构解析

    wordpress-4.4.1.zip 安装包  SQL结构 : wp_commentmeta  :文章评论额外信息表. CREATE TABLE IF NOT EXISTS `wp_commentm ...

  3. ubuntu下安装加装DNS

    感觉在ubuntu下网速特别的慢,所以网上找了下解决方案,本地缓存域名解析相关信息. 首先,安装dns服务 命令: sudo apt-get install dnsmasq 编辑dnsmasq的配置文 ...

  4. SPOJ GSS1 Can you answer these queries I[线段树]

    Description You are given a sequence A[1], A[2], ..., A[N] . ( |A[i]| ≤ 15007 , 1 ≤ N ≤ 50000 ). A q ...

  5. Java — JTree and JTable以及sqlServer的两种连接

    使用JTree的步骤: 暂时只能创建一个头结点,创建一个树的结点作为头结点(其子结点也是相同的创建方法):DefaultMutableTreeNode headNode = new DefaultMu ...

  6. 掌握SortSet接口和Set接口的关系,以及常用方法。

    TreeSet类是可以排序的类.TreeSet实际上也是SortSet接口的子类. 此接口的所有类都是可以排序的. 所有的方法: 实例: package 类集; import java.util.So ...

  7. 通过trie树单词自动补全(二)

    经常使用iciba进行单词查询, 关于他的搜索建议是通过单词前缀做的索引, 所以自己想动手实现下, 当然如果借助mysql的话,一条sql语句就能实现, 网上查询了下trie正适合做这个,所以通过C语 ...

  8. asp.net页面关闭的时候如何触发事件?

      <script type="text/javascript"> var pb_strConfirmCloseMessage; var pb_blnCloseWind ...

  9. SharePoint 2013技巧分享系列 - 隐藏Blog和Apps左侧导航菜单

    企业内部网中,不需要员工创建Blog或者创建,安装SharePoint应用,因此需要在员工个人Web页面需要隐藏Blog或者Apps导航菜单, 其步骤设置如下: 该技巧适合SharePoint 201 ...

  10. flex 布局笔记

    1,今天遇到一个问题,就是当元素布局设置为了flex后,里面的内容只有文字,但是对text-align 属性设置无效,仔细想了下,是因为把display 设置为了flex后,flex将里面的文字也认为 ...