Open chenlijunfan opened 5 years ago
系统启动时Launcher安装2.各大Market安装3.下载安装(手动触发)4.ADB安装
Activity的启动过程 1.AMS从PMS获取要启动的Activity的启动信息 2.AMS需要确认此Activity所需要的进城有没有启动,没有则需要请求Zygote孵化 3.以上过程正常,执行Activity启动流程 PMS加载APK主要完成三件事 1.解析AndroidManifest.xml,拿到构成此app的各组件的信息,以及启动信息 2.为每个app分配UID,GID,以此创建App运行的进城,这涉及到Android的沙箱模型,可以理解为应用程序资源归属问题的解决 3.更新应用程序权限
Package类 从APK中解析出的信息存于Package。codePath区分分包的情况,即5.0以后为了解决65536问题,将APK拆分成多个APK策略
1.解析AndroidManifest.xml 通过XmlResourceParser逐步解析AndroidManifest.xml文件中Manifest节点信息 2.分配进城UID 1).为pkg所描述的应用程序分配UID,并更新PackageSetting,因为APK的安装涉及到新应用的安装、旧版本更新以及share user id场景。新版本情况下,需要准备新的PackageSetting并分配UID;旧版本更新情况下,更新PackageSetting,UID已做过分配;share user id情况下考虑PackageSetting的可用性 2).将pkg所指向的Package保存到PMS 3).将pkg描述的四大组件保存到PMS,以供AMS访问 3.权限更新 权限文件位于/system/etc/permissions/platform.xml,而权限ID保存在PMS.mSetting.mPerssions中,默认全局可访问的权限在mGlobalGids中 4.核心步骤 1).从AndroidManifest中解析出应用信息、各组件信息、权限信息 2).为应用程序分配UID,并让PMS记录个组件信息,AMS启动四大组件时,需要这些信息 3).更新应用程序权限信息,授权应用程序资源访问权
1.解析AndroidManifest.xml 通过XmlResourceParser逐步解析AndroidManifest.xml文件中Manifest节点信息
2.分配进城UID 1).为pkg所描述的应用程序分配UID,并更新PackageSetting,因为APK的安装涉及到新应用的安装、旧版本更新以及share user id场景。新版本情况下,需要准备新的PackageSetting并分配UID;旧版本更新情况下,更新PackageSetting,UID已做过分配;share user id情况下考虑PackageSetting的可用性 2).将pkg所指向的Package保存到PMS 3).将pkg描述的四大组件保存到PMS,以供AMS访问
3.权限更新 权限文件位于/system/etc/permissions/platform.xml,而权限ID保存在PMS.mSetting.mPerssions中,默认全局可访问的权限在mGlobalGids中
4.核心步骤 1).从AndroidManifest中解析出应用信息、各组件信息、权限信息 2).为应用程序分配UID,并让PMS记录个组件信息,AMS启动四大组件时,需要这些信息 3).更新应用程序权限信息,授权应用程序资源访问权
系统启动安装
System进程在启动时,会初始化系统运行时的各种环境参数、并启动各种辅助。在启动Boot服务时,激活PMS.main()创建PMS,并注册入ServiceManager中。 系统在每次启动时,都会重新安装所有应用程序,共有四种类型的应用程序,分别存于不同文件夹之下: /data/app-private: 受DRM保护的程序 /system/app-private: 系统自带程序 /vendor/app: 手机厂商自己程序 /data/app: 用户自行安装的程序 而 /system/framework 则是资源性应用程序,是用来打包资源文件的,不包含有执行代码。 之前说过,每一用户安装的应用程序被分配的UID是不变的,因此系统通过 /data/system/package.xml 可以到达此目的。package.xml文件保存了上一次安装应用程序的信息,其中也包括了应用程序UID,因此可以在解析出package.xml 信息后,向系统申请分配各应用程序的UID 。 紧接着,在拿到各种程序的文件夹后,通过scanDirTracedLI()进行安装,再通过updatePermissionsLPw()触发grantPermissionsLPw()更新所有应用程序权限。最后将最新的pacakge.xml写入保存。这里也就将之前所有的安装APK的核心步骤串联了起来。
第三方应用安装
第三方应用需要PMS向PackageHandler发送信息来驱动安装,见PMS.PackageHandler.doHandleMessage()。 HandlerParams实际操作步骤为: 1.检查尝试安装次数,超过限制则放弃安装请求,发送MCS_GIVE_UP信号,调用handleServiceError() 2.调用子类handleStartCopy()处理具体安装 3.调用子类handleReturnCode()处理安装结果
PMS驱动APK安装可以用上图表示: 1.通过INIT_COPY信号与DefaultContainerService进行连接,连接成功后拿到可转为IMediaContainerService的Binder,发送MCS_BOUND信号 2.通过MCS_BOUND信号接收IMediaContainerService(AIDL) 3.通过INIT_COPY接收HandlerParams请求数据,加入请求队列 4.通过MCS_BOUND新型号处理HandlerParams请求,通过startCopy()拿到合适的APK路径,通过DefaultContainerService进行复制,最后通过handleReturnCode()最终触发核心安装逻辑
注意:在7.0以下的版本能通过file:// Uri的 intent启动InstallStart。但在7.0之后禁止将file:// Uri暴露给其它程序,因此需要FileProvider来解决。
ADB 安装
通过adb命令adb install packagePath 该命令会被PM接收,PM接收到之后,通过PMS执行。 PM与PMS运行在不同的进程,需要IPC,借助PackageInstaller.Session进行,调用commit()
Martket安装
从Martket安装就比较简单了。Martket应用程序在下载完APK后,与PMS进行对话,调用PMS.installPackageAsUser()。 也是发送了INIT_COPY,通过PMS驱动APK安装方式进行
系统启动安装
第三方应用安装
注意:在7.0以下的版本能通过file:// Uri的 intent启动InstallStart。但在7.0之后禁止将file:// Uri暴露给其它程序,因此需要FileProvider来解决。
ADB 安装
Martket安装