Android服务之PackageManagerService启动源码分析
了解了Android系统的启动过程的读者应该知道,Android的所有Java服务都是通过SystemServer进程启动的,并且驻留在SystemServer进程中。SystemServer进程在启动时,通过创建一个ServerThread线程来启动所有服务,本文主要介绍Android服务中PackageManagerService服务启动过程。首先介绍一些PackageManagerService服务下的相关类关系图:

在SystemServer进程的ServerThread线程中,执行以下代码启动PackageManagerService服务:
PackageSignatures来用来描述Android应用程序安装包的签名信息,GrantedPermissions类用于描述应用APK的权限信息。Settings类的成员变量mSharedUsers是一个HashMap,用键值对的形式保存所有的SharedUserSetting对象,SharedUserSetting对象用于记录共享同一进程的所有APK信息,该类的成员变量packages的类型为PackageSetting,用来保存所有共享同一UID的包信息,而成员变量userId则是记录多个APK共享的UID。首先介绍Settings对象的构造过程:UID小于1000的SharedUserSetting保存到数组mOtherUserIds中。回到PackageManagerService的构造函数中,通过Settings的addSharedUserLPw函数向mSharedUsers,mUserIds,mOtherUserIds数组添加了4个特定进程的SharedUserSetting对象。
最后就是创建一些安装目录:
/system/preloadapp
/data/data
/data/app-asec
/data/user
/data/data
/data/app-private
创建用户管理对象UserManager:
这些文件在编译的时候直接从frameworks指定目录下拷贝过来的,在特定product编译目录下的base.mk文件中的配置如下:
函数readPermissionsFromXml使用PULL方式解析这些XML文件,下面分别介绍各个标签的解析过程。
feature标签用来描述设备应该支持的硬件特性。解析过程如下:
library用于指定系统库,当应用程序运行时,系统会为进程加载一些必要库。该标签的解析过程如下:
group标签用于建立Android层与Linux层之间的权限映射关系。
读取安装包信息/data/system/packages.xml文件用于记录系统中所安装的Package信息;/data/system/packages-backup.xml文件是/data/packages.xml文件的备份。在PackageManagerService扫描完目标文件夹后会创建该文件,当系统进行程序安装卸载时会更新该文件。
/data/system/packages-stopped.xml文件用于记录系统中强制停止运行的Package信息。/data/system/packages-stopped-backup.xml是/data/packages-stopped.xml文件的备份。在强制停止某个应用时,会将应用相关信息记录到该文件中。
/data/system/packages.list保存系统中存在的所有非系统自带的APK信息,即UID大于1000的apk。当系统第一次开机时,这些文件并不存在,而在以后的开机中,扫描到的这些XML文件是上一次运行过程中创建的。
mFlagInstall = true;EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,SystemClock.uptimeMillis());final boolean regrantPermissions = mSettings.mInternalSdkPlatform != mSdkVersion;mSettings.mInternalSdkPlatform = mSdkVersion;updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL | (regrantPermissions? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL): 0));ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();for (PreferredActivity pa : mSettings.mPreferredActivities.filterSet()) {if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {removed.add(pa);}}for (int i=0; i<removed.size(); i++) {PreferredActivity pa = removed.get(i);Slog.w(TAG, "Removing dangling preferred activity: "+ pa.mPref.mComponent);mSettings.mPreferredActivities.removeFilter(pa);}// can downgrade to readermSettings.writeLPr();EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,SystemClock.uptimeMillis());Runtime.getRuntime().gc();mRequiredVerifierPackage = getRequiredVerifierLPr();
至此,PackageManagerService就构造完成了,构造过程认为繁重,Apk文件扫描解析耗费比较长的时间,这是导致开机速度慢的原因。


