提示!应用程序的安装有两种情况,第一:首次启动系统时安装。第二:系统启动完毕后安装。

本篇博文基于第一种安装场景。在系统首次启动的场景中,系统会对/system/app、/system/priv-app、/data/app文件夹下的全部APK进行dex字节码到本地机器码的翻译,相同也会对/system/framework文件夹下的APK或者JAR文件,以及这些APK所引用的外部JAR。进行dex字节码到本地机器码的翻译。这样能够保证除了应用之外。系统中使用Java来开发的系统服务,也会统一地从dex字节码翻译成本地机器码。具体内容请移步老罗的博客Android ART执行时无缝替换Dalvik虚拟机的过程分析。

一、JVM、DVM、ART虚拟机了解
  • JVM虚拟机执行的是java字节码:
java->java bytecode(class)->java bytecode(jar)
注!

java虚拟机基于栈,基于栈的机器必须使用指令来加载和操作栈上的数据,所需指令相对来说比較多。

  • Dalvik虚拟机解释运行的dex字节码:
java->java bytecode(class)->dalvik bytecode(dex)
注:相对JVM,Dalvik基于寄存器,且经过优化并同意有限的内存中同一时候执行多个虚拟机实例。每一个Dalvik应用作为一个独立的Linxu进程执行。假设一个应用中有非常多类,编译后会对应生成非常多class文件。class文件之间也会有不少冗余信息,dex格式文件把全部classs文件内容整合到一个文件。这样能够降低总体文件占用,IO操作,同一时候也提高了类的查找速度。

此外。dex格式文件添加了新的操作码支持,文件结构也相对简洁,使用等长的指令来提高解析速度。

并且dex文件会尽量扩大仅仅读结构的大小,来提高进程间数据共享的速度。

  • ART虚拟机运行的本地机器码:
java->java bytecode(class)->dalvik bytecode(dex)->optimized android runtime machine code(oat)
注:ART所使用的AOT(Ahead-Of-Time)编译。在应用首次安装时,字节码预编译成机器码存储在本地,也就是说在程序执行前编译。而Dalvik是典型的JIT(Just_In_Time),此模式下,应用每次执行的时候,字节码都须要即时编译器转换为机器码再执行,也就是在程序执行时编译。因此在App执行时。ART模式相对于Dalvik省去了解释字节码的过程,占用内存也对应降低,进而提高App的执行效率。

二、Odex

从上面一节中我们知道,在编译打包APK时,Java类会被编译成一个或者多个字节码文件(.class),通过dx工具CLASS文件转换成一个DEX(Dalvik Executable)文件。
通常情况下,我们看到的Android应用程序实际上是一个以.apk为后缀名的压缩文件。我们能够通过压缩工具对apk进行解压,解压出来的内容中有一个名为classes.dex的文件。

那么我们首次开机的时候系统须要将其从apk中解压出来保存在data/app文件夹中。

假设当前执行在Dalvik虚拟机下,Dalvik会对classes.dex进行一次“翻译”。“翻译”的过程也就是守护进程installd的函数dexopt来对dex字节码进行优化,实际上也就是由dex文件生成odex文件。终于odex文件被保存在手机的VM缓存文件夹data/dalvik-cache下(注意。这里所生成的odex文件依然是以dex为后缀名,格式如:system@priv-app@Settings@Settings.apk@classes.dex)。
假设当前执行于Art模式下,    Art相同会在首次进入系统的时候调用/system/bin/dexopt工具来将dex字节码翻译成本地机器码,保存在data/dalvik-cache下。
那么这里须要注意的是,不管是对dex字节码进行优化,还是将dex字节码翻译成本地机器码,终于得到的结果都是保存在同样名称的一个odex文件中面的,可是前者相应的是一个dey文件(表示这是一个优化过的dex),后者相应的是一个oat文件(实际上是一个自己定义的elf文件,里面包括的都是本地机器指令)。

简单来说不管是Art模式。还是DVM,优化的结果都是一个odex文件,仅仅是这两种odex文件有着本质的差别(一个是dey字节码,一个是oat机器码)。之所以这么设计。主要通过这样的方式,原来不论什么通过绝对路径引用了该odex文件的代码就都不须要改动了。能够理解为这是art与dalvik兼容的结果。

因为在系统首次启动时会相应用进行安装。那么在预置APK比較多的情况下。将会大大添加系统首次启动的时间。从前面的描写叙述可知,既然不管是DVM还是ART,对DEX的优化结果都是保存在一个同样名称的odex文件,那么假设我们把这两个过程在ROM编译的时候预处理提取Odex文件将会大大优化系统首次启动的时间。
三、预编译提取Odex
在BoardConfig.mk中定义:WITH_DEXPREOPT := true。打开这个宏之后,不管是有源代码还是无源代码的预置apk预编译时都会提取odex文件。

只是这里须要注意的是打开WITH_DEXPREOPT 宏之后,预编译时提取Odex会添加一定的空间。预置太多apk。会导致system.img 过大。而编译只是。遇到这样的情况能够通过删除apk中的dex文件、调大system.img的限制大小,或在预编译时跳过一些apk的odex提取。
比如跳过helloworld应用提取的方法例如以下:

在文件夹\build\core\dex_preopt_odex_install.mk中加入红色标记的代码:

ifeq ($(LOCAL_MODULE),helloworld)

LOCAL_DEX_PREOPT:=

endif

build_odex:=

installed_odex:=

....

helloworld可替换为须要跳过提取odex的apk的LOCAL_MODULE名字,如Settings等。

Android首次启动时间长优化之预编译提取Odex相关推荐

  1. android预置app 不分解odex,Android首次启动时间长优化之预编译提取Odex

    提示!应用程序的安装有两种情况,第一:首次启动系统时安装:第二:系统启动完成后安装.本篇博文基于第一种安装场景.在系统首次启动的场景中,系统会对/system/app./system/priv-app ...

  2. Android开机时长优化

    文章目录 一.背景说明 二.开机流程介绍 三.分析方法&工具 3.1 手动秒表计时 3.2 bootchart 3.2.1 生成log文件 3.2.2 生成bootchart.png 3.2. ...

  3. GCC编译优化应用预编译头

    服务器编译优化记录 对项目编译优化过程中一些思路和脚本工具实现.对内存受限的编译环境有一些帮助. 工具: https://github.com/wangxiaobai-dd/GccPrecompile ...

  4. android 编译之后黑屏_抖音BoostMultiDex:Android低版本上首次启动时间减少80%(一)...

    我们知道,Android 低版本(4.X 及以下,SDK < 21)的设备,采用的 Java 运行环境是 Dalvik 虚拟机.它相比于高版本,最大的问题就是在安装或者升级更新之后,首次冷启动的 ...

  5. Android 8.0 odex预编译与空间占用相关设置探究

    目录 Android 8.0 odex预编译与空间占用相关设置探究 1.引言 2.odex全局设置 3.APK设置 Android 8.0 odex预编译与空间占用相关设置探究 1.引言 所谓Odex ...

  6. 这是预编译工具生成的文件_组件化架构 10.编译优化

    软件研发中,耗费最多时间的并不是编写代码,而是代码编译和代码不断调试的过程 软件试错时间 Android基础编译流程 编译构建的四个步骤: 代码编译:将源代码,R文件,AIDL生成的文件等 编译成.c ...

  7. 【Android 性能优化】应用启动优化 ( 启动优化项目 | 界面启动时间 | 启动优化项目 | 方法追踪 MethodTracing )

    文章目录 一. 界面启动时间 二. 启动优化项目 三. 方法追踪 一. 界面启动时间 在 [Android 性能优化]应用启动优化 ( 启动白屏问题 | 应用启动时间测量 | 冷启动 | 热启动 | ...

  8. 谷歌发布 Android 8.1 首个开发者预览版,优化内存效率

    今晨,谷歌推出了 Android 8.1 首个开发者预览版,此次升级涵盖了针对多个功能的提升优化,其中包含对 Android Go (设备运行内存小于等于 1 GB)和加速设备上对机器学习的全新神经网 ...

  9. 网站优化记录-通过命令预编译Asp.net 网站,成功优化到毫秒级别。

    在去年一次项目上线时发现部署的站点首次访问跟回收后响应特别慢,每次都在3秒以内.(使用的是vs工具预编译的方式发布),在随后找到解决办法是通过命令预编译Asp.net 网站,成功解决站点响应在毫秒级别 ...

最新文章

  1. 硬刚一周,3W字总结,一年的经验告诉你如何准备校招!
  2. 太牛了 Python期末复习总结,提高成绩必备回家过个开心年
  3. 设计模式你怎么看?--抽象工厂模式
  4. 若依框架二次开发中的坑
  5. C++实现tree234树(附完整源码)
  6. C#微信公众号开发系列教程三(消息体签名及加解密)
  7. android 生成debug.keystore,android sdk 如何重新生成debug.keystore
  8. ios html字符转义字符串,iOS HTML特殊字符转译
  9. javascript框架比较(二)
  10. visual studio 2008试用版的评估期29天后结束 解决办法
  11. Polycom高清视频会议桌面系统HDX 4000
  12. 使用planetaryjs插件实现3维地球仪效果
  13. 广东省民营企业合作交流协会会长谭铭卓一行到访
  14. UBUNTU环境下编译的openwrt
  15. Linux-引导过程与服务控制
  16. anaconda安装dlib出现ImportError: libopenblas.so.0: cannot open shared object file***
  17. 干货丨小米自研主动降噪技术在Redmi Buds Pro4上的应用
  18. 红旗linux镜像文件iso,红旗Linux11下载-红旗Linux国产操作系统11ISO 社区预览版下载...
  19. 微信云开发AI短视频一键换脸小程序源码/带流量主
  20. Excel - 学习 - 笔记6: Excel 函数 - filter 函数

热门文章

  1. 使用U盘在Mac机上装win8.1系统
  2. 【原】 动态加载dll
  3. Comparable接口与Comparator接口
  4. EditText / This text field does not specify an inputType or a hint
  5. Esfog_UnityShader教程_前言
  6. 复旦大学跑步爱好者协会章程(终稿)
  7. cnn stride and padding_卷积神经网络(CNN) 第 4 课(上)
  8. 重新封装了一下NODE-MONGO 使其成为一个独立的服务.可以直接通过get/post来操作
  9. 我的 Serverless 实战 — Serverless 架构理念 ( 后端服务器发展 | Serverless 与 ServerFul | Serverless 定义 | 架构优缺点 )
  10. 【Flutter】顶部导航栏实现 ( Scaffold | DefaultTabController | TabBar | Tab | TabBarView )