简介
PackageManager是Android系统的一个服务管理类,主要职责是管理应用程序包,通过它可以获取应用程序信息,系统提供的PackageInfo实体类
常用字段
public String packageName | 包名 |
public ActivityInfo[] activities | 所有<activity> 节点信息 |
public ApplicationInfo applicationInfo | <application> 节点信息,只有一个 |
public ActivityInfo[] receivers | 所有<receiver> 节点信息,多个 |
public ServiceInfo[] services | 所有<service> 节点信息 ,多个 |
手机上已经安装的应用程序信息,才可以通过getPackageManager()方法获取PackageManagerService简称PKMS,是Android系统中的核心服务之一,管理着Package相关的所有工作,例如应用安装、卸载、解析apk文件、验证apk文件的签名、检查AndroidManifest.xml文件中的权限设置、检查应用程序的存储位置、安装应用程序所需的库和框架等。
PackageManagerService的启动流程
SystemServer启动PackageMangerService
Android系统中大多数服务都是从SystemServer中启动,因此PMS也是从其中启动的
system_server.java位置:
platform/frameworks/base/services/java/com/android/server/SystemServer.java
private void run() {
// Start services.
try {
traceBeginAndSlog("StartServices");
// 2.1.1 启动BootstrapService
startBootstrapServices();
// 2.1.2 启动OtherService
startOtherServices();
SystemServerInitThreadPool.shutdown();
}
}
在System_Server中启动pms需要执行两个函数:
startBootstrapServices();
主要做了以下工作:
1.启动installer服务
2.判断当前是否处于加密状态,若处于加密状态只解析核心应用。
3.使用PackageManagerService.main()创建一个pms对象。
4.创建一个pm
5. 管理A/B OTA dexopting
startOtherServices();
主要执行以下操作:
在设备未加密的状态下,做dex优化
磁盘维护
确保pms准备完成(完成默认授权、更新package信息、通知一些pms组件告知systemReady)
dex优化
在设备未加密的状态下,可能需要做一次dex优化。具体的优化策略见代码详情。
@Override
public void updatePackagesIfNeeded() {
enforceSystemOrRoot("Only the system can request package update");
// We need to re-extract after an OTA.
// 1.是否进行了OTA升级,OTA升级后需要重新提取
boolean causeUpgrade = isUpgrade();
// First boot or factory reset.
// Note: we also handle devices that are upgrading to N right now as if it is their
// first boot, as they do not have profile data.
// 2.是否是第一次启动或者升级至N
boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade;
// We need to re-extract after a pruned cache, as AoT-ed files will be out of date.
// 3.判断是否进行过虚拟机缓存清理,如果清理过了,AOT编译后的文件就过时了,需要重新编译
boolean causePrunedCache = VMRuntime.didPruneDalvikCache();
// 如果123都不满足,那么就不需要进行优化。不执行任何操作,退出。
if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) {
return;
}
// 否则,进行优化
List<PackageParser.Package> pkgs;
synchronized (mPackages) {
// 按照package的优先级进行排序,并返回一个list.优先级为:core apps > system apps > other apps
// 代码详见 2.1.2.1.1
pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this);
}
// 开始时间,用于计时
final long startTime = System.nanoTime();
// 执行编译优化
// 代码详见:2.1.2.1.2
final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */,
causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT,
false /* bootComplete */);
// 编译优化消耗的时间
final int elapsedTimeSeconds =
(int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime);
MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]);
MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]);
MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]);
MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size());
MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds);
}
在dex优化前需要进行判断下面三个条件,如果条件都不匹配,则不需要进行dex优化
1. 是否进行OTA升级,OTA升级后需要重新提取。
2.是否是第一次启动或者升级至N。
3.判断是否进行过虚拟机缓存清理
核心方法:
PackageManagerServiceUtils.getPackagesForDexopt():根据优先级返回待优化的list,performDexOptUpgrade(); 将list中的package依次优化
磁盘维护
@Override
public void performFstrimIfNeeded() {
// 只有system或者root用户才可以请求fstrim
enforceSystemOrRoot("Only the system can request fstrim");
// Before everything else, see whether we need to fstrim.
// 在所有事情开始之前,查看是否需要执行fstrim
try {
// 获取StorageManager对象
IStorageManager sm = PackageHelper.getStorageManager();
if (sm != null) {
boolean doTrim = false;
// 获取执行fstrim执行间隔
// private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
final long interval = android.provider.Settings.Global.getLong(
mContext.getContentResolver(),
android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
DEFAULT_MANDATORY_FSTRIM_INTERVAL);
if (interval > 0) {
final long timeSinceLast = System.currentTimeMillis() - sm.lastMaintenance();
if (timeSinceLast > interval) {
// 超过三天自动清理
doTrim = true;
Slog.w(TAG, "No disk maintenance in " + timeSinceLast
+ "; running immediately");
}
}
// 清理
if (doTrim) {
final boolean dexOptDialogShown;
synchronized (mPackages) {
dexOptDialogShown = mDexOptDialogShown;
}
// 不是首次启动并且显示dex优化弹窗
if (!isFirstBoot() && dexOptDialogShown) {
try {
ActivityManager.getService().showBootMessage(
mContext.getResources().getString(
R.string.android_upgrading_fstrim), true);
} catch (RemoteException e) {
}
}
// StorageManagerService发送消息给handler,然后执行fstrim()向Vold发消息
sm.runMaintenance();
}
} else {
Slog.e(TAG, "storageManager service unavailable!");
}
} catch (RemoteException e) {
// Can't happen; StorageManagerService is local
}
}
主要是执行磁盘清理工作,释放磁盘空间。在指定的时间内,依次发送消息,最终执行fstrim()向Vold发送消息。