PMS服务启动原理详解

PMS服务启动原理详解

从开机到app启动PMS服务处理机制与流程

  • Apk安装是怎么进行的,PMS如何分析APK压缩文件
  • 开机时PMS做了什么,data/app目录下的扫描与分析
  • PakageParse类源码解读
  • AndroidManifest为什么要按照Google设计的写,PMS告诉你真相
  • AMS与PMS交互过程解析

PackageInstaller 原理简述

应用安装是智能机的主要特点,即用户可以把各种应用(如游戏等)安装到手机上,并可以对其进行卸载等管理操作。APK是Android Package的缩写,即Android安装包。APK是类似Symbian Sis或Sisx的文件格式。通过将APK文件直接传到Android模拟器或Android手机中执行即可安装。

Android应用安装有如下四种方式

  • 系统应用安装――开机时完成,没有安装界面

  • 网络下载应用安装――通过market应用完成,没有安装界面

  • ADB工具安装――没有安装界面。

  • 第三方应用安装――通过SD卡里的APK文件安装,有安装界面,由packageinstaller.apk应用处理安装及卸载过程的界面。

应用安装的流程及路径

  • 应用安装涉及到如下几个目录:
    system/app系统自带的应用程序,无法删除data/app: 用户程序安装的目录,有删除权限。

安装时把apk文件复制到此目录data/app存放应用程序的数据data/dalvik-cache将apk中的dex文件安装到dalvik-cache目录下(dex文件是dalvik虚拟机的可执行文件,其大小约为原始apk文件大小的四分之一)

安装过程:复制APK安装包到data/app目录下,解压并扫描安装包,把dex文件(Dalvik字节码)保存到dalvik-cache目录,并data/data目录下创建对应的应用数据目录。
卸载过程:删除安装过程中在上述三个目录下创建的文件及目录。

一、系统应用安装:

PackageManagerService处理各种应用的安装,卸载,管理等工作,开机时由systemServer启动此服务

(源文件路径:android\frameworks\base\services\java\com\android\server\PackageManagerService.java)

PackageManagerService服务启动的流程:

  • 首先扫描安装“system\framework”目录下的jar包

  • scanDirLI(mFrameworkDir,PackageParser.PARSE_IS_SYSTEM, scanMode | SCAN_NO_DEX);

  • 第二步扫描安装“system\app”目录下的各个系统应用

  • scanDirLI(mSystemAppDir,PackageParser.PARSE_IS_SYSTEM,scanMode);

  • 第三步扫描“data\app”目录,即用户安装的第三方应用
    scanDirLI(mAppInstallDir, 0, scanMode);

  • 第四步扫描" data\app-private"目录,即安装DRM保护的APK文件(目前没有遇到过此类的应用)。
    scanDirLI(mDrmAppPrivateInstallDir,0, scanMode | SCAN_FORWARD_LOCKED);

安装应用的过程

  1. scanDirLI(Filedir, int flags, int scanMode) 遍历安装指定目录下的文件

2.scanPackageLI(FilescanFile,File destCodeFile, FiledestResourceFile, int parseFlags,int scanMode) //安装package文件

3.scanPackageLI(File scanFile, File destCodeFile, FiledestResourceFile,PackageParser.Package pkg, intparseFlags, int scanMode)//通过解析安装包parsePackage获取到安装包的信息结构

4.mInstaller.install(pkgName,pkg.applicationInfo.uid,pkg.applicationInfo.uid);//实现文件复制的安装过程(源文件路径:frameworks\base\cmds\installd\installd.install)

PMS 作用

PMS 快速定位到 某个类 activity 的入口

  • 时期: 开机时
  • Android 5s 手机启动
  • PMS 耗费70%
  • 缓存 信息缓存到我的数据库

PackageParser.java

  /**
     * Representation of a full package parsed from APK files on disk. A package
     * consists of a single base APK, and zero or more split APKs.
     *
     * Deprecated internally. Use AndroidPackage instead.
     */
 public final static class Package implements Parcelable {

        @UnsupportedAppUsage
        public String packageName;

        // The package name declared in the manifest as the package can be
        // renamed, for example static shared libs use synthetic package names.
        public String manifestPackageName;

        /** Names of any split APKs, ordered by parsed splitName */
        public String[] splitNames;

        // TODO: work towards making these paths invariant

        public String volumeUuid;

        /**
         * Path where this package was found on disk. For monolithic packages
         * this is path to single base APK file; for cluster packages this is
         * path to the cluster directory.
         */
        public String codePath;

        /** Path of base APK */
        public String baseCodePath;
        /** Paths of any split APKs, ordered by parsed splitName */
        public String[] splitCodePaths;

        /** Revision code of base APK */
        public int baseRevisionCode;
        /** Revision codes of any split APKs, ordered by parsed splitName */
        public int[] splitRevisionCodes;

        /** Flags of any split APKs; ordered by parsed splitName */
        public int[] splitFlags;

        /**
         * Private flags of any split APKs; ordered by parsed splitName.
         *
         * {@hide}
         */
        public int[] splitPrivateFlags;

        public boolean baseHardwareAccelerated;

        // For now we only support one application per package.
        @UnsupportedAppUsage
        public ApplicationInfo applicationInfo = new ApplicationInfo();

        @UnsupportedAppUsage
        public final ArrayList<Permission> permissions = new ArrayList<Permission>(0);
        @UnsupportedAppUsage
        public final ArrayList<PermissionGroup> permissionGroups = new ArrayList<PermissionGroup>(0);
        @UnsupportedAppUsage
        public final ArrayList<Activity> activities = new ArrayList<Activity>(0);
        @UnsupportedAppUsage
        public final ArrayList<Activity> receivers = new ArrayList<Activity>(0);
        @UnsupportedAppUsage
        public final ArrayList<Provider> providers = new ArrayList<Provider>(0);
        @UnsupportedAppUsage
        public final ArrayList<Service> services = new ArrayList<Service>(0);
        @UnsupportedAppUsage
        public final ArrayList<Instrumentation> instrumentation = new ArrayList<Instrumentation>(0);

SystemServer


        // Start services.
        try {
            t.traceBegin("StartServices");
            //启动引导服务 引导服务中启动 AMS, WMS, PMS
            startBootstrapServices(t);
            //启动核心服务
            startCoreServices(t);
            //启动其他服务
            startOtherServices(t);
        } catch (Throwable ex) {
            Slog.e("System", "******************************************");
            Slog.e("System", "************ Failure starting system services", ex);
            throw ex;
        } finally {
            t.traceEnd(); // StartServices
        }

PackageParser.java

//解析AndroidManifest.xml
private Package parseBaseApk(File apkFile, AssetManager assets, int flags)
            throws PackageParserException {
        final String apkPath = apkFile.getAbsolutePath();

        String volumeUuid = null;
        if (apkPath.startsWith(MNT_EXPAND)) {
            final int end = apkPath.indexOf('/', MNT_EXPAND.length());
            volumeUuid = apkPath.substring(MNT_EXPAND.length(), end);
        }

        mParseError = PackageManager.INSTALL_SUCCEEDED;
        mArchiveSourcePath = apkFile.getAbsolutePath();

        if (DEBUG_JAR) Slog.d(TAG, "Scanning base APK: " + apkPath);

        XmlResourceParser parser = null;
        try {
            final int cookie = assets.findCookieForPath(apkPath);
            if (cookie == 0) {
                throw new PackageParserException(INSTALL_PARSE_FAILED_BAD_MANIFEST,
                        "Failed adding asset path: " + apkPath);
            }
            
            /解析AndroidManifest.xml///
            
            parser = assets.openXmlResourceParser(cookie, ANDROID_MANIFEST_FILENAME);
            final Resources res = new Resources(assets, mMetrics, null);

            final String[] outError = new String[1];
            final Package pkg = parseBaseApk(apkPath, res, parser, flags, outError);
            if (pkg == null) {
                throw new PackageParserException(mParseError,
                        apkPath + " (at " + parser.getPositionDescription() + "): " + outError[0]);
            }

            pkg.setVolumeUuid(volumeUuid);
            pkg.setApplicationVolumeUuid(volumeUuid);
            pkg.setBaseCodePath(apkPath);
            pkg.setSigningDetails(SigningDetails.UNKNOWN);

            return pkg;

        } catch (PackageParserException e) {
            throw e;
        } catch (Exception e) {
            throw new PackageParserException(INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION,
                    "Failed to read manifest from " + apkPath, e);
        } finally {
            IoUtils.closeQuietly(parser);
        }
    }

在这里插入图片描述

  • PMS 用来管理所有的package信息,包括安装、卸载、更新以及解析AndroidManifest.xml以组织相应的数据结构这些数据结构将会被PMS、
  • data/app/pakage/base.apk
  • system/app/pakage/base.apk
  • systemService 启动 让后 在run 方法中启动 引导服务, 引导服务中启动 packageManageService, 然后 packageManageService 扫描 data/app/pakage/base.apk, system/app/pakage/base.apk 包下的文件,加载base.apk 储存到Package 对象里面,方便与查找 四大组件
  • pms 解析手机里面所有apk的manifest.xml 文件
  • ams pms交互,快速找到Activity(javabean) 再来反射 启动Activity 对象

image

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值