- Android框架层
- Android包管理机制
- Android框架层
<!--more-->本文首发于微信公众号「刘望舒」
前言
PMS的创建过程分为两个部分进行讲解,分别是SyetemServer处理部分和PMS构造方法。其中SyetemServer处理部分和AMS和WMS的创建过程是类似的,可以将它们进行对比,这样可以更好的理解和记忆这一知识点。
1. SyetemServer处理部分
PMS是在SyetemServer进程中被创建的,SyetemServer进程用来创建系统服务,不了解它的可以查看Android系统启动流程(三)解析SyetemServer进程启动过程这篇文章。 从SyetemServer的入口方法main方法开始讲起,如下所示。 frameworks/base/services/java/com/android/server/SystemServer.java
1 public static void main(String[] args) { 2 new SystemServer().run(); 3 }
main方法中只调用了SystemServer的run方法,如下所示。 frameworks/base/services/java/com/android/server/SystemServer.java
1private void run() { 2 try { 3 ... 4 //创建消息Looper 5 Looper.prepareMainLooper(); 6 //加载了动态库libandroid_servers.so 7 System.loadLibrary("android_servers");//1 8 performPendingShutdown(); 9 // 创建系统的Context 10 createSystemContext(); 11 // 创建SystemServiceManager 12 mSystemServiceManager = new SystemServiceManager(mSystemContext);//2 13 mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart); 14 LocalServices.addService(SystemServiceManager.class, mSystemServiceManager); 15 SystemServerInitThreadPool.get(); 16 } finally { 17 traceEnd(); 18 } 19 try { 20 traceBeginAndSlog("StartServices"); 21 //启动引导服务 22 startBootstrapServices();//3 23 //启动核心服务 24 startCoreServices();//4 25 //启动其他服务 26 startOtherServices();//5 27 SystemServerInitThreadPool.shutdown(); 28 } catch (Throwable ex) { 29 Slog.e("System", "******************************************"); 30 Slog.e("System", "************ Failure starting system services", ex); 31 throw ex; 32 } finally { 33 traceEnd(); 34 } 35 ... 36}
在注释1处加载了动态库libandroid_servers.so。接下来在注释2处创建SystemServiceManager,它会对系统的服务进行创建、启动和生命周期管理。在注释3中的startBootstrapServices方法中用SystemServiceManager启动了ActivityManagerService、PowerManagerService、PackageManagerService等服务。在注释4处的startCoreServices方法中则启动了DropBoxManagerService、BatteryService、UsageStatsService和WebViewUpdateService。注释5处的startOtherServices方法中启动了CameraService、AlarmManagerService、VrManagerService等服务。这些服务的父类均为SystemService。从注释3、4、5的方法可以看出,官方把系统服务分为了三种类型,分别是引导服务、核心服务和其他服务,其中其他服务是一些非紧要和一些不需要立即启动的服务。这些系统服务总共有100多个,我们熟知的AMS属于引导服务,WMS属于其他服务, 本文要讲的PMS属于引导服务,因此这里列出引导服务以及它们的作用,见下表。
| 引导服务 | 作用 |
|---|---|
| Installer | 系统安装apk时的一个服务类,启动完成Installer服务之后才能启动其他的系统服务 |
| ActivityManagerService | 负责四大组件的启动、切换、调度。 |
| PowerManagerService | 计算系统中和Power相关的计算,然后决策系统应该如何反应 |
| LightsService | 管理和显示背光LED |
| DisplayManagerService | 用来管理所有显示设备 |
| UserManagerService | 多用户模式管理 |
| SensorService | 为系统提供各种感应器服务 |
| PackageManagerService | 用来对apk进行安装、解析、删除、卸载等等操作 |
查看启动引导服务的注释3处的startBootstrapServices方法。 frameworks/base/services/java/com/android/server/SystemServer.java
1private void startBootstrapServices() { 2 ... 3 String cryptState = SystemProperties.get("vold.decrypt");//1 4 if (ENCRYPTING_STATE.equals(cryptState)) { 5 Slog.w(TAG, "Detected encryption in progress - only parsing core apps"); 6 mOnlyCore = true; 7 } else if (ENCRYPTED_STATE.equals(cryptState)) { 8 Slog.w(TAG, "Device encrypted - only parsing core apps"); 9 mOnlyCore = true; 10 } 11 ... 12 traceBeginAndSlog("StartPackageManagerService"); 13 mPackageManagerService = PackageManagerService.main(mSystemContext, installer, 14 mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);//2 15 mFirstBoot = mPackageManagerService.isFirstBoot();//3 16 mPackageManager = mSystemContext.getPackageManager(); 17 traceEnd(); 18 ... 19}
注释1处读取init.rc的vold.decrypt属性,如果它的值为"trigger_restart_min_framework",说明我们加密了设备,这时mOnlyCore的值为true,表示只运行“核心”程序,这是为了创建一个极简的启动环境。 注释2处的PMS的main方法主要用来创建PMS,注释3处获取boolean类型的变量mFirstBoot,它用于表示PMS是否首次被启动。mFirstBoot是后续WMS创建时所需要的参数,从这里就可以看出系统服务之间是有依赖关系的,它们的启动顺序不能随意被更改。
2. PMS构造方法
PMS的main方法如下所示。 frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
1 public static PackageManagerService main(Context context, Installer installer, 2 boolean factoryTest, boolean onlyCore) { 3 PackageManagerServiceCompilerMapping.checkProperties(); 4 PackageManagerService m = new PackageManagerService(context, installer, 5 factoryTest, onlyCore); 6 m.enableSystemUserPackages(); 7 ServiceManager.addService("package", m); 8 return m; 9 }
main方法主要做了两件事,一个是创建PMS对象,另一个是将PMS注册到ServiceManager中。 PMS的构造方法大概有600多行,分为5个阶段,每个阶段会打印出相应的EventLog,EventLog用于打印Android系统的事件日志。
- BOOT_PROGRESS_PMS_START(开始阶段)
- BOOT_PROGRESS_PMS_SYSTEM_SCAN_START(扫描系统阶段)
- BOOT_PROGRESS_PMS_DATA_SCAN_START(扫描Data分区阶段)
- BOOT_PROGRESS_PMS_SCAN_END(扫描结束阶段)
- BOOT_PROGRESS_PMS_READY(准备阶段)
2.1 开始阶段
PMS的构造方法中会获取一些包管理需要属性,如下所示。 frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
1public PackageManagerService(Context context, Installer installer, 2 boolean factoryTest, boolean onlyCore) { 3 LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES); 4 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager"); 5 //打印开始阶段日志 6 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START, 7 SystemClock.uptimeMillis()) 8 ... 9 //用于存储屏幕的相关信息 10 mMetrics = new DisplayMetrics(); 11 //Settings用于保存所有包的动态设置 12 mSettings = new Settings(mPackages); 13 //在Settings中添加多个默认的sharedUserId 14 mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID, 15 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);//1 16 mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID, 17 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 18 mSettings.addSharedUserLPw("android.uid.log", LOG_UID, 19 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 20 ... 21 mInstaller = installer; 22 //创建Dex优化工具类 23 mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context, 24 "*dexopt*"); 25 mDexManager = new DexManager(this, mPackageDexOptimizer, installer, mInstallLock); 26 mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper()); 27 mOnPermissionChangeListeners = new OnPermissionChangeListeners( 28 FgThread.get().getLooper()); 29 getDefaultDisplayMetrics(context, mMetrics); 30 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "get system config"); 31 //得到全局系统配置信息。 32 SystemConfig systemConfig = SystemConfig.getInstance(); 33 //获取全局的groupId 34 mGlobalGids = systemConfig.getGlobalGids(); 35 //获取系统权限 36 mSystemPermissions = systemConfig.getSystemPermissions(); 37 mAvailableFeatures = systemConfig.getAvailableFeatures(); 38 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 39 mProtectedPackages = new ProtectedPackages(mContext); 40 //安装APK时需要的锁,保护所有对installd的访问。 41 synchronized (mInstallLock) {//1 42 //更新APK时需要的锁,保护内存中已经解析的包信息等内容 43 synchronized (mPackages) {//2 44 //创建后台线程ServiceThread 45 mHandlerThread = new ServiceThread(TAG, 46 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/); 47 mHandlerThread.start(); 48 //创建PackageHandler绑定到ServiceThread的消息队列 49 mHandler = new PackageHandler(mHandlerThread.getLooper());//3 50 mProcessLoggingHandler = new ProcessLoggingHandler(); 51 //将PackageHandler添加到Watchdog的检测集中 52 Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);//4 53 54 mDefaultPermissionPolicy = new DefaultPermissionGrantPolicy(this); 55 mInstantAppRegistry = new InstantAppRegistry(this); 56 //在Data分区创建一些目录 57 File dataDir = Environment.getDataDirectory();//5 58 mAppInstallDir = new File(dataDir, "app"); 59 mAppLib32InstallDir = new File(dataDir, "app-lib"); 60 mAsecInternalPath = new File(dataDir, "app-asec").getPath(); 61 mDrmAppPrivateInstallDir = new File(dataDir, "app-private"); 62 //创建多用户管理服务 63 sUserManager = new UserManagerService(context, this, 64 new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages); 65 ... 66 mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false))//6 67 ... 68}
在开始阶段中创建了很多PMS中的关键对象并赋值给PMS中的成员变量,下面简单介绍这些成员变量。
- mSettings :用于保存所有包的动态设置。注释1处将系统进程的sharedUserId添加到Settings中,sharedUserId用于进程间共享数据,比如两个App的之间的数据是不共享的,如果它们有了共同的sharedUserId,就可以运行在同一个进程中共享数据。
- mInstaller :Installer继承自SystemService,和PMS、AMS一样是系统的服务(虽然名称不像是服务),PMS很多的操作都是由Installer来完成的,比如APK的安装和卸载。在Installer内部,通过IInstalld和installd进行Binder通信,由位于nativie层的installd来完成具体的操作。
- systemConfig:用于得到全局系统配置信息。比如系统的权限就可以通过SystemConfig来获取。
- mPackageDexOptimizer : Dex优化的工具类。
- mHandler(PackageHandler类型) :PackageHandler继承自Handler,在注释3处它绑定了后台线程ServiceThread的消息队列。PMS通过PackageHandler驱动APK的复制和安装工作,具体的请看在Android包管理机制(三)PMS处理APK的安装这篇文章。 PackageHandler处理的消息队列如果过于繁忙,有可能导致系统卡住, 因此在注释4处将它添加到Watchdog的监测集中。 Watchdog主要有两个用途,一个是定时检测系统关键服务(AMS和WMS等)是否可能发生死锁,还有一个是定时检测线程的消息队列是否长时间处于工作状态(可能阻塞等待了很长时间)。如果出现上述问题,Watchdog会将日志保存起来,必要时还会杀掉自己所在的进程,也就是SystemServer进程。
- sUserManager(UserManagerService类型) :多用户管理服务。
除了创建这些关键对象,在开始阶段还有一些关键代码需要去讲解:
- 注释1处和注释2处加了两个锁,其中mInstallLock是安装APK时需要的锁,保护所有对installd的访问;mPackages是更新APK时需要的锁,保护内存中已经解析的包信息等内容。
- 注释5处后的代码创建了一些Data分区中的子目录,比如/data/app。
- 注释6处会解析packages.xml等文件的信息,保存到Settings的对应字段中。packages.xml中记录系统中所有安装的应用信息,包括基本信息、签名和权限。如果packages.xml有安装的应用信息,那么注释6处Settings的readLPw方法会返回true,mFirstBoot的值为false,说明PMS不是首次被启动。
2.2 扫描系统阶段
1... 2public PackageManagerService(Context context, Installer installer, 3 boolean factoryTest, boolean onlyCore) { 4... 5 //打印扫描系统阶段日志 6 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START, 7 startTime); 8 ... 9 //在/system中创建framework目录 10 File frameworkDir = new File(Environment.getRootDirectory(), "framework"); 11 ... 12 //扫描/vendor/overlay目录下的文件 13 scanDirTracedLI(new File(VENDOR_OVERLAY_DIR), mDefParseFlags 14 | PackageParser.PARSE_IS_SYSTEM 15 | PackageParser.PARSE_IS_SYSTEM_DIR 16 | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0); 17 mParallelPackageParserCallback.findStaticOverlayPackages(); 18 //扫描/system/framework 目录下的文件 19 scanDirTracedLI(frameworkDir, mDefParseFlags 20 | PackageParser.PARSE_IS_SYSTEM 21 | PackageParser.PARSE_IS_SYSTEM_DIR 22 | PackageParser.PARSE_IS_PRIVILEGED, 23 scanFlags | SCAN_NO_DEX, 0); 24 final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app"); 25 //扫描 /system/priv-app 目录下的文件 26 scanDirTracedLI(privilegedAppDir, mDefParseFlags 27 | PackageParser.PARSE_IS_SYSTEM 28 | PackageParser.PARSE_IS_SYSTEM_DIR 29 | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0); 30 final File systemAppDir = new File(Environment.getRootDirectory(), "app"); 31 //扫描/system/app 目录下的文件 32 scanDirTracedLI(systemAppDir, mDefParseFlags 33 | PackageParser.PARSE_IS_SYSTEM 34 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 35 File vendorAppDir = new File("/vendor/app"); 36 try { 37 vendorAppDir = vendorAppDir.getCanonicalFile(); 38 } catch (IOException e) { 39 // failed to look up canonical path, continue with original one 40 } 41 //扫描 /vendor/app 目录下的文件 42 scanDirTracedLI(vendorAppDir, mDefParseFlags 43 | PackageParser.PARSE_IS_SYSTEM 44 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 45 46 //扫描/oem/app 目录下的文件 47 final File oemAppDir = new File(Environment.getOemDirectory(), "app"); 48 scanDirTracedLI(oemAppDir, mDefParseFlags 49 | PackageParser.PARSE_IS_SYSTEM 50 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 51 52 //这个列表代表有可能有升级包的系统App 53 final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();//1 54 if (!mOnlyCore) { 55 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 56 while (psit.hasNext()) { 57 PackageSetting ps = psit.next(); 58 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) { 59 continue; 60 } 61 //这里的mPackages的是PMS的成员变量,代表scanDirTracedLI方法扫描上面那些目录得到的 62 final PackageParser.Package scannedPkg = mPackages.get(ps.name); 63 if (scannedPkg != null) { 64 if (mSettings.isDisabledSystemPackageLPr(ps.name)) {//2 65 ... 66 //将这个系统App的PackageSetting从PMS的mPackages中移除 67 removePackageLI(scannedPkg, true); 68 //将升级包的路径添加到mExpectingBetter列表中 69 mExpectingBetter.put(ps.name, ps.codePath); 70 } 71 continue; 72 } 73 74 if (!mSettings.isDisabledSystemPackageLPr(ps.name)) { 75 ... 76 } else { 77 final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name); 78 //这个系统App升级包信息在mDisabledSysPackages中,但是没有发现这个升级包存在 79 if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {//5 80 possiblyDeletedUpdatedSystemApps.add(ps.name);// 81 } 82 } 83 } 84 } 85 ... 86}
/system可以称作为System分区,里面主要存储谷歌和其他厂商提供的Android系统相关文件和框架。Android系统架构分为应用层、应用框架层、系统运行库层(Native 层)、硬件抽象层(HAL层)和Linux内核层,除了Linux内核层在Boot分区,其他层的代码都在System分区。下面列出 System分区的部分子目录。
| 目录| 含义| | :--------: | :--------:| :--: | | app| 存放系统App,包括了谷歌内置的App也有厂商或者运营商提供的App | | framework| 存放应用框架层的jar包 | | priv-app| 存放特权App | | lib| 存放so文件 | | fonts| 存放系统字体文件 | | media| 存放系统的各种声音,比如铃声、提示音,以及系统启动播放的动画 |
上面的代码还涉及到/vendor 目录,它用来存储厂商对Android系统的定制部分。
系统扫描阶段的主要工作有以下3点:
- 创建/system的子目录,比如/system/framework、/system/priv-app和/system/app等等
- 扫描系统文件,比如/vendor/overlay、/system/framework、/system/app等等目录下的文件。
- 对扫描到的系统文件做后续处理。
主要来说第3点,一次OTA升级对于一个系统App会有三种情况:
- 这个系统APP无更新。
- 这个系统APP有更新。
- 新的OTA版本中,这个系统APP已经被删除。
当系统App升级,PMS会将该系统App的升级包设置数据(PackageSetting)存储到Settings的mDisabledSysPackages列表中(具体见PMS的replaceSystemPackageLIF方法),mDisabledSysPackages的类型为ArrayMap<String, PackageSetting>。mDisabledSysPackages中的信息会被PMS保存到packages.xml中的<updated-package>标签下(具体见Settings的writeDisabledSysPackageLPr方法)。
注释2处说明这个系统App有升级包,那么就将该系统App的PackageSetting从mDisabledSysPackages列表中移除,并将系统App的升级包的路径添加到mExpectingBetter列表中,mExpectingBetter的类型为ArrayMap<String, File>等待后续处理。
注释5处如果这个系统App的升级包信息存储在mDisabledSysPackages列表中,但是没有发现这个升级包存在,则将它加入到possiblyDeletedUpdatedSystemApps列表中,意为“系统App的升级包可能被删除”,之所以是“可能”,是因为系统还没有扫描Data分区,只能暂放到possiblyDeletedUpdatedSystemApps列表中,等到扫描完Data分区后再做处理。
2.3 扫描Data分区阶段
1public PackageManagerService(Context context, Installer installer, 2 boolean factoryTest, boolean onlyCore) { 3 ... 4 mSettings.pruneSharedUsersLPw(); 5 //如果没有加密设备,那么就开始扫描Data分区。 6 if (!mOnlyCore) { 7 //打印扫描Data分区阶段日志 8 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START, 9 SystemClock.uptimeMillis()); 10 //扫描/data/app目录下的文件 11 scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0); 12 //扫描/data/app-private目录下的文件 13 scanDirTracedLI(mDrmAppPrivateInstallDir, mDefParseFlags 14 | PackageParser.PARSE_FORWARD_LOCK, 15 scanFlags | SCAN_REQUIRE_KNOWN, 0); 16 //扫描完Data分区后,处理possiblyDeletedUpdatedSystemApps列表 17 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) { 18 PackageParser.Package deletedPkg = mPackages.get(deletedAppName); 19 // 从mSettings.mDisabledSysPackages变量中移除去此应用 20 mSettings.removeDisabledSystemPackageLPw(deletedAppName); 21 String msg; 22 //1:如果这个系统App的包信息不在PMS的变量mPackages中,说明是残留的App信息,后续会删除它的数据。 23 if (deletedPkg == null) { 24 msg = "Updated system package " + deletedAppName 25 + " no longer exists; it's data will be wiped"; 26 // Actual deletion of code and data will be handled by later 27 // reconciliation step 28 } else { 29 //2:如果这个系统App在mPackages中,说明是存在于Data分区,不属于系统App,那么移除其系统权限。 30 msg = "Updated system app + " + deletedAppName 31 + " no longer present; removing system privileges for " 32 + deletedAppName; 33 deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM; 34 PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName); 35 deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM; 36 } 37 logCriticalInfo(Log.WARN, msg); 38 } 39 //遍历mExpectingBetter列表 40 for (int i = 0; i < mExpectingBetter.size(); i++) { 41 final String packageName = mExpectingBetter.keyAt(i); 42 if (!mPackages.containsKey(packageName)) { 43 //得到系统App的升级包路径 44 final File scanFile = mExpectingBetter.valueAt(i); 45 logCriticalInfo(Log.WARN, "Expected better " + packageName 46 + " but never showed up; reverting to system"); 47 int reparseFlags = mDefParseFlags; 48 //3:根据系统App所在的目录设置扫描的解析参数 49 if (FileUtils.contains(privilegedAppDir, scanFile)) { 50 reparseFlags = PackageParser.PARSE_IS_SYSTEM 51 | PackageParser.PARSE_IS_SYSTEM_DIR 52 | PackageParser.PARSE_IS_PRIVILEGED; 53 } 54 ... 55 //将packageName对应的包设置数据(PackageSetting)添加到mSettings的mPackages中 56 mSettings.enableSystemPackageLPw(packageName);//4 57 try { 58 //扫描系统App的升级包 59 scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null);//5 60 } catch (PackageManagerException e) { 61 Slog.e(TAG, "Failed to parse original system package: " 62 + e.getMessage()); 63 } 64 } 65 } 66 } 67 //清除mExpectingBetter列表 68 mExpectingBetter.clear(); 69... 70}
/data可以称为Data分区,它用来存储所有用户的个人数据和配置文件。下面列出Data分区部分子目录:
| 目录| 含义| | :--------: | :--------:| :--: | | app| 存储用户自己安装的App| | data| 存储所有已安装的App数据的目录,每个App都有自己单独的子目录 | | app-private| App的私有存储空间 | | app-lib|存储所有App的Jni库 | | system| 存放系统配置文件 | | anr| 用于存储ANR发生时系统生成的traces.txt文件 |
扫描Data分区阶段主要做了以下几件事:
- 扫描/data/app和/data/app-private目录下的文件。
- 遍历possiblyDeletedUpdatedSystemApps列表,注释1处如果这个系统App的包信息不在PMS的变量mPackages中,说明是残留的App信息,后续会删除它的数据。注释2处如果这个系统App的包信息在mPackages中,说明是存在于Data分区,不属于系统App,那么移除其系统权限。
- 遍历mExpectingBetter列表,注释3处根据系统App所在的目录设置扫描的解析参数,注释4处的方法内部会将packageName对应的包设置数据(PackageSetting)添加到mSettings的mPackages中。注释5处扫描系统App的升级包,最后清除mExpectingBetter列表。
2.4 扫描结束阶段
1 //打印扫描结束阶段日志 2 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END, 3 SystemClock.uptimeMillis()); 4 Slog.i(TAG, "Time to scan packages: " 5 + ((SystemClock.uptimeMillis()-startTime)/1000f) 6 + " seconds"); 7 int updateFlags = UPDATE_PERMISSIONS_ALL; 8 // 如果当前平台SDK版本和上次启动时的SDK版本不同,重新更新APK的授权 9 if (ver.sdkVersion != mSdkVersion) { 10 Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to " 11 + mSdkVersion + "; regranting permissions for internal storage"); 12 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 13 } 14 updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags); 15 ver.sdkVersion = mSdkVersion; 16 //如果是第一次启动或者是Android M升级后的第一次启动,需要初始化所有用户定义的默认首选App 17 if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) { 18 for (UserInfo user : sUserManager.getUsers(true)) { 19 mSettings.applyDefaultPreferredAppsLPw(this, user.id); 20 applyFactoryDefaultBrowserLPw(user.id); 21 primeDomainVerificationsLPw(user.id); 22 } 23 } 24 ... 25 //OTA后的第一次启动,会清除代码缓存目录。 26 if (mIsUpgrade && !onlyCore) { 27 Slog.i(TAG, "Build fingerprint changed; clearing code caches"); 28 for (int i = 0; i < mSettings.mPackages.size(); i++) { 29 final PackageSetting ps = mSettings.mPackages.valueAt(i); 30 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) { 31 clearAppDataLIF(ps.pkg, UserHandle.USER_ALL, 32 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE 33 | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 34 } 35 } 36 ver.fingerprint = Build.FINGERPRINT; 37 } 38 ... 39 // 把Settings的内容保存到packages.xml中 40 mSettings.writeLPr(); 41 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
扫描结束结束阶段主要做了以下几件事:
- 如果当前平台SDK版本和上次启动时的SDK版本不同,重新更新APK的授权。
- 如果是第一次启动或者是Android M升级后的第一次启动,需要初始化所有用户定义的默认首选App。
- OTA升级后的第一次启动,会清除代码缓存目录。
- 把Settings的内容保存到packages.xml中,这样此后PMS再次创建时会读到此前保存的Settings的内容。
2.5 准备阶段
1 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY, 2 SystemClock.uptimeMillis()); 3 ... 4 mInstallerService = new PackageInstallerService(context, this);//1 5 ... 6 Runtime.getRuntime().gc();//2 7 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 8 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "loadFallbacks"); 9 FallbackCategoryProvider.loadFallbacks(); 10 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 11 mInstaller.setWarnIfHeld(mPackages); 12 LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());//3 13 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 14}
注释1处创建PackageInstallerService,PackageInstallerService是用于管理安装会话的服务,它会为每次安装过程分配一个SessionId,在Android包管理机制(二)PackageInstaller安装APK这篇文章中提到过PackageInstallerService。 注释2处进行一次垃圾收集。注释3处将PackageManagerInternalImpl(PackageManager的本地服务)添加到LocalServices中, LocalServices用于存储运行在当前的进程中的本地服务。
3. 总结
本篇文章介绍了PMS的创建过程,分为两个部分,分别是SyetemServer处理部分和PMS构造方法,PMS构造方法又分为5个部分,分别是开始阶段、扫描系统阶段、扫描Data分区阶段、扫描结束阶段和准备阶段。
感谢 Android包管理机制 源码分析 — PackageManagerService(一)之启动流程 Android-6.0之PMS解析下篇 APK安装流程详解6——PackageManagerService启动前奏
