它的作用?

关于PKMS的全称是啥应该咱们不陌生,PackageManagerService,和AMS一样是Android系统的核心服务,它主要负责系统中Package的管理,应用程序的安装、卸载、信息查询等工作。几乎每个实际项目都会使用它,最典型的就是APP的更新安装。

服务何时启动?

那PKMS是在何时进行的启动了,其实是在SystemServer.main()中进行的,下面来直接看一下源码,其源码还是基于8.0,如下:

然后在它的run()方法中看一下启动细节,看核心:

然后接下来就启动各种服务了:

那么问题来了?PKMS服务的启动是在哪个方法中来执行的呢?咱先先来看第一个启动引导服务方法:

接下来就可以看到启动AMS服务了,也就是上次咱们所析的,这里再来回顾一下:

接下来还有一系列系统服务的启动,如:PowerManagerService:

DisplayManagerService:

好,接下来我们想要的答案的代码来了:

由于已经看到了咱们所要看到的服务的启动,对于其它2个启动服务的方法就暂且不看了,得集中精力分析我们想分析的PKMS,免得精力分散了:

好,咱们来分析一下PKMS的main()方法,既然在注册它时调用了它:

上面来将其整个PKMS启动的流程用图来表述一下:

然后最后将其注册到ServiceManager当中:

好,既然构造了PKMS,那下面来看一下它里面的构造细节。

构造方法:

该构造方法代码量很大:

700多行。。当然也只能顺着核心流程来分析喽,其实分为如下五个阶段。

第一阶段:

构造函数在第一阶段的工作,主要是扫描并解析 ,XML 文件,将其中的信息保存到特定的数据结构中。看下代码:

第二阶段:

该阶段主要是扫描系统文件。

1、创建/system的子目录,比如/system/framework、system/priv-app和/system/app等等。

瞅下代码:

2、扫描系统文件,比如/vendor/overlay、/system/framework、/system/app等等目录下的文件,对扫描到的系统文件做后续处理。

其中:

/system/frameworks:该目录中的文件都是系统库,例如:framework.jar、services.jar、framework-res.apk。不过 scanDirLI 只扫描APK文件,所以 framework-res.apk 是该目录中唯一“受宠”的文件。
该目录下全是默认的系统应用,例如:Browser.apk、SettingsProvider.apk 等。
/vendor/app:该目录中的文件由厂商提供,即厂商特定的 APK 文件,不过目前市面上的厂商都把自己的应用放在 /system/app 目录下。

瞅下代码:

第三阶段:

它是属于扫描data分区阶段,扫描/data/app和/data/app-private目录下的文件:

,具体细节为:

1、遍历possiblyDeletedUpdatedSystemApps列表,如果这个系统App的包信息不在PMS的变量mPackages中,说明是残留的App信息,后续会删除它的数据。说明是存在于Data分区,不属于系统App,那么移除其系统权限。
看下代码:

其中可以看到是利用PackageParser.Package来对包进行扫描的:

咱们点进去看一下大概扫描的细节:

然后看一下它里面定义的成员变量,就知道它的大概作用了:

也就是会扫描manifest文件,然后将其扫描的信息存储到对应的集合当中了。

2、遍历mExpectingBetter列表,根据系统App所在的目录设置扫描的解析参数,内部会将packageName对应的包设置数据(PackageSetting)添加到mSettings的mPackages中。扫描系统App的升级包,最后清除mExpectingBetter列表。

看下代码:

第四阶段:

扫描结束阶段主要是做了以下事情:

1、如果当前平台SDK版本和上次启动时的SDK版本不同,重新更新APK的授权;

2、如果是第一次启动或者是Android M升级后的第一次启动,需要初始化所有用户定义的默认首选App;

3、OTA升级后的第一次启动,会清除代码缓存目录。

4、把Settings的内容保存到packages.xml中,这样此后PMS再次创建时会读到此前保存的Settings的内容。

第五阶段:

此时就进入了准备安装的阶段了:

以上五个阶段走完之后,咱们再来完善之前的图:

installd进程:

我们在之前分析PKMS服务启动时知道在它之前会创建一个这样的服务:

而它是运行在installd进程中的,看一下Installer.java类的注释:

那么该进程是何时启动的呢?这里就得从开机到app启动的流程进行梳理一下,其创建结点这在其中,下面来梳理一下:

也就是installd 是由 Android 系统的 init 进程(pid=1),在解析 init.rc 文件的如下代码块时,通过 fork 创建的用户空间的守护进程 installd,

而该进程的代码对应于这样cpp:

而installd 是随着系统启动过程中 main class 而启动的,并启动InstalldNativeService服务发布到native层的ServiceManager中,通过IPC机制跟上层的 installer服务进行交互。下面来看一下它的main入口函数:

然后咱们再来跟到InstalldNativeService.cpp中来看一下它启动的细节:

而它里面都是跟一些app的操作相关的服务,大致瞅一下提供的函数:

系统内置应用程序安装app:

对于应用的安装我们在应用时会这样来写:

咱们接下来就来分析一下它的整个安装过程,最终就是会用到PKMS来进行安装,先贴一张整个安装的流程图:

下面根据上面的流程来看一下具体的代码,对于上面的调用安装是最终会到PackageInstallerActivity这个界面上来,也就是安装确定界面,这个是大家再熟悉不过的了,下面打开看一下这个类的源码:

然后在onCreate()的最后会有一句这个代码:

判断是否是未知来源的应用,如果开启允许安装未知来源选项则直接初始化安装,这个在实际咱们在安装时也是经常会出现的,此时就需要到设置里去把未知来源勾选一下就可以正常安装了,好下面再来看一下检测方法:

好,下面直接来看一下直接安装的方法:

然后具体UI的细节就不看了,直接看到用户点了“安装”的事件:

此时就会跳到安装中的InstallInstalling的Acitivity界面了,跟进去看一下细节:

然后在安装后台线程中看一下真正执行安装的逻辑:

此时就转到PackageInstaller.Session.commit()方法来瞅一下:

而它的具体实现类则为PackageInstallerSession.java,所以看一下它的细节:

此时看一下这个消息处理逻辑:

而mPm就是PKMS:

所以又转到PKMS.installStage()方法中来瞅一下,最终的执行是通过消息处理:

最终的安装就会还是用installer服务来进行安装,也就是对于安装是底层来完成的。也就是这块:

Android PKMS服务的更多相关文章

  1. 3D语音天气球(源码分享)——在Unity中使用Android语音服务

    转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 开篇废话: 这个项目准备分四部分介绍: 一:创建可旋转的"3D球":3 ...

  2. Android从服务端获取json解析显示在客户端上面

    Android从服务端获取json解析显示在客户端上面 百度经验:jingyan.baidu.com 首先说一下Json数据的最基本的特点,Json数据是一系列的键值对的集合,和XML数据来比,Jso ...

  3. [Android] Service服务详解以及如何使service服务不被杀死

    排版上的细节有些不好看,主要是我用的MarkDown编辑器预览和这里的不一样,在那个上面的样式很舒服.这里要改的地方太多就不想改了,将就看吧.下次写的时候注意.还有看到错误给我提啊. 本文链接:htt ...

  4. Android 前台服务

    Android 前台服务 学习自 https://blog.csdn.net/guolin_blog/article/details/11952435#t3 前台服务漫谈 我们之前学习的Service ...

  5. Android Service 服务(三)—— bindService与remoteService

    (转自:http://blog.csdn.net/ithomer/article/details/7366396)   一.bindService简介 bindService是绑定Service服务, ...

  6. Android 位置服务——BaiduLocation的使用

    原文:Android 位置服务--BaiduLocation的使用 版权声明:本文为博主原创文章,欢迎转载,转载请在文章显眼处说明文章出处并给出连接. https://blog.csdn.net/To ...

  7. Android 网络服务介绍

    1. 介绍 Android网络服务主要包括如下四个部分 - ConnectivityService: 提供数据连接管理服务,包括移动数据.WIFI.以太网等 - NetworkPolicyManage ...

  8. android之服务

    android中的进程优先级 前台进程 拥有一个正在与用户交互的Activity(onResume方法被调用) 与一个前台Activity绑定的服务 服务调用了startForeground onCr ...

  9. Android日志服务 记录日志

    转: http://easion-zms.iteye.com/blog/981568 import java.io.BufferedReader; import java.io.File; impor ...

随机推荐

  1. es6 Decorator修饰器

    1.类的修饰: 修饰器(Decorator)函数,用来修改类的行为.修饰器是一个对类进行处理的函数.修饰器函数的第一个参数,就是所要修饰的目标类. @testable class MyTestable ...

  2. 阉割的List

    实在忍不住,模仿STL写了个阉割版的List,还没加迭代器,等搞完STL源码再说吧. #pragma once #include <stdexcept> namespace vlyf { ...

  3. 适合 ASP.NET Core 的超级-DRY开发

    作者 Thomas Hansen DRY 是那些非常重要的软件体系结构缩写之一.它的意思是“不要自我重复”,并向维护旧源代码项目的任何用户阐明了一个重要原则.也就是说,如果你在代码中自我重复,会发现每 ...

  4. [转帖]Mysql各版本介绍及下载

    Mysql各版本介绍及下载 http://blog.itpub.net/12679300/viewspace-1251661/ 原创 MySQL 作者:wzq609 时间:2014-08-15 10: ...

  5. 模拟 + 打表 --- Emag eht htiw Em Pleh

    Emag eht htiw Em Pleh Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2578   Accepted: ...

  6. 自学Dos的随堂笔记

    开启DOS控制台的几种方式 开始+windows系统+命令提示符. Win键+R,输入cmd打开控制台. 在任意文件夹下,按住shift键+鼠标右键点击,在此处打开命令窗口. 资源管理器的地址栏前面加 ...

  7. 【题解】Luogu P5301 [GXOI/GZOI2019]宝牌一大堆

    原题传送门 首先先要学会麻将,然后会发现就是一个暴力dp,分三种情况考虑: 1.非七对子国士无双,设\(dp_{i,j,k,a,b}\)表示看到了第\(i\)种牌,一共有\(j\)个\(i-1\)开头 ...

  8. Jenkins部署git+python项目实现持续集成

    目录 1. 创建 item 2. 配置 3. 构建 1. 创建 item 接下来填写创建任务的名字,并选择创建一个 Freestyle project ,点击确认. 2. 配置 接下来进入到项目相关配 ...

  9. Windwos利用批处理文件自动清理归档日志,计划任务

    首先在X盘根目录建立一个文档  cmd.txt 打开cmd.txt这个文本文件,在里面第一行写入 DELETE ARCHIVELOG ALL COMPLETED BEFORE 'SYSDATE-3'; ...

  10. RabbitMQ学习之Topics(5)

    上一节,我们讲了direct exchange,这节我们讲下topic exchange Topic exchange 发送到topic exchange的messages不可以有一个随意的routi ...