序言

  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. Python正则表达式:最短匹配

    最短匹配应用于:假如有一段文本,你只想匹配最短的可能,而不是最长. 例子 比如有一段html片段,'\this is first label\\the second label\',如何匹配出每个a标 ...

  2. 记录一次MongoDB3.0.6版本wiredtiger与MMAPv1引擎的写入耗时对比

    一.MongoDB3.0.x的版本特性(相对于MongoDB2.6及以下): 增加了wiredtiger引擎: 开源的存储引擎: 支持多核CPU.充分利用内存/芯片级别缓存(注:10月14日刚刚发布的 ...

  3. 曲演杂坛--当ROW_NUMBER遇到TOP

    值班期间研发同事打来电话,说应用有超时,上服务器上检查发现有SQL大批量地执行,该SQL消耗IO资源较多,导致服务器存在IO瓶颈,细看SQL,发现自己都被整蒙了,不知道这SQL是要干啥,处理完问题赶紧 ...

  4. Spark存储管理(读书笔记)

    Spark存储管理(读书笔记) 转载请注明出处:http://www.cnblogs.com/BYRans/ Spark的存储管理 RDD的存放和管理都是由Spark的存储管理模块实现和管理的.本文从 ...

  5. LLVM 笔记(二)—— PHI node

    ilocker:关注 Android 安全(新手) QQ: 2597294287 什么是 PHI node? 所有 LLVM 指令都使用 SSA (Static Single Assignment,静 ...

  6. java设计模式之策略模式

    策略模式 定义了算法家族,分别封装起来,让它们之间可以相互替换,此模式让算法的变化,不会影响到使用算法的客户(大话设计模式). 策略模式UML图   策略模式代码 古代的各种计谋都是一种策略,这次我们 ...

  7. 洛谷P1262 间谍网络[强连通分量 BFS]

    题目描述 由于外国间谍的大量渗入,国家安全正处于高度的危机之中.如果A间谍手中掌握着关于B间谍的犯罪证据,则称A可以揭发B.有些间谍收受贿赂,只要给他们一定数量的美元,他们就愿意交出手中掌握的全部情报 ...

  8. POJ2528Mayor's posters[线段树 离散化]

    Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 59683   Accepted: 17296 ...

  9. 用extract-text-webpack-plugin提取出来的css文件中背景图片url的不正确的问题

    在一个main.js中require一个scss文件,scss文件中用了背景图片,图片url是用的相对路径,用extract-text-webpack-plugin插件提取出的css文件背景图片路径不 ...

  10. 数据存储单位的换算关系(TB、PB、EB、ZB、YB)