Android 6.0 PM机制系列(四) APK安装需要空间分析

本文深入分析了Android 6.0中APK安装时所需存储空间的计算方式,通过源码解读发现,与Android 9.0不同,6.0在仅有30M空间时仍能安装10M应用。关键在于6.0使用`getStorageBytesUntilLow()`方法,该方法计算的是可用空间减去1M。因此,6.0安装所需空间大致为应用大小的2倍。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

Android 9.0 PM机制系列(四) APK安装需要空间分析文章中,我们重点分析了Android9.0需要的最小APK安装存储空间大小。结论就是:只要系统空间小于Math.min(getTotalSpace的5%,500M)+ PackageHelper.calculateInstalledSize(pkg, abiOverride),系统就会报空间不足。
正当以为所有的系统都大抵如此,但是没想到在Android6.0上面,当空间存储只有30M的时候,依旧可以安装10M的应用。这到底是怎么回事,唯有读源码能一解我的困惑!

1.开始安装

分析源码,一直跟到PMS里面,发现和Android9.0一样,安装核心代码开始处就在handleStartCopy方法,代码如下:
/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java

public void handleStartCopy() throws RemoteException {
   
   int ret = PackageManager.INSTALL_SUCCEEDED;
    // If we're already staged, we've firmly committed to an install location
    if (origin.staged) {
   //1
        if (origin.file != null) {
   //2
            installFlags |= PackageManager.INSTALL_INTERNAL;//3
            installFlags &= ~PackageManager.INSTALL_EXTERNAL;
        }
        ...
    }

    final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
    final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;

    PackageInfoLite pkgLite = null;

    if (onInt && onSd) {
   
        // Check if both bits are set.
        Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
        ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
    } else {
   
        pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
                packageAbiOverride);//4

        /*
         * If we have too little free space, try to free cache
         * before giving up.
         */
        if (!origin.staged && pkgLite.recommendedInstallLocation
                == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
   
            // TODO: focus freeing disk space on the target device
            final StorageManager storage = StorageManager.from(mContext);
            final long lowThreshold = storage.getStorageLowBytes(
                    Environment.getDataDirectory());

            final long sizeBytes = mContainerService.calculateInstalledSize(
                    origin.resolvedPath, isForwardLocked(), packageAbiOverride);

            if (mInstaller.freeCache(null, sizeBytes + lowThreshold) >= 0) {
   
                pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
                        installFlags, packageAbiOverride);
            }

            /*
             * The cache free must have deleted the file we
             * downloaded to install.
             *
             * TODO: fix the "freeCache" call to not delete
             *       the file we care about.
             */
            if (pkgLite.recommendedInstallLocation
                    == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
   //5
                pkgLite.recommendedInstallLocation
                    = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值