相关源码:
1 2 3 4 5 6 7 8 9 10 frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java frameworks/base/services/core/java/com/android/server/pm/PackageInstallerService.java frameworks/base/services/core/java/com/android/server/pm/Settings.java frameworks/base/services/core/java/com/android/server/pm/Installer.java frameworks/base/services/core/java/com/android/server/SystemConfig.java frameworks/base/core/java/android/content/pm/PackageManager.java frameworks/base/core/java/android/content/pm/IPackageManager.aidl frameworks/base/core/java/android/content/pm/PackageParser.java frameworks/base/core/java/com/android/internal/os/InstallerConnection.java frameworks/base/cmds/pm/src/com/android/commands/pm/Pm.java
一. system_server启动pms Android的所有Java服务都是通过System_server进程启动的,并且驻留在system_server进程中。SystemServer进程在启动时,通过创建一个ServerThread线程来启动所有服务,现在先来看看Android服务中PackageManagerService服务启动过程
1 /frameworks/base/services/java/com/android/server/SystemServer.java
1.1 startBootstrapServices() system_server的startBootstrapServices()函数启动一些引导服务,该方法所创建的服务
ActivityManagerService
PowerManagerService
LightService
DisplayManagerService
PackageManagerService
UserManagerService
SensorService服务
其中我们需要的PackageManagerService就在这里启动,我们来看看startBootstrapServices()是如何PMS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 private void startBootstrapServices() { //启动installer服务 Installer installer = mSystemServiceManager.startService(Installer.class); // We need the default display before we can initialize the package manager. mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); //处于加密状态则仅仅解析核心应用 // Only run "core" apps if we're encrypting the device. String cryptState = SystemProperties.get("vold.decrypt"); if (ENCRYPTING_STATE.equals(cryptState)) { Slog.w(TAG, "Detected encryption in progress - only parsing core apps"); mOnlyCore = true; } else if (ENCRYPTED_STATE.equals(cryptState)) { Slog.w(TAG, "Device encrypted - only parsing core apps"); mOnlyCore = true; } // 创建PMS对象 - 启动入口 traceBeginAndSlog("StartPackageManagerService"); mPackageManagerService = PackageManagerService.main(mSystemContext, installer, mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore); // 是否首次启动 mFirstBoot = mPackageManagerService.isFirstBoot(); // 获取PackageManager mPackageManager = mSystemContext.getPackageManager(); Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); }
1.2 startOtherServices() 另外,system_server的startOtherServices()方法会启动其他服务,这个函数也会对PMS作一些操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 private void startOtherServices() { ...... if (!mOnlyCore) { ........ try { //将调用performDexOpt:Performs dexopt on the set of packages mPackageManagerService.updatePackagesIfNeeded(); }....... ........ try { //执行Fstrim,执行磁盘维护操作,未看到详细的资料 //可能类似于TRIM技术,将标记为删除的文件,彻底从硬盘上移除 //而不是等到写入时再移除,目的是提高写入时效率 mPackageManagerService.performFstrimIfNeeded(); }......... ....... try { mPackageManagerService.systemReady(); }........ ....... } }
从上面的代码可以看出,PMS启动后将参与一些系统优化的工作,然后调用SystemReady函数通知系统进入就绪状态。
整个system_server进程启动过程,涉及PackageManagerServer启动流程
二. PMS.main入口 PackageManagerServer.main过程主要创建PMS服务,并注册到ServiceManager大管家
三.PMS构造函数-分析 1 new PackageManagerService(context, installer, factoryTest, onlyCore);
创建PMS对象的过程,就是执行PMS的构造函数,PMS构造函数比较长,我们把这个过程分成几个阶段
BOOT_PROGRESS_PMS_START
BOOT_PROGRESS_PMS_SYSTEM_SCAN_START
BOOT_PROGRESS_PMS_DATA_SCAN_START
BOOT_PROGRESS_PMS_SCAN_END
BOOT_PROGRESS_PMS_READY PMS构造函数里面,在每个阶段开始的时候,都会往Eventlog里面打tag,比如像这样 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START, SystemClock.uptimeMillis());
3.1 PMS_START BOOT_PROGRESS_PMS_START阶段:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 // 输出event log EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START, SystemClock.uptimeMillis()); /** M: Mtprof tool @{ */ //mMTPROFDisable = "1".equals(SystemProperties.get("ro.mtprof.disable")); mMTPROFDisable = false; addBootEvent("Android:PackageManagerService_Start"); /** @} */ if (mSdkVersion <= 0) { Slog.w(TAG, "**** ro.build.version.sdk not set!"); } mContext = context; mFactoryTest = factoryTest; mOnlyCore = onlyCore; // DisplayMetrics是一个描述界面显示,尺寸,分辨率,密度的类。 mMetrics = new DisplayMetrics(); // Settings是Android的全局管理者,用于协助PMS保存所有的安装包信息 mSettings = new Settings(mPackages); mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID, ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID, ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); mSettings.addSharedUserLPw("android.uid.log", LOG_UID, ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID, ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID, ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID, ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); // 获取debug.separate_processes属性 // 如果设置了这个属性,那么会强制应用程序组件在自己的进程中运行。 // 一般情况下不会设置这个属性 String separateProcesses = SystemProperties.get("debug.separate_processes"); if (separateProcesses != null && separateProcesses.length() > 0) { // 所有process都设置这个属性 if ("*".equals(separateProcesses)) { mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES; mSeparateProcesses = null; Slog.w(TAG, "Running with debug.separate_processes: * (ALL)"); } // 个别的process设置这个属性 else { mDefParseFlags = 0; mSeparateProcesses = separateProcesses.split(","); Slog.w(TAG, "Running with debug.separate_processes: " + separateProcesses); } } else { // 不设置这个属性,一般情况下会走这 mDefParseFlags = 0; mSeparateProcesses = null; } // 保存Installer对象 mInstaller = installer; // //用于dex优化 mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context, "*dexopt*"); mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper()); mOnPermissionChangeListeners = new OnPermissionChangeListeners( FgThread.get().getLooper()); // 获取默认的显示信息,保存到mMetrics getDefaultDisplayMetrics(context, mMetrics); // 获取系统配置信息 SystemConfig systemConfig = SystemConfig.getInstance(); mGlobalGids = systemConfig.getGlobalGids(); mSystemPermissions = systemConfig.getSystemPermissions(); mAvailableFeatures = systemConfig.getAvailableFeatures(); synchronized (mInstallLock) { // writer synchronized (mPackages) { //创建名为“PackageManager”的handler线程 mHandlerThread = new ServiceThread(TAG, Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/); mHandlerThread.start(); // 建立PackageHandler消息循环,用于处理外部的安装请求等消息 // 比如如adb install、packageinstaller安装APK时 mHandler = new PackageHandler(mHandlerThread.getLooper()); mProcessLoggingHandler = new ProcessLoggingHandler(); Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT); // 创建各种目录 File dataDir = Environment.getDataDirectory(); mAppInstallDir = new File(dataDir, "app"); mAppLib32InstallDir = new File(dataDir, "app-lib"); mEphemeralInstallDir = new File(dataDir, "app-ephemeral"); mAsecInternalPath = new File(dataDir, "app-asec").getPath(); mDrmAppPrivateInstallDir = new File(dataDir, "app-private"); // 创建用户管理服务 sUserManager = new UserManagerService(context, this, mPackages); // Propagate permission configuration in to package manager. ArrayMap<String, SystemConfig.PermissionEntry> permConfig = systemConfig.getPermissions(); for (int i=0; i<permConfig.size(); i++) { SystemConfig.PermissionEntry perm = permConfig.valueAt(i); BasePermission bp = mSettings.mPermissions.get(perm.name); if (bp == null) { bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN); mSettings.mPermissions.put(perm.name, bp); } if (perm.gids != null) { bp.setGids(perm.gids, perm.perUser); } } // 获取共享库 ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries(); for (int i=0; i<libConfig.size(); i++) { mSharedLibraries.put(libConfig.keyAt(i), new SharedLibraryEntry(libConfig.valueAt(i), null)); } mFoundPolicyFile = SELinuxMMAC.readInstallPolicy(); // 解析packages.xml和packages-backup.xml mRestoredSettings = mSettings.readLPw(sUserManager.getUsers(false)); ... }
总结阶段一主要工作如下:
构造DisplayMetrics类:描述界面显示,尺寸,分辨率,密度。构造完后并获取默认的信息保存到变量mMetrics中。
构造Setting:这个是Android的全局管理者,用于协助PMS保存所有的安装包信息
保存Installer对象
获取系统配置信息:SystemConfig构造函数中通过readPermissions()解析指定目录下的xml,然后把这个信息保存到SystemConfig中,设计的目录如下:
/system/etc/sysconfig
/system/etc/permissions
/oem/etc/sysconfig
/oem/etc/permissions
创建名为PackageManager的handler线程,建立PackageHandler消息循环,用于处理外部的安装请求等消息
创建data下的各种目录,比如data/app,data/app-private
创建用户管理服务UserManagerService
把systemConfig关于xml中的标签所指动态库保存到mSharedLibraries
Setting.readLPw扫描packages.xml和package-backup.xml
补充说明debug.separate_processes这个属性 这个属性你可以使用强制应用程序组件在自己的进程中运行,有两种方法可以使用这个:
1 2 3 4 // 所有的进程都会收到影响 setprop debug.separate_processes // 指定进程受影响 setprop debug.separate_processes "com.google.process.content, com.google.android.samples"
3.2 PMS_SYSTEM_SCAN_START 接下来是BOOT_PROGRESS_PMS_SYSTEM_SCAN_START阶段
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 long startTime = SystemClock.uptimeMillis(); EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START, startTime); final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING | SCAN_INITIAL; //该集合中存放的是已经优化或者不需要优先的文件 final ArraySet<String> alreadyDexOpted = new ArraySet<String>(); final String bootClassPath = System.getenv("BOOTCLASSPATH"); final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH"); //将环境变量BOOTCLASSPATH所执行的文件加入alreadyDexOpted if (bootClassPath != null) { String[] bootClassPathElements = splitString(bootClassPath, ':'); for (String element : bootClassPathElements) { alreadyDexOpted.add(element); } } //将环境变量SYSTEMSERVERCLASSPATH所执行的文件加入alreadyDexOpted if (systemServerClassPath != null) { String[] systemServerClassPathElements = splitString(systemServerClassPath, ':'); for (String element : systemServerClassPathElements) { alreadyDexOpted.add(element); } } ... //此处共享库是由SystemConfig实例化过程赋值的 if (mSharedLibraries.size() > 0) { for (String dexCodeInstructionSet : dexCodeInstructionSets) { for (SharedLibraryEntry libEntry : mSharedLibraries.values()) { final String lib = libEntry.path; ... int dexoptNeeded = DexFile.getDexOptNeeded(lib, dexCodeInstructionSet, "speed", false); if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { alreadyDexOpted.add(lib); //执行dexopt操作 mInstaller.dexopt(lib, Process.SYSTEM_UID, dexCodeInstructionSet, dexoptNeeded, DEXOPT_PUBLIC /*dexFlags*/); } } } } //此处frameworkDir目录为/system/framework File frameworkDir = new File(Environment.getRootDirectory(), "framework"); //添加以下两个文件添加到已优化集合 alreadyDexOpted.add(frameworkDir.getPath() + "/framework-res.apk"); alreadyDexOpted.add(frameworkDir.getPath() + "/core-libart.jar"); String[] frameworkFiles = frameworkDir.list(); if (frameworkFiles != null) { for (String dexCodeInstructionSet : dexCodeInstructionSets) { for (int i=0; i<frameworkFiles.length; i++) { File libPath = new File(frameworkDir, frameworkFiles[i]); String path = libPath.getPath(); //跳过已优化集合中的文件 if (alreadyDexOpted.contains(path)) { continue; } //跳过后缀不为apk和jar的文件 if (!path.endsWith(".apk") && !path.endsWith(".jar")) { continue; } int dexoptNeeded = DexFile.getDexOptNeeded(path, dexCodeInstructionSet, "speed", false); if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { //执行dexopt操作【见小节2.2.1】 mInstaller.dexopt(path, Process.SYSTEM_UID, dexCodeInstructionSet, dexoptNeeded, DEXOPT_PUBLIC /*dexFlags*/); } } } } final VersionInfo ver = mSettings.getInternalVersion(); mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint); mPromoteSystemApps = mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1; if (mPromoteSystemApps) { Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator(); while (pkgSettingIter.hasNext()) { PackageSetting ps = pkgSettingIter.next(); if (isSystemApp(ps)) { mExistingSystemPackages.add(ps.name); } } } //收集供应商包名:/vendor/overlay File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR); scanDirLI(vendorOverlayDir, PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags | SCAN_TRUSTED_OVERLAY, 0); //收集包名:/system/framework scanDirLI(frameworkDir, PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR | PackageParser.PARSE_IS_PRIVILEGED, scanFlags | SCAN_NO_DEX, 0); //收集私有的系统包名:/system/priv-app final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app"); scanDirLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0); //收集一般地系统包名:/system/app final File systemAppDir = new File(Environment.getRootDirectory(), "app"); scanDirLI(systemAppDir, PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); //收集私有供应商包名:/vendor/priv-app final File privilegedVendorAppDir = new File(Environment.getVendorDirectory(), "priv-app"); scanDirLI(privilegedVendorAppDir, PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0); //收集所有的供应商包名:/vendor/app File vendorAppDir = new File(Environment.getVendorDirectory(), "app"); vendorAppDir = vendorAppDir.getCanonicalFile(); scanDirLI(vendorAppDir, PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); //收集所有OEM包名:/oem/app final File oemAppDir = new File(Environment.getOemDirectory(), "app"); scanDirLI(oemAppDir, PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); //移除文件 mInstaller.moveFiles(); //删除不在存在的系统包 final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>(); if (!mOnlyCore) { Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); while (psit.hasNext()) { PackageSetting ps = psit.next(); if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) { continue; } final PackageParser.Package scannedPkg = mPackages.get(ps.name); if (scannedPkg != null) { if (mSettings.isDisabledSystemPackageLPr(ps.name)) { removePackageLI(ps, true); mExpectingBetter.put(ps.name, ps.codePath); } continue; } if (!mSettings.isDisabledSystemPackageLPr(ps.name)) { psit.remove(); removeDataDirsLI(null, ps.name); } else { final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name); if (disabledPs.codePath == null || !disabledPs.codePath.exists()) { possiblyDeletedUpdatedSystemApps.add(ps.name); } } } } //清理所有安装不完整的包 ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr(); for(int i = 0; i < deletePkgsList.size(); i++) { cleanupInstallFailedPackage(deletePkgsList.get(i)); } //删除临时文件 deleteTempPackageFiles(); //移除不相干包中的所有共享userID mSettings.pruneSharedUsersLPw();
PMS_SYSTEM_SCAN_START阶段主要做了如下工作:
首先将BOOTCLASSPATH,SYSTEMSERVERCLASSPATH这两个环境变量下的路径加入到不需要优化dex优化集合alreadyDexOpted中
SYSTEMSERVERCLASSPATH:主要包含/system/framework目录下的services.jar ethernet-service.jar,wifi-service.jar这3个文件
BOOTCLASSPATH:该环境变量内容较多,不同的ROM可能有所不同,常见内容包含/system/frmework目录下的freamework.jar,ext.jar,core-libart.jar,telephony-commom.jar,ims-common.jar,core-junit.jar等
获取共享库mSharedLibraries,判断是否需要dex优化,如果需要则进行dex优化,并加入到alreadyDexOpted列表中
添加framework-res.apk,core-libart.jar两个文件添加到已优化集合alreadyDexOpted中
将framework目录下,其他的apk或jar,进行dex优化并加入到优化集合alreadyDexOpted中
scanDirLi():扫描指定目录下的apk文件,最终调用PackageParse.parseBaseApk来完成AndroidManifest.xml的文件解析,生成Application,activity,service,broadcast,provider等信息
删除系统不存在的包removePackageLI
清理安装失败的包cleanupInstallFaildPackage
删除临时文件deleteTempPackageFiles
移除不想干包中的所有共享UserId
3.3 PMS_DATA_SCAN_START BOOT_PROGRESS_PMS_DATA_SCAN_START阶段:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 if (!mOnlyCore) { EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START, SystemClock.uptimeMillis()); scanDirLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0); scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK, scanFlags | SCAN_REQUIRE_KNOWN, 0); /** * Remove disable package settings for any updated system * apps that were removed via an OTA. If they're not a * previously-updated app, remove them completely. * Otherwise, just revoke their system-level permissions. */ for (String deletedAppName : possiblyDeletedUpdatedSystemApps) { PackageParser.Package deletedPkg = mPackages.get(deletedAppName); mSettings.removeDisabledSystemPackageLPw(deletedAppName); String msg; if (deletedPkg == null) { msg = "Updated system package " + deletedAppName + " no longer exists; wiping its data"; removeDataDirsLI(null, deletedAppName); } else { msg = "Updated system app + " + deletedAppName + " no longer present; removing system privileges for " + deletedAppName; deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM; PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName); deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM; } logCriticalInfo(Log.WARN, msg); } /** * Make sure all system apps that we expected to appear on * the userdata partition actually showed up. If they never * appeared, crawl back and revive the system version. */ for (int i = 0; i < mExpectingBetter.size(); i++) { final String packageName = mExpectingBetter.keyAt(i); if (!mPackages.containsKey(packageName)) { final File scanFile = mExpectingBetter.valueAt(i); logCriticalInfo(Log.WARN, "Expected better " + packageName + " but never showed up; reverting to system"); final int reparseFlags; if (FileUtils.contains(privilegedAppDir, scanFile)) { reparseFlags = PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR | PackageParser.PARSE_IS_PRIVILEGED; } else if (FileUtils.contains(systemAppDir, scanFile)) { reparseFlags = PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR; } else if (FileUtils.contains(vendorAppDir, scanFile)) { reparseFlags = PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR; } else if (FileUtils.contains(oemAppDir, scanFile)) { reparseFlags = PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR; } else { Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile); continue; } mSettings.enableSystemPackageLPw(packageName); try { scanPackageLI(scanFile, reparseFlags, scanFlags, 0, null); } catch (PackageManagerException e) { Slog.e(TAG, "Failed to parse original system package: " + e.getMessage()); } } } } mExpectingBetter.clear(); // Now that we know all of the shared libraries, update all clients to have // the correct library paths. updateAllSharedLibrariesLPw(); for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) { // NOTE: We ignore potential failures here during a system scan (like // the rest of the commands above) because there's precious little we // can do about it. A settings error is reported, though. adjustCpuAbisForSharedUserLPw(setting.packages, null /* scanned package */, false /* force dexopt */, false /* defer dexopt */); } // Now that we know all the packages we are keeping, // read and update their last usage times. mPackageUsage.readLP();
3.4 PMS_SCAN_END BOOT_PROGRESS_PMS_SCAN_END阶段:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END, SystemClock.uptimeMillis()); Slog.i(TAG, "Time to scan packages: " + ((SystemClock.uptimeMillis()-startTime)/1000f) + " seconds"); // 当sdk版本不一致时,需要更新权限 int updateFlags = UPDATE_PERMISSIONS_ALL; if (ver.sdkVersion != mSdkVersion) { Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to " + mSdkVersion + "; regranting permissions for internal storage"); updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; } updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags); ver.sdkVersion = mSdkVersion; //当这是ota后的首次启动,正常启动则需要清除目录的缓存代码 if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) { for (UserInfo user : sUserManager.getUsers(true)) { mSettings.applyDefaultPreferredAppsLPw(this, user.id); applyFactoryDefaultBrowserLPw(user.id); primeDomainVerificationsLPw(user.id); } } //当权限和其他默认项都完成更新,则清理相关信息 final int storageFlags; if (StorageManager.isFileEncryptedNativeOrEmulated()) { storageFlags = StorageManager.FLAG_STORAGE_DE; } else { storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; } reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL, UserHandle.USER_SYSTEM, storageFlags); //当这是ota后的首次启动,正常启动则需要清除目录的缓存代码 if (mIsUpgrade && !onlyCore) { Slog.i(TAG, "Build fingerprint changed; clearing code caches"); for (int i = 0; i < mSettings.mPackages.size(); i++) { final PackageSetting ps = mSettings.mPackages.valueAt(i); if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) { // No apps are running this early, so no need to freeze clearAppDataLIF(ps.pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); } } ver.fingerprint = Build.FINGERPRINT; } checkDefaultBrowser(); //当权限和其他默认项都完成更新,则清理相关信息 mExistingSystemPackages.clear(); mPromoteSystemApps = false; // All the changes are done during package scanning. ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION; //信息写回packages.xml文件 mSettings.writeLPr();
当sdk版本不一致时,需要跟新权限
当这是ota后的首次启动,正常启动则需要清理目标的缓存代码
当权限和其他默认项都完成更新,则清理相关信息
信息写回package.xml文件
3.5 PMS_READY BOOT_PROGRESS_PMS_READY阶段:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY, SystemClock.uptimeMillis()); if (!mOnlyCore) { mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr(); mRequiredInstallerPackage = getRequiredInstallerLPr(); mRequiredUninstallerPackage = getRequiredUninstallerLPr(); mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr(); mIntentFilterVerifier = new IntentVerifierProxy(mContext, mIntentFilterVerifierComponent); mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr( PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES); mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr( PackageManager.SYSTEM_SHARED_LIBRARY_SHARED); } else { mRequiredVerifierPackage = null; mRequiredInstallerPackage = null; mRequiredUninstallerPackage = null; mIntentFilterVerifierComponent = null; mIntentFilterVerifier = null; mServicesSystemSharedLibraryPackageName = null; mSharedSystemSharedLibraryPackageName = null; } mInstallerService = new PackageInstallerService(context, this); final ComponentName ephemeralResolverComponent = getEphemeralResolverLPr(); final ComponentName ephemeralInstallerComponent = getEphemeralInstallerLPr(); // both the installer and resolver must be present to enable ephemeral if (ephemeralInstallerComponent != null && ephemeralResolverComponent != null) { if (DEBUG_EPHEMERAL) { Slog.i(TAG, "Ephemeral activated; resolver: " + ephemeralResolverComponent + " installer:" + ephemeralInstallerComponent); } mEphemeralResolverComponent = ephemeralResolverComponent; mEphemeralInstallerComponent = ephemeralInstallerComponent; setUpEphemeralInstallerActivityLP(mEphemeralInstallerComponent); mEphemeralResolverConnection = new EphemeralResolverConnection(mContext, mEphemeralResolverComponent); } else { if (DEBUG_EPHEMERAL) { final String missingComponent = (ephemeralResolverComponent == null) ? (ephemeralInstallerComponent == null) ? "resolver and installer" : "resolver" : "installer"; Slog.i(TAG, "Ephemeral deactivated; missing " + missingComponent); } mEphemeralResolverComponent = null; mEphemeralInstallerComponent = null; mEphemeralResolverConnection = null; } mEphemeralApplicationRegistry = new EphemeralApplicationRegistry(this); } // synchronized (mPackages) } // synchronized (mInstallLock) // Now after opening every single application zip, make sure they // are all flushed. Not really needed, but keeps things nice and // tidy. Runtime.getRuntime().gc(); // The initial scanning above does many calls into installd while // holding the mPackages lock, but we're mostly interested in yelling // once we have a booted system. mInstaller.setWarnIfHeld(mPackages); // Expose private service for system components to use. LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());
初始化PackageInstallerService
GC回收下内存
四. PMS构造函数-总结 PMS初始化过程,分为5个阶段: 1.PMS_START阶段:
创建Setting对象;
将6类shareUserId到mSettings;
初始化SystemConfig;
创建名为“PackageManagerService”的handler线程mHandlerThread
创建UserManagerService多用户管理服务
通过解析4大目录中的xml文件构造共享mSharedLibraries;
PMS_SYSTEM_SCAN_START阶段:
mSharedLibraries共享库的文件执行dexopt操作
system/framework目录中满足的pak或jar文件执行dexopt操作
扫描系统apk
PMS_DATA_SCAN_START阶段:
扫描/data/app目录下的apk
扫描/data/app-private目录下的apk
PMS_SCAN_END
将上诉信息写回/data/system/package.xml 5 PMS_READY阶段
创建服务PackageInstallerService
到这里,大致介绍完了整个PMS构造函数的流程,基本上PMS_SCAN_END阶段我们apk就算安装完成了,接下来是单独看看几个比较重要模块
Setting
SystemConfig-readPermissions
scanPackageLI
五. Settings 在BOOT_PROGRESS_PMS_START阶段,我们会创建Setting对象,以及一堆addSharedUserLPw调用
1 2 3 4 mSettings = new Settings(mPackages); mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID, ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
5.1 创建Settings
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 [frameworks/base/services/core/java/com/android/server/pm/Settings.java] Settings(Object lock) { this(Environment.getDataDirectory(), lock); } Settings(File dataDir, Object lock) { mLock = lock; mRuntimePermissionsPersistence = new RuntimePermissionPersistence(mLock); //创建目录"data/system" mSystemDir = new File(dataDir, "system"); mSystemDir.mkdirs(); FileUtils.setPermissions(mSystemDir.toString(), FileUtils.S_IRWXU|FileUtils.S_IRWXG |FileUtils.S_IROTH|FileUtils.S_IXOTH, -1, -1); // packages.xml和packages-backup.xml为一组,用于描述系统所安装的Package信息, // 其中packages-backup.xml是packages.xml的备份 // PMS写把数据写到backup文件中,信息全部写成功后在改名为非backup文件, // 以防止在写文件的过程中出错,导致信息丢失 mSettingsFilename = new File(mSystemDir, "packages.xml"); mBackupSettingsFilename = new File(mSystemDir, "packages-backup.xml"); //packages.list保存系统中存在的所有非系统自带的APK信息,即UID大于10000的apk mPackageListFilename = new File(mSystemDir, "packages.list"); FileUtils.setPermissions(mPackageListFilename, 0640, SYSTEM_UID, PACKAGE_INFO_GID); //感觉是sdcardfs相关的文件 final File kernelDir = new File("/config/sdcardfs"); mKernelMappingFilename = kernelDir.exists() ? kernelDir : null; // Deprecated: Needed for migration //packages-stopped.xml用于描述系统中强行停止运行的package信息,backup也是备份文件 mStoppedPackagesFilename = new File(mSystemDir, "packages-stopped.xml"); mBackupStoppedPackagesFilename = new File(mSystemDir, "packages-stopped-backup.xml"); }
Setting的构造函数主要用于创建data/system 目录和一些xml文件,并配置相应的权限,其中:
packages.xml记录所有安装app信息,当系统进行程序安装,卸载和更新操作时,均会跟新该文件
package-backup.xml 备份文件
packages-stopped.xml 记录被用户强行停止的应用Package信息
packages-stopped-backup.xml 备份文件
packages.list 记录非系统自带的apk的数据信息,这些apk有变化会更新该文件
5.2 Setting.readLPw readLPw()函数,从/data/system/packages.xml或packages-backup.xml文件中获取packages,permissions相关信息,添加相关内存列表。packages.xml文件记录了系统的permisssions以及每个apk的name,codePath,flags,version等信息这些信息主要通过apk的AndroidManifest.xml解析获取,解析完apk后将更新信息写入这个文件,下次开机直接从里面读取相关信息添加到内存相关结构中,当有apk升级,安装,删除会更新这个文件。
5.3 Setting.writeLPr writeLPr函数,将解析出的每个apk的信息(mSetting.mPackages)保存到packages.xml和packages.list文件。packages.list记录如下数据:pkgName,userid,debugFlag,dataPath(包的数据路径)
六. SystemConfig-readPermissions 同样在BOOT_PROGRESS_PMS_START阶段,我们会初始化SystemConfig去获取系统配置信息
1 2 3 4 5 // 获取系统配置信息 SystemConfig systemConfig = SystemConfig.getInstance(); mGlobalGids = systemConfig.getGlobalGids(); mSystemPermissions = systemConfig.getSystemPermissions(); mAvailableFeatures = systemConfig.getAvailableFeatures();
6.1 创建SystemCofig
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 [frameworks/base/services/core/java/com/android/server/SystemConfig.java] //单例模式 public static SystemConfig getInstance() { synchronized (SystemConfig.class) { if (sInstance == null) { sInstance = new SystemConfig(); } return sInstance; } } SystemConfig() { // system/etc/目录 readPermissions(Environment.buildPath( Environment.getRootDirectory(), "etc", "sysconfig"), ALLOW_ALL); readPermissions(Environment.buildPath( Environment.getRootDirectory(), "etc", "permissions"), ALLOW_ALL); int odmPermissionFlag = ALLOW_LIBS | ALLOW_FEATURES | ALLOW_APP_CONFIGS; // odm/etc/目录 readPermissions(Environment.buildPath( Environment.getOdmDirectory(), "etc", "sysconfig"), odmPermissionFlag); readPermissions(Environment.buildPath( Environment.getOdmDirectory(), "etc", "permissions"), odmPermissionFlag); // oem/etc/目录 readPermissions(Environment.buildPath( Environment.getOemDirectory(), "etc", "sysconfig"), ALLOW_FEATURES); readPermissions(Environment.buildPath( Environment.getOemDirectory(), "etc", "permissions"), ALLOW_FEATURES); }
从上面可以看出,SystemConfig是单例模式,会通过readPermissions解析目录下的xml文件: */system/etc/sysconfig */system/etc/permissions */odm/etc/sysconfig */odm/etc/permissions */oem/etc/sysconfig */oem/etc/permissions 其中比较重要的是system/etc/permisssions目录,该目录大多来源于代码中的frameworks/(base or native)/data/etc,这些文件的作用表明系统支持的feature有哪些,例如是否支持蓝牙,wifi,p2p
6.2 readzPermissions
readPermissions会循环去读取目录下的xml,但是它会跳过platform.xml文件,最后再去读取platform.xml文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 void readPermissions(File libraryDir, int permissionFlag) { //检测目录是否存在,是否可读 .......... // Iterate over the files in the directory and scan .xml files File platformFile = null; // 循环解析xml文件 for (File f : libraryDir.listFiles()) { // 跳过,最后再解析platform.xml if (f.getPath().endsWith("etc/permissions/platform.xml")) { platformFile = f; continue; } // 解析可读的xml文件 readPermissionsFromXml(f, permissionFlag); } // 最后解析platform.xml文件 if (platformFile != null) { readPermissionsFromXml(platformFile, permissionFlag); }
我们发现读取函数最后都调用最后都调用readPermissionsFromXml(),函数readPermissionFromXml最终会使用XMLPullParase的方式解析这些文件,然后再把解析出来的数据结构保存到PMS中
6.2.1 android.hardware.bluetooth.xml 最终会解析并且保存到PMS的 final ArrayMap<String, FeatureInfo> mAvailableFeatures中。
1 2 3 <permissions> <feature name="android.hardware.bluetooth" /> </permissions>
6.2.2 com.android.location.provider.xml 指明了运行一些library时,还需要加载一些java库。 这个最终会解析并保存到PMS的final ArrayMap<String, SharedLibraryEntry> mSharedLibraries中。
1 2 3 4 5 <permissions> <library name="com.android.location.provider" file="/system/framework/com.android.location.provider.jar" /> </permissions>
6.2.3 platform.xml 这个文件中定义了底层GID和app层权限名字之间的对应关系,或者直接给某一个uid赋予对应的权限:
1 2 3 4 5 6 7 8 9 10 <permissions> <permission name="android.permission.WRITE_EXTERNAL_STORAGE" > <group gid="sdcard_r" /> <group gid="sdcard_rw" /> </permission> ...... <assign-permission name="android.permission.MODIFY_AUDIO_SETTINGS" uid="media" /> <assign-permission name="android.permission.ACCESS_SURFACE_FLINGER" uid="media" /> ...... </permissions>
解析标签的时候,会创建一个PermissionEntry类,他关联了gids和permission name: 最终PermissionEntry会放入SystemConfig的final ArrayMap<String, PermissionEntry> mPermissions变量中。
1 2 3 4 5 6 7 public static final class PermissionEntry { public final String name; public int[] gids; PermissionEntry(String _name) { name = _name; } }
解析的时候表示把属性name中的字符串表示的权限赋予属性uid中的用户。uid和name则存入SystemConfig中的SparseArray> 类型的mSystemPermissions变量中
7.2 scanPackageLI安装apk PackageManagerService的scanPackageLI过程scanPackageLI()有3个重载的方法,参数稍有不同:
1 2 3 4 5 6 7 8 9 10 // 第(1)个 private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags, long currentTime, UserHandle user) // 第(2)个 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile, final int policyFlags, int scanFlags, long currentTime, UserHandle user) // 第(3)个 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, final int policyFlags, int scanFlags, long currentTime, UserHandle user)
(1)scanPackageLI(File scanFile, int parseFlags,…)函数
实例化一个PackageParser对象,接着调用该对象的parsePackage()对APK文件进行解析。 实例化一个Package对象,用于保存解析出的APK信息 从AndroidManifest.xml文件中解析出VersionCode、VersionName、installLocation等全局属性信息,然后根据标签循环解析XML文件包含的其它组成部分,将解析出的信息添加到Package对象的相关列表中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { //创建出PackageParser对象 PackageParser pp = new PackageParser(); ........... final PackageParser.Package pkg; try { // 解析package pkg = pp.parsePackage(scanFile, parseFlags); } catch (PackageParserException e) { .......... } finally { .......... } //调用第(2)个scanPackageLI return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user); }
最后会调用第(2)个scanPackageLI去继续解析。
(2)scanPackageLI(PackageParser.Package pkg, File scanFile,…)函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile, final int policyFlags, int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { //有childPackage时,第一次只执行检查的工作 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { //当解析一个Package的AndroidManifest.xml时,如果该XML文件中使用了"package"的tag //那么该tag对应的package是当前XML文件对应package的childPackage if (pkg.childPackages != null && pkg.childPackages.size() > 0) { scanFlags |= SCAN_CHECK_ONLY; } } else { //第二次进入,才开始实际的解析 scanFlags &= ~SCAN_CHECK_ONLY; } final PackageParser.Package scannedPkg; try { // Scan the parent //scanFlags将决定这一次是否仅执行检查工作 scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags, currentTime, user); final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; for (int i = 0; i < childCount; i++) { PackageParser.Package childPkg = pkg.childPackages.get(i); scanPackageLI(childPkg, policyFlags, scanFlags, currentTime, user); } } finally { ......... } if ((scanFlags & SCAN_CHECK_ONLY) != 0) { //第一次检查完毕后,再次调用函数 return scanPackageTracedLI(pkg, policyFlags, scanFlags, currentTime, user); } return scannedPkg; }
(3)scanPackageLI(PackageParser.Package pkg, final int policyFlags,…)函数
最终会走到第三个scanPackageLI函数,这个函数最后会调用scanPackageDirtyLI函数,scanPackageDirtyLI是实际解析package的函数,这个才是真正干活的。
1 2 3 4 5 6 7 8 9 10 11 12 13 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, final int policyFlags, int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { boolean success = false; try { //实际的解析函数,很长... final PackageParser.Package res = scanPackageDirtyLI(pkg, policyFlags, scanFlags, currentTime, user); success = true; return res; } finally { ........... } }
7.3 scanPackageDirtyLI 通过上述的扫描过程,我们得到了当前apk文件对应的Package信息。不过这部分信息是存储在PackageParser中的,我们必须将这部分信息传递到PMS中。毕竟最终的目的是:让PMS能得到所有目录下Package的信息。 scanPackageDirtyLI函数主要就是把签名解析应用程序得到的package、provider、service、receiver和activity等信息保存在PackageManagerService相关的成员列表里。
比如将每个APK的receivers列表里的元素,通过mReceivers.addActivity(a, “receiver”)添加到PMS成员列表mReceivers中:
1 final ActivityIntentResolver mReceivers = new ActivityIntentResolver();` 由于实际解析函数太长,粗略看下有1000来行,读者有兴趣的可以自行研究。
八、开机时间分析 adb shell cat /proc/bootprof/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 C:\Users\shun>adb shell cat /proc/bootprof ---------------------------------------- 0 BOOT PROF (unit:msec) ---------------------------------------- 1655 : preloader 1001 : lk 493 : lk->Kernel ---------------------------------------- 5156.702307 : Kernel_init_done 5171.629538 : SElinux start. 10739.699692 : SElinux end. 11496.788538 : INIT: on init start 11878.325615 : INIT:eMMC:Mount_START 12777.653384 : INIT:eMMC:Mount_END 12780.874230 : INIT:PROTECT:Mount_START 12938.042615 : INIT:PROTECT:Mount_END 14029.370538 : INIT: eng build setting 15215.342538 : BOOT_Animation:START 16618.475076 : Zygote:Preload Start 20691.658230 : Zygote:Preload 2775 classes in 4062ms 23061.424153 : Zygote:Preload 274 obtain resources in 2334ms 23110.519076 : Zygote:Preload 31 resources in 47ms 23240.816000 : Zygote:Preload End 23720.832000 : Android:SysServerInit_START 24448.175153 : Android:PackageManagerService_Start 24747.363153 : Android:PMS_scan_START 24817.216000 : Android:PMS_scan_done:/custom/framework 24947.104384 : Android:PMS_scan_done:/system/framework 25131.265384 : Android:PMS_scan_done:/system/priv-app 25533.440461 : Android:PMS_scan_done:/system/app 25540.237769 : Android:PMS_scan_done:/system/vendor/app 25542.379538 : Android:PMS_scan_done:/system/vendor/operator/app 25544.285615 : Android:PMS_scan_done:/custom/app 25551.297076 : Android:PMS_scan_data_start 25967.971076 : Android:PMS_scan_data_done:/data/app 25969.811230 : Android:PMS_scan_data_done:/data/app-private 25971.862692 : Android:PMS_scan_END 26224.410076 : Android:PMS_READY 30108.635538 : AP_Init:[service]:[com.mediatek.security]:[com.mediatek.security/.service.PermControlService]:pid:738 30548.305692 : AP_Init:[broadcast]:[com.android.settings]:[com.android.settings/.widget.SettingsAppWidgetProvider]:pid:769 31341.380923 : AP_Init:[broadcast]:[com.mediatek.engineermode]:[com.mediatek.engineermode/.wifi.WifiStateReceiver]:pid:806 31563.917923 : AP_Init:[broadcast]:[com.tvguo.app]:[com.tvguo.app/.content.TvguoStateReceiver]:pid:829 31708.206000 : AP_Init:[service]:[com.android.systemui]:[com.android.systemui/.ImageWallpaper]:pid:847 31796.008076 : AP_Init:[service]:[com.android.inputmethod.latin]:[com.android.inputmethod.latin/.LatinIME]:pid:860 31987.434923 : AP_Init:[added application]:[com.mediatek.dongle]:[com.mediatek.dongle]:pid:878:(PersistAP) 32051.271692 : AP_Init:[added application]:[com.mediatek.bluetooth]:[com.mediatek.bluetooth]:pid:891:(PersistAP) 32142.389846 : AP_Init:[activity]:[com.android.launcher3]:[com.android.launcher3/.Launcher]:pid:906 32170.530846 : Android:SysServerInit_END 32309.788000 : AP_Init:[service]:[com.android.printspooler]:[com.android.printspooler/.PrintSpoolerService]:pid:923 33967.604076 : AP_Init:[broadcast]:[com.android.contacts]:[com.android.contacts/com.mediatek.contacts.simcontact.BootCmpReceiver]:pid:972 34752.970538 : AP_Init:[content provider]:[android.process.acore]:[com.android.providers.contacts/.ContactsProvider2]:pid:1028 35486.120000 : BOOT_Animation:END ---------------------------------
我们可以从上面的信息看到PMS在开机的时候做的动作和时间分布:(因为手上只有kk的平台,所以信息不太对应)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 24747.363153 : Android:PMS_scan_START 24817.216000 : Android:PMS_scan_done:/custom/framework 24947.104384 : Android:PMS_scan_done:/system/framework 25131.265384 : Android:PMS_scan_done:/system/priv-app 25533.440461 : Android:PMS_scan_done:/system/app 25540.237769 : Android:PMS_scan_done:/system/vendor/app 25542.379538 : Android:PMS_scan_done:/system/vendor/operator/app 25544.285615 : Android:PMS_scan_done:/custom/app 25551.297076 : Android:PMS_scan_data_start 25967.971076 : Android:PMS_scan_data_done:/data/app 25969.811230 : Android:PMS_scan_data_done:/data/app-private 25971.862692 : Android:PMS_scan_END 26224.410076 : Android:PMS_READY 一般app装的越多,那么开机时间就会越长。