PackageManagerService(一)

简介

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发送消息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值