以下资料摘录整理自老罗的Android之旅博客,是对老罗的博客关于Android底层原理的一个抽象的知识概括总结(如有错误欢迎指出)(侵删):
http://blog.csdn.net/luoshengyang/article/details/8923485
http://blog.csdn.net/luoshengyang/article/details/12957169

整理by Doing

 
         Android系统在启动的过程中,会启动一个应用程序管理服务PackageManagerService,这个服务负责扫描系统中特定的目录,找到里面的应用程序文件,即以Apk为后缀的文件,然后对这些文件进解析(其实就是解析应用程序配置文件AndroidManifest.xml的过程,并从里面得到得到应用程序的相关信息,例如得到应用程序的组件Activity、Service、Broadcast Receiver和Content Provider等信息),得到应用程序的相关信息,完成应用程序的安装过程。
        通过ActivityManagerService这个服务,我们就可以在系统中正常地使用这些应用程序了。
 
  • PackageManagerService负责安装系统的应用程序:
  1. Android系统在启动的过程中,Zygote进程启动SystemServer组件,SystemServer组件启动PackageManagerService服务、ActivityManagerService服务等。
  2. PackageManagerService服务启动过程:创建了一个PackageManagerService服务实例,把这个服务添加到ServiceManager中去(ServiceManager是Android系统Binder进程间通信机制的守护进程,负责管理系统中的Binder对象)。
  3. PackageManagerService类的构造函数中开始执行安装应用程序的过程:调用scanDirLI函数来扫描移动设备上的五个目录中的Apk文件( /system/framework、 /system/app、 /vendor/app、/data/app、 /data/app-private),对于目录中的每一个文件,如果是以Apk作为后缀名,那么就调用scanPackageLI函数来对它进行解析和安装:
  4. 首先会为这个Apk文件创建一个PackageParser实例,接着调用这个实例的parsePackage函数来对这个Apk文件进行解析(这个函数最后还会调用另外一个版本的scanPackageLI函数把来解析后得到的应用程序信息保存在PackageManagerService中。见后):
  5. 每一个Apk文件都是一个归档文件,它里面包含了Android应用程序的配置文件AndroidManifest.xml,这里主要就是要对这个配置文件解析就行了。从Apk归档文件中得到这个配置文件后,就调用另一外版本的parsePackage函数对这个应用程序进行解析:对AndroidManifest.xml文件中的各个标签进行解析,如application标签的解析,这是通过调用parseApplication函数来进行的。
  6. 解析完成后,一层层返回,调用另一个版本的scanPackageLI函数,把前面解析应用程序得到的package、provider、service、receiver和activity等信息保存在PackageManagerService服务中(保存在mPackages、mActivities、mReceivers、mServices等成员变量(HashMap类型)中)
 
 
  • 这些应用程序只是相当于在PackageManagerService服务注册好了,如果我们想要在Android桌面上看到这些应用程序,还需要有一个Home应用程序(Android系统默认的Home应用程序就是Launcher),负责从PackageManagerService服务中把这些安装好的应用程序取出来,并以友好的方式在桌面上展现出来,例如以快捷图标的形式:
  1. 系统中的应用程序安装好了以后,SystemServer组件接下来通过ActivityManagerService来启动Home应用程序Launcher
  2. ActivityManagerService.startHomeActivityLocked() 创建一个CATEGORY_HOME类型的Intent,然后通过Intent.resolveActivityInfo函数向PackageManagerService查询Category类型为HOME的Activity
  3. 由于是第一次启动这个Activity,接下来调用函数getProcessRecordLocked返回来的ProcessRecord值为null,于是调用mMainStack.startActivityLocked函数启动com.android.launcher2.Launcher这个Activity,接着调用它的onCreate函数。
  4. 把加载应用程序的操作为一个消息来处理:sWorker(Handler)通过它的post方式把一个消息放在消息队列中去,然后系统就会调用传进去的参数mLoaderTask(LoaderTask类型)的run函数来处理这个消息:调用loadAndBindAllApps成员函数,由于还没有加载过应用程序,这里的mAllAppsLoaded为false,于是调用loadAllAppsByBatch,构造一个CATEGORY_LAUNCHER类型的Intent,mContext.getPackageManager()获得PackageManagerService的接口,通过这个PackageManagerService.queryIntentActivities接口来取回所有Action类型为Intent.ACTION_MAIN,并且Category类型为Intent.CATEGORY_LAUNCHER的Activity(前面启动PackageManagerService时,会把系统中的应用程序都解析一遍,然后把解析得到的Activity都保存在mActivities成员变量中,这里通过这个mActivities变量的queryIntent函数返回符合条件intent的Activity,这里要返回的便是Action类型为Intent.ACTION_MAIN,并且Category类型为Intent.CATEGORY_LAUNCHER的Activity)
  5. Launcher.bindAllApplications调用AllApps2D.setApps,setApps调用addApps函数来为上一步得到的每一个应用程序创建一个ApplicationInfo实例了,有了这些ApplicationInfo实例之后,就可以在桌面上展示系统中所有的应用程序了。到了这里,系统默认的Home应用程序Launcher就把PackageManagerService中的应用程序加载进来了:当我们点击Home按键时,便会响应Launcher.onClick函数调用showAllApps函数显示应用程序图标,把刚才加载好的应用程序以图标的形式展示出来了。
  6. 当点击这些应用程序图标时,便会响应AllApps2D.onItemClick函数,然后调用Launcher.startActivitySafely函数来启动应用程序
 
 
 

Android应用程序安装与Launcher启动机制的更多相关文章

  1. Android Studio的安装及第一次启动时的配置

    Android Studio的安装及第一次启动时的配置 一.下载Android Studio 百度搜索“Android Studio" 点击中文社区进入,选择最新版本下载. 下载后双击安装包 ...

  2. Android应用程序安装过程源代码分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6766010 Android系统在启动的过程中, ...

  3. Android应用程序安装过程浅析

    我们知道在android中.安装应用是由PackageManager来管理的,可是我们发现PackageManager是一个抽象类.他的installPackage方法也没有详细的实现. 那在安装过程 ...

  4. Android 虚拟机 程序安装目录

    Android应用安装涉及到如下几个目录:system/app系统自带的应用程序,无法删除.data/app用户程序安装的目录,有删除权限.安装时把apk文件复制到此目录.data/data存放应用程 ...

  5. 学习笔记#Android Studio 从安装到虚拟机启动

    1.JDK下载与环境变量配置 (JDK是什么?JDK是 Java 语言的软件开发工具包,主要用于移动设备.嵌入式设备上的java应用程序.JDK是整个java开发的核心,它包含了JAVA的运行环境(J ...

  6. Android应用程序键盘(Keyboard)消息处理机制分析

    在Android系统中,键盘按键事件是由WindowManagerService服务来管理的,然后再以消息的形 式来分发给应用程序处理,不过和普通消息不一样,它是由硬件中断触发的:在上一篇文章< ...

  7. Android应用程序启动过程源代码分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6689748 前文简要介绍了Android应用程 ...

  8. Android 应用程序启动过程源代码分析

    本文转自:http://blog.csdn.net/luoshengyang/article/details/6689748 前文简要介绍了Android应用程序的Activity的启动过程.在And ...

  9. Android应用程序消息处理机制(Looper、Handler)分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6817933 Android应用程序是通过消息来 ...

随机推荐

  1. 动态插入图片到 svg 中

    动态插入图片到 svg 中使用 createElementNS 来创建svg标签,通过setAttributeNS 来设置属性, 要注意两点,创建的时候要有'http://www.w3.org/200 ...

  2. 重新开始学习javase_类再生(类的合成和继承)

    一.合成在新类里简单地创建原有类的对象.我们把这种方法叫作“合成” 为进行合成,我们只需在新类里简单地置入对象句柄即可.举个例子来说,假定需要在一个对象里容纳几个 String对象.两种基本数据类型以 ...

  3. cocos2d-x 实现沙子特效

    效果图. 说明. 标题取的不好, 原因是我也不知道这效果应该叫什么. 大概效果是这样的, 随着鼠标按下并且移动, 所到之处所有磁铁都将扩散. 就好比鼠标是一个圆形区域去排挤在场的磁铁. 话不多说, 直 ...

  4. 自动Telnet远程登陆命令

    有些时候,在面对开发机的时候,不断的telnet和不断的command自己的命令确实非常麻烦,需要一些自动测试或者自动部署的需求.然而面对telnet很多同学都跟我一样一开始觉得无法通过管道等传用户名 ...

  5. js学习笔记之:时间(三)

    今天来学习一个简单的时间应用:时间的倒影,如图所示:   主要知识点: 1  获取系统的时间值:2 建立一个div的倒影 div的倒影主要利用css来控制,函数值为:filter:flipv() 步骤 ...

  6. Bootstrap_排版_标题

    Bootstrap和普通的HTML页面一样,定义标题都是使用标签<h1>到<h6>,只不过Bootstrap覆盖了其默认的样式,使用其在所有浏览器下显示的效果一样,具体定义的规 ...

  7. HTML 内嵌JS脚本、相关参考手册

    提供一个JS.HTML参考手册入口:http://www.w3school.com.cn/jsref/index.asp. JavaScript 最常用于图片操作.表单数据处理以及内容动态更新. &l ...

  8. 洛谷 P1331 海战

    传送门 题解:由于船是方形的,所以比较简单.但是考试的时候跪了,orz.忘了考虑类似一圈井号中间有一摊水.          可以只考虑这个点上方和左边点的情况,这样分为四种情况.一种是左边是一滩水, ...

  9. get set

    关于C# get set的文章很多,但是笔者的这篇文章有它的特别之处,笔者用简单的语言把c# get set讲述的十分明了. C# get set释一:属性的访问器包含与获取(读取或计算)或设置(写) ...

  10. stdout 与 stderr 的区别

    stdout 与 stderr 的区别 一直没有注意 stdout 与 stderr 的区别,以为只是不同的描述方式.看来不是这样的. stdout 主要处理的是使用者输出 stderr 主要处理的错 ...