当前位置: 首页 > news >正文

Android 安装应用-提交阶段之后剩下的操作

  它的实现代码在executePostCommitSteps(commitRequest)中,看一下它的代码:

    /*** On successful install, executes remaining steps after commit completes and the package lock* is released. These are typically more expensive or require calls to installd, which often* locks on {@link #mLock}.*/private void executePostCommitSteps(CommitRequest commitRequest) {final ArraySet<IncrementalStorage> incrementalStorages = new ArraySet<>();for (ReconciledPackage reconciledPkg : commitRequest.reconciledPackages.values()) {final boolean instantApp = ((reconciledPkg.scanResult.request.scanFlags& PackageManagerService.SCAN_AS_INSTANT_APP) != 0);final AndroidPackage pkg = reconciledPkg.pkgSetting.pkg;final String packageName = pkg.getPackageName();final String codePath = pkg.getPath();final boolean onIncremental = mIncrementalManager != null&& isIncrementalPath(codePath);if (onIncremental) {IncrementalStorage storage = mIncrementalManager.openStorage(codePath);if (storage == null) {throw new IllegalArgumentException("Install: null storage for incremental package " + packageName);}incrementalStorages.add(storage);}prepareAppDataAfterInstallLIF(pkg);if (reconciledPkg.prepareResult.clearCodeCache) {clearAppDataLIF(pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE | FLAG_STORAGE_CE| FLAG_STORAGE_EXTERNAL | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);}if (reconciledPkg.prepareResult.replace) {mDexManager.notifyPackageUpdated(pkg.getPackageName(),pkg.getBaseApkPath(), pkg.getSplitCodePaths());}// Prepare the application profiles for the new code paths.// This needs to be done before invoking dexopt so that any install-time profile// can be used for optimizations.mArtManagerService.prepareAppProfiles(pkg,resolveUserIds(reconciledPkg.installArgs.user.getIdentifier()),/* updateReferenceProfileContent= */ true);// Compute the compilation reason from the installation scenario.final int compilationReason = mDexManager.getCompilationReasonForInstallScenario(reconciledPkg.installArgs.mInstallScenario);// Construct the DexoptOptions early to see if we should skip running dexopt.//// Do not run PackageDexOptimizer through the local performDexOpt// method because `pkg` may not be in `mPackages` yet.//// Also, don't fail application installs if the dexopt step fails.final boolean isBackupOrRestore =reconciledPkg.installArgs.installReason == INSTALL_REASON_DEVICE_RESTORE|| reconciledPkg.installArgs.installReason == INSTALL_REASON_DEVICE_SETUP;final int dexoptFlags = DexoptOptions.DEXOPT_BOOT_COMPLETE| DexoptOptions.DEXOPT_INSTALL_WITH_DEX_METADATA_FILE| (isBackupOrRestore ? DexoptOptions.DEXOPT_FOR_RESTORE : 0);DexoptOptions dexoptOptions =new DexoptOptions(packageName, compilationReason, dexoptFlags);// Check whether we need to dexopt the app.//// NOTE: it is IMPORTANT to call dexopt://   - after doRename which will sync the package data from AndroidPackage and//     its corresponding ApplicationInfo.//   - after installNewPackageLIF or replacePackageLIF which will update result with the//     uid of the application (pkg.applicationInfo.uid).//     This update happens in place!//// We only need to dexopt if the package meets ALL of the following conditions://   1) it is not an instant app or if it is then dexopt is enabled via gservices.//   2) it is not debuggable.//   3) it is not on Incremental File System.//// Note that we do not dexopt instant apps by default. dexopt can take some time to// complete, so we skip this step during installation. Instead, we'll take extra time// the first time the instant app starts. It's preferred to do it this way to provide// continuous progress to the useur instead of mysteriously blocking somewhere in the// middle of running an instant app. The default behaviour can be overridden// via gservices.//// Furthermore, dexopt may be skipped, depending on the install scenario and current// state of the device.//// TODO(b/174695087): instantApp and onIncremental should be removed and their install//       path moved to SCENARIO_FAST.final boolean performDexopt =(!instantApp || Global.getInt(mContext.getContentResolver(),Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0)&& !pkg.isDebuggable()&& (!onIncremental)&& dexoptOptions.isCompilationEnabled();if (performDexopt) {// Compile the layout resources.if (SystemProperties.getBoolean(PRECOMPILE_LAYOUTS, false)) {Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "compileLayouts");mViewCompiler.compileLayouts(pkg);Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);}Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");ScanResult result = reconciledPkg.scanResult;// This mirrors logic from commitReconciledScanResultLocked, where the library files// needed for dexopt are assigned.// TODO: Fix this to have 1 mutable PackageSetting for scan/install. If the previous//  setting needs to be passed to have a comparison, hide it behind an immutable//  interface. There's no good reason to have 3 different ways to access the real//  PackageSetting object, only one of which is actually correct.PackageSetting realPkgSetting = result.existingSettingCopied? result.request.pkgSetting : result.pkgSetting;if (realPkgSetting == null) {realPkgSetting = reconciledPkg.pkgSetting;}// Unfortunately, the updated system app flag is only tracked on this PackageSettingboolean isUpdatedSystemApp = reconciledPkg.pkgSetting.getPkgState().isUpdatedSystemApp();realPkgSetting.getPkgState().setUpdatedSystemApp(isUpdatedSystemApp);mPackageDexOptimizer.performDexOpt(pkg, realPkgSetting,null /* instructionSets */,getOrCreateCompilerPackageStats(pkg),mDexManager.getPackageUseInfoOrDefault(packageName),dexoptOptions);Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);}// Notify BackgroundDexOptService that the package has been changed.// If this is an update of a package which used to fail to compile,// BackgroundDexOptService will remove it from its denylist.// TODO: Layering violationBackgroundDexOptService.notifyPackageChanged(packageName);notifyPackageChangeObserversOnUpdate(reconciledPkg);}waitForNativeBinariesExtraction(incrementalStorages);}

  首先对ReconciledPackage对象循环,得到AndroidPackage对象pkg,包名、文件路径。
  接着调用prepareAppDataAfterInstallLIF(pkg),它主要用来创建应用需要使用的文件或文件夹。应用需要使用的文件或文件夹和参数uuid(存储位置相关)、userId和包名相关。如果uuid为null,userId为0,则文件夹为"/data/data/“(版本遗留) + 包名 或 “/data/user/0/” + 包名,及其目录下面的"cache"和"code_cache"目录;”/data/user_de/0/" + 包名,及其目录下面的"cache"和"code_cache"目录,如果"dalvik.vm.usejitprofiles"属性值为true的情况下(和JIT编译有关),还会创建 “/data/misc/profiles/cur/0” + 包名 目录 和 “/data/misc/profiles/ref/” + 包名 目录。
  如果reconciledPkg.prepareResult.clearCodeCache为true,代表需要清除代码缓存,所以调用带有Installer.FLAG_CLEAR_CODE_CACHE_ONLY标识的clearAppDataLIF()方法。带这个标识的方法,就是清除这个应用数据文件夹下面的"code_cache"目录及其中文件。
  reconciledPkg.prepareResult.replace为true,代表是替换升级。mDexManager.notifyPackageUpdated()通知mDexManager应用包发生了更新,它会更新其中应用的安装位置,去除使用该应用的其他APP。
  mArtManagerService.prepareAppProfiles()是和使用profile优化应用有关,它的参数updateReferenceProfileContent为true,代表它需要将dex元数据文件(“.dm"结尾文件)更新到它自己引用的profile内容中,这块需要使用Profman程序。主APK文件相关的profile文件名为"primary.prof”。
  接着往下就是和执行Dex优化相关的,就是将相关的Dex指令转化成对应的机器指令。
  在属性变量PRECOMPILE_LAYOUTS值为true,调用mViewCompiler.compileLayouts(pkg)。它是用来将布局资源文件转化成dex文件。生成的dex文件为 包的数据目录 + “/code_cache/compiled_view.dex”。包的数据目录和uuid、userId、ce标识相关,如果uuid为null,userId为0,ce标识存在,则生成的文件位置为"/data/user/0/" + packageName + “/code_cache/compiled_view.dex”。它是对应用的一种优化。
  可以看到执行dexopt需要满足几个条件:不是instantApp,除非设置了Global.INSTANT_APP_DEXOPT_ENABLED对应的值不为0;包不是debuggable;不是在增量文件系统上。
  接着,BackgroundDexOptService.notifyPackageChanged(packageName) 是从BackgroundDexOptService中将应用包从之前编译失败的名单中去除。
  notifyPackageChangeObserversOnUpdate(reconciledPkg) 是通知注册在PackageManagerService对象成员mPackageChangeObservers集合中的每一个元素,调用它的onPackageChanged(event)方法。
  最后waitForNativeBinariesExtraction(incrementalStorages) 是处理增量更新的。

总结

  该阶段主要就是创建应用需要使用的目录,在更新应用安装情况下,会将代码缓存目录"code_cache"目录及其中文件清除。如果有dex元数据文件(.dm文件)会将它更新到应用的profile中去,如果满足dex优化条件,会执行Dexopt。

相关文章:

Android 安装应用-提交阶段之后剩下的操作

它的实现代码在executePostCommitSteps(commitRequest)中&#xff0c;看一下它的代码&#xff1a; /*** On successful install, executes remaining steps after commit completes and the package lock* is released. These are typically more expensive or require calls t…...

buuctf [ACTF2020 新生赛]Include

学习笔记。 开启靶机。 进入靶场&#xff1a; 我们跟进 tips瞅瞅&#xff1a; 额&#xff0c;纯小白&#xff0c;能想到的就是先F12看看&#xff0c;在CTRLu、以及抓包。 得&#xff0c;不会了&#xff0c;看wp呗&#xff0c;不会死磕没脑子0,0&#xff1f; 参考&#xff1a;…...

JS使用MutationObserver接口来监听DOM的更新

在JavaScript中&#xff0c;可以使用MutationObserver接口来监听DOM的更新。以下是一个使用MutationObserver的示例代码&#xff0c;它监听一个DOM节点的变化&#xff0c;并在变化发生时输出信息 // 选择目标节点 const targetNode document.getElementById(some-id);// 创建…...

图解C#高级教程(三):泛型

本讲用许多代码示例介绍了 C# 语言当中的泛型&#xff0c;主要包括泛型类、接口、结构、委托和方法。 文章目录 1. 为什么需要泛型&#xff1f;2. 泛型类的定义2.1 泛型类的定义2.2 使用泛型类创建变量和实例 3. 使用泛型类实现一个简单的栈3.1 类型参数的约束3.2 Where 子句3…...

240930_CycleGAN循环生成对抗网络

240930_CycleGAN循环生成对抗网络 CycleGAN&#xff0c;也算是笔者记录GAN生成对抗网络的第四篇&#xff0c;前三篇可以跳转 240925-GAN生成对抗网络-CSDN博客 240929-DCGAN生成漫画头像-CSDN博客 240929-CGAN条件生成对抗网络-CSDN博客 在第三篇中&#xff0c;我们采用了p…...

ide 使用技巧与插件推荐

ide 使用技巧与插件推荐 一、IDE 使用技巧 1. 快捷键 掌握常用快捷键&#xff1a; Windows: 使用 Ctrl、Alt 和 Shift 的组合。 Mac: 使用 Cmd、Option 和 Shift。 常用快捷键示例&#xff1a; VS Code: Ctrl P: 快速打开文件。 Ctrl Shift P: 打开命令面板。 Ctrl /…...

【node】 cnpm|npm查看、修改镜像地址操作 换源操作

【node】 cnpm|npm查看、修改镜像地址操作 换源操作 安装完node后 npm 1.查看当前npm信息 npm -v2.查看当前的镜像源 npm config get registry3.如果需要淘宝镜像源&#xff0c;修改当前的镜像源为淘宝镜像源 registry https://registry.npm.taobao.org弃用 npm config se…...

大数据-152 Apache Druid 集群模式 配置启动【下篇】 超详细!

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…...

IDE 使用技巧与插件推荐全面指南

目录 目录 常用IDE概述 Visual Studio Visual Studio Code IntelliJ IDEA PyCharm Eclipse IDE 使用技巧 通用技巧 Visual Studio 专属技巧 Visual Studio Code 专属技巧 IntelliJ IDEA 专属技巧 插件推荐 Visual Studio 插件 Visual Studio Code 插件 IntelliJ…...

java-快速将普通main类变为javafx类,并加载自定义fxml

java-快速将普通main类变为javafx类&#xff0c;并加载自定义fxml 前提步骤1. 普通类继承Application2. 实现main方法3. 写一个controller4. 写一个fxml文件5. 写start方法加载fxml6. 具体代码7. 运行即可 前提 使用自带javafx的jdk&#xff0c;这里使用的是jdk1.834&#xff…...

数据结构之——单循环链表和双向循环链表

一、单循环链表的奥秘 单循环链表是一种特殊的链表结构&#xff0c;它在数据结构领域中具有重要的地位。其独特的循环特性使得它在某些特定的应用场景中表现出强大的优势。 &#xff08;一&#xff09;结构与初始化 单循环链表的结构由节点组成&#xff0c;每个节点包含数据域…...

Git Stash: 管理临时更改的利器

Git 是一个非常强大的版本控制系统&#xff0c;它不仅帮助我们管理代码的版本&#xff0c;还提供了许多实用的功能来优化我们的工作流程。今天&#xff0c;我们要介绍的是 Git 中的一个非常实用的功能——git stash。 什么是 Git Stash&#xff1f; 在开发过程中&#xff0c;…...

ELK--收集日志demo

ELK--收集日志demo 安装ELK日志收集配置启动容器springboot配置测试 之前项目多实例部署的时候&#xff0c;由于请求被负载到任意节点&#xff0c;所以查看日志是开多个终端窗口。后来做了简单处理&#xff0c;将同一项目的多实例日志存入同一个文件&#xff0c;由于存在文件锁…...

Redis的主要特点及运用场景

Redis的主要特点及运用场景 Redis&#xff08;Remote Dictionary Server&#xff09;是一个开源的高性能键值对&#xff08;key-value&#xff09;数据库。它支持多种类型的数据结构&#xff0c;如字符串&#xff08;strings&#xff09;、散列&#xff08;hashes&…...

与我免费ai书童拆解《坚持》创作历程

插科打诨的海侃胡闹&#xff0c;调侃舒展《坚持》诗创的灵魂盛宴之旅。 (笔记模板由python脚本于2024年09月30日 19:11:42创建&#xff0c;本篇笔记适合喜欢python和诗歌的coder翻阅) 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.python.org/ Free&#x…...

昇思MindSpore进阶教程--下沉模式

大家好&#xff0c;我是刘明&#xff0c;明志科技创始人&#xff0c;华为昇思MindSpore布道师。 技术上主攻前端开发、鸿蒙开发和AI算法研究。 努力为大家带来持续的技术分享&#xff0c;如果你也喜欢我的文章&#xff0c;就点个关注吧 正文开始 昇腾芯片集成了AICORE和AICPU等…...

Hive SQL业务场景:连续5天涨幅超过5%股票

一、需求描述 现有一张股票价格表 dwd_stock_trade_dtl 有3个字段分别是&#xff1a; 股票代码(stock_code), 日期(trade_date)&#xff0c; 收盘价格(closing_price) 。 请找出满足连续5天以上&#xff08;含&#xff09;每天上涨超过5%的股票&#xff0c;并给出连续满足…...

Java 如何从图片上提取文字

生活中我们可能会遇到想从图片上直接复制上边的文字&#xff0c;该如何获取呢&#xff0c;接下来看看如何使用Java程序实现从图片中读取文字。 实现过程 1、引入Tess4J 依赖 <!--Tess4J 依赖--> <dependency><groupId>net.sourceforge.tess4j</groupId…...

C#进阶-读写Excel常用框架及其使用方式

目录 一、MiniExcel开源框架&#xff08;推荐&#xff09; 1、写/导出 方式一 方式二 多表创建 更改配置 特性使用 CSV尾行新增行 CSV、XLSX互转 2、读/导入 简单示例 二、NPOI开源框架 一、MiniExcel开源框架&#xff08;推荐&#xff09; 添加NuGet包MiniExcel…...

Python爬虫lxml模块安装导入和xpath基本语法

lxml模块是Python的一个解析库&#xff0c;主要用于解析HTML和XML文件。 一、安装导入 使用包管理器安装&#xff0c;在cmd下或编辑器下的控制台&#xff0c;运行&#xff1a; pip install lxml 导入&#xff1a; from lxml import etree 二、xpath基础知识 XPath&#…...

uniapp 对接腾讯云IM群组成员管理(增删改查)

UniApp 实战&#xff1a;腾讯云IM群组成员管理&#xff08;增删改查&#xff09; 一、前言 在社交类App开发中&#xff0c;群组成员管理是核心功能之一。本文将基于UniApp框架&#xff0c;结合腾讯云IM SDK&#xff0c;详细讲解如何实现群组成员的增删改查全流程。 权限校验…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者

抖音增长新引擎&#xff1a;品融电商&#xff0c;一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中&#xff0c;品牌如何破浪前行&#xff1f;自建团队成本高、效果难控&#xff1b;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下&#xff0c;知识图谱凭借其高效的信息组织能力&#xff0c;正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合&#xff0c;探讨知识图谱开发的实现细节&#xff0c;帮助读者掌握该技术栈在实际项目中的落地方法。 …...

k8s业务程序联调工具-KtConnect

概述 原理 工具作用是建立了一个从本地到集群的单向VPN&#xff0c;根据VPN原理&#xff0c;打通两个内网必然需要借助一个公共中继节点&#xff0c;ktconnect工具巧妙的利用k8s原生的portforward能力&#xff0c;简化了建立连接的过程&#xff0c;apiserver间接起到了中继节…...

tree 树组件大数据卡顿问题优化

问题背景 项目中有用到树组件用来做文件目录&#xff0c;但是由于这个树组件的节点越来越多&#xff0c;导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多&#xff0c;导致的浏览器卡顿&#xff0c;这里很明显就需要用到虚拟列表的技术&…...

C#学习第29天:表达式树(Expression Trees)

目录 什么是表达式树&#xff1f; 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持&#xff1a; 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...

快刀集(1): 一刀斩断视频片头广告

一刀流&#xff1a;用一个简单脚本&#xff0c;秒杀视频片头广告&#xff0c;还你清爽观影体验。 1. 引子 作为一个爱生活、爱学习、爱收藏高清资源的老码农&#xff0c;平时写代码之余看看电影、补补片&#xff0c;是再正常不过的事。 电影嘛&#xff0c;要沉浸&#xff0c;…...

Qemu arm操作系统开发环境

使用qemu虚拟arm硬件比较合适。 步骤如下&#xff1a; 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载&#xff0c;下载地址&#xff1a;https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...

用递归算法解锁「子集」问题 —— LeetCode 78题解析

文章目录 一、题目介绍二、递归思路详解&#xff1a;从决策树开始理解三、解法一&#xff1a;二叉决策树 DFS四、解法二&#xff1a;组合式回溯写法&#xff08;推荐&#xff09;五、解法对比 递归算法是编程中一种非常强大且常见的思想&#xff0c;它能够优雅地解决很多复杂的…...

Java并发编程实战 Day 11:并发设计模式

【Java并发编程实战 Day 11】并发设计模式 开篇 这是"Java并发编程实战"系列的第11天&#xff0c;今天我们聚焦于并发设计模式。并发设计模式是解决多线程环境下常见问题的经典解决方案&#xff0c;它们不仅提供了优雅的设计思路&#xff0c;还能显著提升系统的性能…...