adb安装应用后重启设备应用消失

场景:应用本身安装在system/app路径下,然后我们通过adb install -r安装应用后重启手机,发现应用还是用的以前的不是我们更新的

分析:
首先adb install -r安装的应用是在data/app/下,由于apksystem/app中已经存在,所以系统会在data/app/的应用包名后添加-1作为标记抓取开机log有如下log打印:

01-01 19:19:38.103   787   787 D PackageManager: scan package: /system/app/P92Service , start at: 10513ms.
01-01 19:19:38.103   787   787 D PackageManager: Parsing: /system/app/P92Service
01-01 19:19:38.111   787   787 D PackageManager: updatedPkg = PackageSetting{387114ae com.allinpay.usdk.service/1000}
01-01 19:19:38.111   787   787 D PackageManager: Path changing from /data/app/com.allinpay.usdk.service-1
01-01 19:19:38.112   787   787 W PackageManager: Package com.allinpay.usdk.service at /system/app/P92Service reverting from /data/app/com.allinpay.usdk.service-1: new version 1 better than installed 1
01-01 19:19:38.153   787   787 W PackageManager: Trying to update system app code path from /data/app/com.allinpay.usdk.service-1 to /system/app/P92Service
01-01 19:19:38.160   787   787 I PackageManager: Perform pre-dex opt for package: com.allinpay.usdk.service
01-01 19:19:38.162   787   787 W PackageManager: Code path for pkg : com.allinpay.usdk.service changing from /data/app/com.allinpay.usdk.service-1 to /system/app/P92Service
01-01 19:19:38.162   787   787 W PackageManager: Resource path for pkg : com.allinpay.usdk.service changing from /data/app/com.allinpay.usdk.service-1 to /system/app/P92Service
01-01 19:19:38.164   787   787 D PackageManager: scan package: /system/app/P92Service , end at: 10574ms. elapsed time = 61ms.

对我们有用的信息是:

01-01 19:19:38.112   787   787 W PackageManager: Package com.allinpay.usdk.service at /system/app/P92Service reverting from /data/app/com.allinpay.usdk.service-1: new version 1 better than installed 1

而这段log对应在系统中的代码如下:


private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
        long currentTime, UserHandle user) throws PackageManagerException {
    if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
    parseFlags |= mDefParseFlags;
    PackageParser pp = new PackageParser();
    pp.setSeparateProcesses(mSeparateProcesses);
    pp.setOnlyCoreApps(mOnlyCore);
    pp.setDisplayMetrics(mMetrics);

    if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) {
        parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY;
    }

    final PackageParser.Package pkg;
    try {
        pkg = pp.parsePackage(scanFile, parseFlags);
    } catch (PackageParserException e) {
        throw PackageManagerException.from(e);
    }

    PackageSetting ps = null;
    PackageSetting updatedPkg;
    // reader
    synchronized (mPackages) {
        // Look to see if we already know about this package.
        String oldName = mSettings.mRenamedPackages.get(pkg.packageName);
        if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
            // This package has been renamed to its original name.  Let's
            // use that.
            ps = mSettings.peekPackageLPr(oldName);
        }
        // If there was no original package, see one for the real package name.
        if (ps == null) {
            ps = mSettings.peekPackageLPr(pkg.packageName);
        }
        // Check to see if this package could be hiding/updating a system
        // package.  Must look for it either under the original or real
        // package name depending on our state.
        updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
		 		if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
    }
    boolean updatedPkgBetter = false;
    // First check if this is a system package that may involve an update

    /** M: [Operator] Package in vendor folder should also be checked @{ */
    if (updatedPkg != null &&
            (((parseFlags & PackageParser.PARSE_IS_SYSTEM) != 0) ||
                    ((parseFlags & PackageParser.PARSE_IS_OPERATOR) != 0))) {
    /** @} */
        // If new package is not located in "/system/priv-app" (e.g. due to an OTA),
        // it needs to drop FLAG_PRIVILEGED.
        if (locationIsPrivileged(scanFile)) {
            updatedPkg.pkgFlags |= ApplicationInfo.FLAG_PRIVILEGED;
        } else {
            updatedPkg.pkgFlags &= ~ApplicationInfo.FLAG_PRIVILEGED;
        }

        if (ps != null && !ps.codePath.equals(scanFile)) {
            // The path has changed from what was last scanned...  check the
            // version of the new path against what we have stored to determine
            // what to do.
            if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath); 			android.util.Log.i("weiyw","pkg.mVersionCode:"+pkg.mVersionCode+",pkg.codePath:"+
				pkg.codePath); 			android.util.Log.i("weiyw","ps.versionCode:"+ps.versionCode+",ps.codePathString:"+
				ps.codePathString);
            /** M: [Operator] Allow vendor package downgrade. @{ */
            /// Always install the updated one on data partition
            if (pkg.mVersionCode < ps.versionCode || ((parseFlags & PackageParser.PARSE_IS_OPERATOR) != 0)) {
            /** @} */
                // The system package has been updated and the code path does not match
                // Ignore entry. Skip it.
                Slog.i(TAG, "Package " + ps.name + " at " + scanFile
                        + " ignored: updated version " + ps.versionCode
                        + " better than this " + pkg.mVersionCode);
                if (!updatedPkg.codePath.equals(scanFile)) {
                    Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg : "
                            + ps.name + " changing from " + updatedPkg.codePathString
                            + " to " + scanFile);
                    updatedPkg.codePath = scanFile;
                    updatedPkg.codePathString = scanFile.toString();
                }
                updatedPkg.pkg = pkg;
                throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, null);
            } else {
                // The current app on the system partition is better than
                // what we have updated to on the data partition; switch
                // back to the system partition version.
                // At this point, its safely assumed that package installation for
                // apps in system partition will go through. If not there won't be a working
                // version of the app
                // writer
                synchronized (mPackages) {
                    // Just remove the loaded entries from package lists.
                    mPackages.remove(ps.name);
                }

                logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
                        + " reverting from " + ps.codePathString
                        + ": new version " + pkg.mVersionCode
                        + " better than installed " + ps.versionCode);

                InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
                        ps.codePathString, ps.resourcePathString, ps.legacyNativeLibraryPathString,
                        getAppDexInstructionSets(ps));
                synchronized (mInstallLock) {
                    args.cleanUpResourcesLI();
                }
                synchronized (mPackages) {
                    mSettings.enableSystemPackageLPw(ps.name);
                }
                updatedPkgBetter = true;
            }

在这里我们可以看到打印出的log信息,看后面的代码是会去删除data分区的apk,以system分区的为准,如果我们想让data分区的为主,那我们就不能进else,需要进入if里面,看下判断条件

if (pkg.mVersionCode < ps.versionCode || ((parseFlags & PackageParser.PARSE_IS_OPERATOR) != 0))

PackageParser.PARSE_IS_OPERATOR是判断是不是operator apps的,我们明显不是,那就看versioncode

Package com.allinpay.usdk.service at /system/app/P92Service reverting from /data/app/com.allinpay.usdk.service-1: new version 1 better than installed 1

logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
                            + " reverting from " + ps.codePathString
                            + ": new version " + pkg.mVersionCode
                            + " better than installed " + ps.versionCode);

通过log我们可知scanFile是/system/app/目录下,通过之前的代码:pkg = pp.parsePackage(scanFile, parseFlags)可以pkg代表的是系统分区下的app通过代码

if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
                // This package has been renamed to its original name.  Let's
                // use that.
                ps = mSettings.peekPackageLPr(oldName);
            }
            // If there was no original package, see one for the real package name.
            if (ps == null) {
                ps = mSettings.peekPackageLPr(pkg.packageName);
       }

可知ps是根据pkg提供的包名在其他分区去搜索,所以ps代表的是其他分区的,也就是这里的data分区
只要我们满足pkg.mVersionCode < ps.versionCode这个条件,那我们就会进入if里面,在if里面会去隐藏system分区里的应用,将data的应用优先级提高,满足这个条件很简单,只要相应的应用在AndroidManifest.xml里面将versioncode升级一下就可以了,比如system/app里面的versioncode是1,那新的应用只需将versioncode修改成2即可,这样adb install -r安装后重启用的还是data分区的应用

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值