2016六月
21

Android系统启动流程分析之安装应用

分类:Android系统源码研究

(295)  (0)  举报  收藏

跟随上一篇博客Android系统的启动流程简要分析继续分析android系统的启动.上一篇文章里讲了,SystemServer在main方法里创建了一个线程ServerThread,并调用

initAndLoop方法.
[java] view plain copy
  1. ServerThread thr = new ServerThread();
  2. thr.initAndLoop();
在initAndLoop方法里加载各种服务,比如WindowManagerService(Wms)、ActivityManagerService(Ams)、PackageManagerService(Pms)等.
看下启动PackageManagerServer的代码
[java] view plain copy
  1. pm = PackageManagerService.main(context, installer, factoryTest != SystemServer.FACTORY_TEST_OFF, onlyCore);

这个pm是IPackageManager的实例,IPackageManager是由IPackageManager.aidl文件编译生成的.

PackageManagerService继承自IPackageManager.Stub
[java] view plain copy
  1. public class PackageManagerService extends IPackageManager.Stub {

PackageManagerService调用main方法,传入四个参数

context 上下文
installer 安装器
factoryTest != SystemServer.FACTORY_TEST_OFF 是否为正常的工厂模式
onlyCore 为true表示在加密的设备只启动核心的程序
那么查看PackageManagerService的main方法.
PackageManagerService定义在frameworks/base/services/java/com/android/server/PackageManagerService.java文件中.
main方法是这样的
[java] view plain copy
  1. public static final IPackageManager main(Context context, Installer installer, boolean factoryTest, boolean onlyCore) {
  2. PackageManagerService m = new PackageManagerService(context, installer, factoryTest, onlyCore);
  3. ServiceManager.addService("package", m);
  4. return m;
  5. }
根据传入的四个参数创建PackageManagerService的实例,
然后通过ServiceManager添加这个PackageManagerService实例.
既然创建了这个实例,那么就调用了它的有参构造函数
1.在构造函数里会扫描制定目录的apk文件
[java] view plain copy
  1. // 扫描基础框架(没有代码的资源包)。
  2. mFrameworkInstallObserver = new AppDirObserver(frameworkDir.getPath(), OBSERVER_EVENTS, true, false, false);
  3. mFrameworkInstallObserver.startWatching();
  4. scanDirLI(frameworkDir, PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR | PackageParser.PARSE_IS_PRIVILEGED, scanMode | SCAN_NO_DEX, 0);
  5. // 扫描system/priv-app目录
  6. File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
  7. mPrivilegedInstallObserver = new AppDirObserver(privilegedAppDir.getPath(), OBSERVER_EVENTS, true, true, false);
  8. mPrivilegedInstallObserver.startWatching();
  9. scanDirLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR | PackageParser.PARSE_IS_PRIVILEGED, scanMode, 0);
  10. // 扫描system/app目录
  11. File systemAppDir = new File(Environment.getRootDirectory(), "app");
  12. mSystemInstallObserver = new AppDirObserver(systemAppDir.getPath(), OBSERVER_EVENTS, true, false, false);
  13. mSystemInstallObserver.startWatching();
  14. scanDirLI(systemAppDir, PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);
  15. // 扫描映射目录
  16. File vendorAppDir = new File("/vendor/app");
  17. mVendorInstallObserver = new AppDirObserver(vendorAppDir.getPath(), OBSERVER_EVENTS, true, false, false);
  18. mVendorInstallObserver.startWatching();
  19. scanDirLI(vendorAppDir, PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);

扫描调用的方法是scanDirLI,传入四个参数,context(上下文),flag(标志),scanMode(扫描模式),currentTime(当前时间).

2.在scanDirLI方法内部会调用
[java] view plain copy
  1. PackageParser.Package pkg = scanPackageLI(file, flags | PackageParser.PARSE_MUST_BE_APK, scanMode, currentTime, null);

3.scanPackageLI通过解析安装包parsePackage获取到安装包的信息结构

[java] view plain copy
  1. PackageParser pp = new PackageParser(scanPath)
  2. pp.setSeparateProcesses(mSeparateProcesses);
  3. pp.setOnlyCoreApps(mOnlyCore);
  4. final PackageParser.Package pkg = pp.parsePackage(scanFile, scanPath, mMetrics, parseFlags);
4.之后调用parsePackage的重载方法解析,将应用信息保存在PackageManagerService,比如VersionCode、VersionName等
[java] view plain copy
  1. try {
  2. // XXXX todo: need to figure out correct configuration.
  3. pkg = parsePackage(res, parser, flags, errorText);
  4. } catch (Exception e) {
  5. errorException = e;
  6. mParseError = PackageManager.INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION;
  7. }

5.回到第3步,调用scanPackageLI的重载方法

[java] view plain copy
  1. PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanMode | SCAN_UPDATE_SIGNATURE, currentTime, user);6.
6.然后调用createDataDirsLI方法
[java] view plain copy
  1. // And now re-install the app.
  2. ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid, pkg.applicationInfo.seinfo);

7.在createDataDirsLI方法里调用mInstaller的install方法进行安装.

[java] view plain copy
  1. int res = mInstaller.install(packageName, uid, uid, seinfo);

版权声明:本文为博主原创文章,转载请注明出处:邓志勇博客 http://blog.csdn.net/qq_31530015/

Android系统启动流程分析之安装应用相关推荐

  1. Android 7.0系统启动流程分析

    随着Android版本的升级,aosp项目中的代码也有了些变化,本文基于Android 7.0分析Android系统启动流程.当我们按下电源键后,整个Android设备大体经过了一下过程:  今天我们 ...

  2. Android系统启动流程—— init进程zygote进程SystemServer进程启动流程

    原文地址:https://blog.csdn.net/qq_30993595/article/details/82714409 Android系统启动流程 Android系统启动过程往细了说可以分为5 ...

  3. 从源码解析-Android系统启动流程概述 init进程zygote进程SystemServer进程启动流程

    Android系统启动流程 启动流程 Loader Kernel Native Framework Application init进程 启动 rc文件规则 Actions Commands Serv ...

  4. 基于Android13的系统启动流程分析(六)之SystemServer内部逻辑分析

    主要分析一下SystemServer启动过后的内部逻辑,特别说明一下AMS,WMS都属于SystemServer进程,属于同一个进程 一. SystemServer进程启动流程 基于Android13 ...

  5. Android 7.1.2(Android N) Android系统启动流程

    Android 7.1.2(Android N) Android系统启动流程 源码: system/core/rootdir/ init.rc init.zygote64.rc system/core ...

  6. Android系统启动流程(四)Launcher进程启动过程解析(附带面试题)

    前面我们分析了init进程,zygote进程,SystemServer进程,本篇的Launcher是系统启动流程的最后一个进程. 1 Launcher概述 Launcher进程是一个系统的应用程序,位 ...

  7. Android系统启动流程(nougat7.1.1_r6)

    一.Android启动简介 Android 是一种基于 Linux 的开放源代码软件栈,为广泛的设备和机型而创建.下图所示为 Android 平台的主要组件. Linux 内核 Android 平台的 ...

  8. Android系统启动流程(四)Launcher启动过程与系统启动流程

    相关文章 Android系统架构与系统源码目录 Android系统启动流程(一)解析init进程启动过程 Android系统启动流程(二)解析Zygote进程启动过程 Android系统启动流程(三) ...

  9. Android系统启动流程 -- bootloader

    Android系统启动流程 -- bootloader   BootLoader:在嵌入式操作系统中,BootLoader是在操作系统内核运行之前运行.可以初始化硬件设备.建立内存空间映射图,从而将系 ...

最新文章

  1. 【FFmpeg】解码时refcounted_frames标志的使用
  2. mysql 10 进制 转36_mysql 10进制与35进制之间的转换 注意Power处理bigint的问题
  3. 点赞功能,用 MySQL?还是 Redis!
  4. 转:Ogre的MaterialSystem分析
  5. 超越Linux!华为鸿蒙明年将成“第五大操作系统”,网友:何时超过iOS?
  6. 在DataTable和DataView中查找指定记录
  7. 标准库举例:sys、copy
  8. Spring-MVC案例:Spitter的笔记
  9. 图之Dijkstra算法
  10. 2008年5月Windows Mobile Webcast预告
  11. iOS 最新AppStore申请加急审核 以及 apple联系方式大全
  12. IMU惯性测量单元是什么?
  13. iPhone所有手机型号屏幕尺寸及H5的CSS适配
  14. 25个移动APP图表设计欣赏(译)
  15. 台式计算机蓝牙在哪,台式电脑蓝牙在哪里打开(台式电脑连接蓝牙教程分享)...
  16. 51单片机设计计算器
  17. 关于抢红包的_酷乐研究所 | 过年净抢红包了?我们准备了50种新玩法
  18. nginx日志统计pv、uv命令
  19. 关于激励(如何发挥员工积极性)
  20. 把手机当作电脑显示器指导参考

热门文章

  1. 通过一组RESTful API暴露CQRS系统功能
  2. Java基础知识总结(一)
  3. MOSS点滴(1):如何开发和部署feature
  4. 分类系列之感知器学习算法PLA 和 口袋算法Pocket Algorithm
  5. Canny边缘检测算法
  6. 二十万字C/C++、嵌入式软开面试题全集宝典三
  7. C++去掉字符串首尾的特殊字符(比如空格)
  8. Redis介绍及常用应用场景介绍
  9. Python6:oriented objective programming
  10. VTK修炼之道20:图像基本操作_图像类型转换