应用启动流程梳理(一)-应用安装流程

想针对启动耗时&卡顿优化做一个专题,一来是复习二来是构建完整知识结构。分析应用的启动势必需要先了解整个启动的流程,那么在分析前,需要先简单总结下整个启动流程的梳理大纲,基于android 9.0版本:


梳理大纲

那么我梳理的场景整体流程是:安装一个应用,完成安装之后点击Launcher桌面某App图标,应用启动到主界面显示完成整个过程。过程不涉及代码,具体分析可以去看之前对应的文章,里面有详细的源码分析。

一、应用安装流程

应用安装过程简单说就两步:

1.1 复制Apk到指定目录

主Apk复制路径如下:
system/app 系统应用存放目录
data/app 三方应用存放目录

~:/system/app/Bluetooth # ls -al
total 4048
drwxr-xr-x   4 root root    4096 2009-01-01 08:00 .
drwxr-xr-x 103 root root    4096 2009-01-01 08:00 ..
-rw-r--r--   1 root root 4124698 2009-01-01 08:00 Bluetooth.apk
drwxr-xr-x   3 root root    4096 2009-01-01 08:00 lib
drwxr-xr-x   3 root root    4096 2009-01-01 08:00 oat

~:/data/app/com.ss.android.article.news-kk9ZSokxPMvccIA7c41aJA== # ls -al
total 26108
drwxrwxr-x  4 system system      3488 2019-10-31 23:57 .
drwxrwx--x 41 system system      3488 2019-10-31 23:57 ..
-rw-r--r--  1 system system  26690526 2019-10-31 23:57 base.apk
drwxr-xr-x  3 system system      3488 2019-10-31 23:57 lib
drwxrwx--x  3 system install     3488 2019-10-31 23:57 oat

内容与权限一目了然,这里就不赘述了。另外再关注一个目录,data/data,这是各三方应用的私有目录,自然是用户权限的,那么是不是root权限的进程就可以随意访问了呢?其实也不然,在锁屏解锁前,data/data目录内的文件都是按FBE加密的,但是在解锁之后会解密。这属于文件系统的东西了,没有深入研究。

但是我总结的结论是:/data目录下,凡是_ce结尾的是一直加密的,_de结尾是不加密的。其他的没有调研,但是data/data是在锁屏解锁前加密,解锁后解密。感兴趣的可以自行研究Android的文件系统加密。
[FBE加密官方介绍]https://source.android.google.cn/security/encryption/file-based

~:/data/data/com.ss.android.article.news # ls -al
total 73
drwx------  13 u0_a214 u0_a214        3488 2019-11-01 00:08 .
drwxrwx--x 322 system  system        24576 2019-10-31 23:57 ..
drwxrwx--x   2 u0_a214 u0_a214        3488 2019-11-01 00:08 app_textures
drwx------   3 u0_a214 u0_a214        3488 2019-11-01 00:08 app_webview
drwx------   2 u0_a214 u0_a214        3488 2019-11-01 00:08 app_webview_2930
drwx------   2 u0_a214 u0_a214        3488 2019-11-01 00:08 app_webview_3017
drwx------   4 u0_a214 u0_a214        3488 2019-11-01 00:08 app_webview_3298
drwxrws--x  10 u0_a214 u0_a214_cache  3488 2019-11-01 00:08 cache
drwxrws--x   2 u0_a214 u0_a214_cache  3488 2019-10-31 23:57 code_cache
drwxrwx--x   2 u0_a214 u0_a214        3488 2019-11-01 00:08 databases
drwxrwx--x  26 u0_a214 u0_a214        3488 2019-11-01 00:08 files
lrwxrwxrwx   1 root    root             74 2019-10-31 23:57 lib -> /data/app/com.ss.android.article.news-kk9ZSokxPMvccIA7c41aJA==/lib/arm
drwx------   2 u0_a214 u0_a214        3488 2019-11-01 00:08 lib-main
drwxrwx--x   2 u0_a214 u0_a214       20480 2019-11-01 00:09 shared_prefs

1.2 安装APK:

安装过程简单说就是AndroidManifest.xml的解析,包括名字、版本、权限、四大组件等信息。然后分别做了内存存储和文件持久化。Launcher会获取<action android:name="android.intent.action.MAIN" />和<category android:name="android.intent.category.LAUNCHER" />的Activity,并绑定一个应用图标,点击Launcher对应的应用图标,实际上就是做了一次Activity的隐式启动。

当然应用安装过程是很复杂的,包括权限的检查、文件夹的创建、安装逻辑判断、数据结构的封装等等内容。我这只是挑了几点与启动相关的总结一下。

1.3 其他APK相关知识点

1)APK组成

  • AndroidManifest.xml 应用整体配置信息。

  • META-INF 签名信息。

  • lib 应用依赖的native .so库,也包括一些插件。根据手机CPU的架构,lib库大体上可以分为4种:ARM、ARM-V7、MIPS和X86,分别对应着4种CPU架构。实际上,市面上的手机几乎全都是ARM架构的,所以大多数情况下我们只需要有armeabi和armeabi-v7a两种类型的库就足够了。

  • res 系统资源目录,与工程对应目录内容一致。

  • assets 跟res目录有点相似,但实际上二者还是有区别的。res目录中的文件会映射到R文件中,每个资源文件都有自己的ID,而assets中的文件则直接通过AssetManager类进行访问,而且assets目录你可以添加任意深度的子目录,这一点会比较方便管理和归类文件。相比较之下,res目录目前不能支持更深级的子目录。附带了解assets与raw的区别:assets不做任何处理被打包,资源通过AssetManager访问,目录可以分层。raw通过资源ID访问,不参与编译,目录不可分层。

  • classes.dex .java文件通过javac编译生成.class,多个.class通过dex生成.dex文件。.dex是面向Android虚拟机的标准字节码。

  • resources.arsc 编译后的二进制资源文件索引,记录了资源文件(即res目录中的文件)和资源文件ID的映射关系,这样程序运行的时候就可以根据资源的ID获取到相应的资源。

2)编译

  App在android上运行,首先需要dex加载到内存,dex执行方式主要有两种:解释器执行 和 执行编译后的机器码 两种执行方式。解释执行就是及时编译,运行到哪解释到哪,这样效率不高,所以google在2.2版本引入了JIT,在解释执行过程中针对热点代码编译为机器码并且优化,然后缓存在内存中,下次执行到相同代码直接调用缓存的机器码,提升效率。但是app进程消亡下次重新冷启就没了。google4.4.推出art虚拟机替换Dalvik,推出AOT编译,即生成的机器码缓存为文件,作为持久化优化,每次编译会更新文件,但是更新频率并不高。优点是机器码持久化保证下次使用也能直接跑机器码,提升执行效率,缺点是编译耗时且CPU抢占严重。为了不影响用户体验,编译时机非常关键。

Android推出4种编译filter:

  • verify:只运行 DEX 代码验证。
  • quicken:运行 DEX 代码验证,并优化一些 DEX 指令,以获得更好的解释器性能。
  • speed-profile:运行 DEX 代码验证,并对配置文件中列出的方法进行 AOT 编译。
  • speed:运行 DEX 代码验证,并对所有方法进行 AOT 编译。
    执行效率上:
    verify < quicken < speed-profile < speed
    编译速度上:
    verify > quicken > speed-profile > speed
    编译触发的几个时机:
路径 描述 编译方式 编译内容
Install 应用安装通过installd触发的编译 speed-profile 主apk
OTA升级 系统升级通过installd触发的编译 verify 主apk
load dexFile 动态加载插件直接通过虚拟机触发的编译 quicken 插件
postboot 开机1分钟后,针对全部安装的7天内未使用且过期的应用通过installd触发的编译 verify 主apk
idle 同时满足充电、idle状态且24小时内只触发一次,主apk通过installd触发编译,插件通过虚拟机触发编译 speed-profile 主apk 和 插件

另外,编译的内存除了主apk之外还包含应用的插件,主apk间距通过PMS交由installd来触发dex2oat编译,插件则通过动态加载直接由虚拟机触发dex2oat编译。

3)动态加载插件

核心流程在于loadDexFile,这个过程核心逻辑是:先判断是否有.odex文件,然后判断是否过期,如果既有.odex又没过期,那么直接加载,如果不满足则先执行dex2oat编译,编译完之后将.odex加载到内存才开始执行。另外.dex编译过程是持锁的,个人感觉目的可能是防止多处同时触发loadDexFile,避免重复编译。到了Android Q之后,动态加载插件去掉了编译逻辑,也就是如果没有.odex或者有但是过期,直接跳出去加载.dex文件走解释模式,不再进行编译了。 好处是减少第一次加载等锁造成的卡顿,坏处就是解释模式执行效率不高。

这里其实我多加了很多内容,不光是关于应用安装流程的,好了这部分先到这。

上面牵涉到的部分知识点详细细节可以参看之前写过的文章:
Android PMS(一)-启动流程
Android PMS(二)-Apk安装流程
Android PMS(三)-Installd执行dexopt流程
Android PMS(四)-安装微信
启动耗时分析(三)-ART编译分析
Android 9.0 ART编译分析(一)-编译通路梳理
Android 9.0 ART编译分析(二)-Installd触发dex2oat编译流程
Android 9.0 ART编译分析(三)-虚拟机触发dex2oat编译流程

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 162,408评论 4 371
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,690评论 2 307
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 112,036评论 0 255
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,726评论 0 221
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 53,123评论 3 296
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 41,037评论 1 225
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,178评论 2 318
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,964评论 0 213
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,703评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,863评论 2 254
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,333评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,658评论 3 263
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,374评论 3 244
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,195评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,988评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,167评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,970评论 2 279