当前位置: 首页 > 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&#…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)

概述 在 Swift 开发语言中&#xff0c;各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过&#xff0c;在涉及到多个子类派生于基类进行多态模拟的场景下&#xff0c;…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成&#xff0c;核心是利用 HTTP 协议的 Range 请求头指定下载范围&#xff1a; 实现原理 Range 请求头&#xff1a;向服务器请求文件的特定字节范围&#xff08;如 Range: bytes1024-&#xff09; 本地文件记录&#xff1a;保存已…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案

随着新能源汽车的快速普及&#xff0c;充电桩作为核心配套设施&#xff0c;其安全性与可靠性备受关注。然而&#xff0c;在高温、高负荷运行环境下&#xff0c;充电桩的散热问题与消防安全隐患日益凸显&#xff0c;成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

【决胜公务员考试】求职OMG——见面课测验1

2025最新版&#xff01;&#xff01;&#xff01;6.8截至答题&#xff0c;大家注意呀&#xff01; 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:&#xff08; B &#xff09; A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台

🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...