工具使用指南Android

Android之静默安装接口对比分析

2022-01-15  本文已影响0人  锄禾豆

简介

分析静默安装新老接口的对比。
源码:
7.1

分析

老接口A:
PackageManager.installPackage(
            Uri packageURI,
            PackageInstallObserver observer,
            @InstallFlags int flags,
            String installerPackageName);
            
新接口B:
PackageInstaller packageInstaller = PackageManager.getPackageInstaller();
SessionParams sessionParams = new SessionParams(SessionParams.MODE_FULL_INSTALL);
int sessionId = packageInstaller.createSession(sessionParams);//创建会话id
PackageInstaller.Session session = packageInstaller.openSession(sessionId);//创建会话

final InputStream in = new FileInputStream(file);
final long sizeBytes = file.length();
final OutputStream out = session.openWrite("PackageInstaller", 0, sizeBytes);//打开会话写操作
try {
    int c;
    while ((c = in.read(buffer)) != -1) {
        out.write(buffer, 0, c);//往会话中写数据
        if (sizeBytes > 0) {
            final float fraction = ((float) c / (float) sizeBytes);
            session.addProgress(fraction);
        }
    }
    session.fsync(out);//会话数据同步
} finally {
    IoUtils.closeQuietly(in);
    IoUtils.closeQuietly(out);
}

Intent broadcastIntent = new Intent(BROADCAST_ACTION);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
                    InstallAppProgress.this /*context*/,
                    sessionId,
                    broadcastIntent,
                    PendingIntent.FLAG_UPDATE_CURRENT);
session.commit(pendingIntent.getIntentSender());//提交数据

对比:
A 实现简单  结果监听直接采用observer    数据通过系统直接写到data/app/包名/base.apk
B 实现复杂  结果监听通过PendingIntent   数据先保存在/data/app/vmt{sessiondi}.tmp,再写到/data/app/包名/base.apk

注:
B 涉及了委托模式和会话模式的运用
A 写入base.apk采用了DefaultContainerService.apk拷贝业务

SessionParams需要一个模式参数:
MODE_FULL_INSTALL:新的apk会替换旧的apk的模式。
MODE_INHERIT_EXISTING:新的apk继承旧的apk.

原理

老接口A:
PackageManager.installPackage --> PackageManagerService.installPackageAsUser

新接口B:
PackageManager --> PackageInstaller (PackageInstaller.Session.commmit) --> PackageInstallSession --> PackageManagerService.installStage

对比AMS实现:原理一样,只是传进来的参数B比A更加丰富
A: mHandler INIT_COPY
        final Message msg = mHandler.obtainMessage(INIT_COPY);
        final VerificationInfo verificationInfo = new VerificationInfo(
                null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid);
        final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer,
                installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user,
                null /*packageAbiOverride*/, null /*grantedPermissions*/,
                null /*certificates*/);
        params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params));
        msg.obj = params;

        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser",
                System.identityHashCode(msg.obj));
        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
                System.identityHashCode(msg.obj));

        mHandler.sendMessage(msg);
        
B: mHandler INIT_COPY
        final VerificationInfo verificationInfo = new VerificationInfo(
                sessionParams.originatingUri, sessionParams.referrerUri,
                sessionParams.originatingUid, installerUid);

        final OriginInfo origin;
        if (stagedDir != null) {
            origin = OriginInfo.fromStagedFile(stagedDir);
        } else {
            origin = OriginInfo.fromStagedContainer(stagedCid);
        }

        final Message msg = mHandler.obtainMessage(INIT_COPY);
        final InstallParams params = new InstallParams(origin, null, observer,
                sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid,
                verificationInfo, user, sessionParams.abiOverride,
                sessionParams.grantedRuntimePermissions, certificates);
        params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
        msg.obj = params;

        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
                System.identityHashCode(msg.obj));
        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
                System.identityHashCode(msg.obj));

        mHandler.sendMessage(msg);

adb查询

adb shell dumpsys package installs
采用新接口安装的业务,通过此命令可查询apk安装的相关信息
上一篇下一篇

猜你喜欢

热点阅读