乐趣区

关于android:大厂Android启动优化出其不意的优化手段

惯例的伎俩优化后,咱们能解决根本的问题,然而咱们得持续谋求极致,本章将分享一些意想不到的伎俩。

1 首页合并

通常咱们启动的时候分为闪屏和首页两个页面,咱们将闪屏和首页合并成一个,通过 fragment 来操作实在页面,广告设计成一个 dialog fragment 浮在首页就行。根本的收益在 100ms 左右。首页合并后发现几个问题:首页治理、唤端启动问题。

  • 首页无奈应用 singletask,singletask 的问题咱们通过手动保护一个 activity 栈去治理,保障一个首页。
  • 唤端启动,第三方 app 唤端没有加 newtask 标签,导致页面启动在第三方 app 内,这个临时没有遇到很好的解决形式,还是在推动比拟大的第三方平台去解决。

2 渲染音讯优先级队列

咱们数据申请后,通过 handler 将音讯发送到主线程,handler 音讯队列内可能比拟忙碌,咱们思考的是将数据回调和图片回调的音讯发送到音讯队列后面。
MessageQueue 其实提供了一个办法 handler.sendMessageAtFrontOfQueue 的形式。

3 dex2oat

Android ART 虚拟机后,能够将 dex 文件事后的翻译解决成机器码间接运行,在 Android 5 – 7 版本,dex 解决是在 app 装置的时候解决的,然而因为 dex2oat 性能影响较大,装置的时候将耗时过长,Android 7 后改为装置的时候不做翻译,运行时还是解释执行,运行时的时候记录运行的函数等信息,在手机闲置的状况上来把这些热办法做 dex2oat,下次运行间接运行机器码。
然而零碎判断闲置的条件比拟刻薄,导致大部分状况下 app 没有被 dex2oat,另外互联网 app 疾速倒退,发版速度较快,所以 dex2oat 的利用率低,通过 app 本人手动调用零碎 dex2oat 达到疾速将 app 的 dex 转化,进步代码执行效率,该计划的收益大略在 10%。相干的具体常识能够网上搜寻一下。

零碎记录热办法的数据文件存在 /data/misc/profiles/cur/0/packageName/primary.prof下,咱们能够通过 FileObserver 监听这个这个文件批改判断是否须要 dex2oat。
dex2oat 能够通过 shell 命令执行cmd package compile -m speed-profile -f packageName

4 Redex

Linux 文件系统从磁盘读文件的时候,会以 block 为单位去磁盘读取,个别 block 大小是 4KB。也就是说一次磁盘读写大小至多是 4KB,而后会把 4KB 数据放到页缓存 Page Cache 中。如果下次读取文件数据曾经在页缓存中,那就不会产生实在的磁盘 I/O,而是间接从页缓存中读取,大大晋升了读的速度。所以下面的例子,咱们尽管读了 1000 次,但事实上只会产生一次磁盘 I/O,其余的数据都会在页缓存中失去。

Dex 文件用的到的类和安装包 APK 外面各种资源文件个别都比拟小,然而读取十分频繁。咱们能够利用零碎这个机制将它们依照读取程序重新排列,缩小实在的磁盘 I/O 次数。

类重排

启动过程类加载程序能够通过插装动态代码块获取。

class A {
    static {// 记录}
}

而后通过 ReDex 的 Interdex 调整类在 Dex 中的排列程序,最初能够利用 010 Editor 查看批改后的成果。

从多方拿到的数据来看,收益在0-6%,整体不是很显著,而且须要把 redex 工程化、思考和 proguard 的兼容等问题。

5 黑科技

微信 Hardcoder

构建了 App 与零碎(ROM)之间牢靠的通信框架,让零碎晓得 App 的需要,能够让 app 获取更多的系统资源。

原理

  • 1、其实质是让App 跨过 Framework 间接跟厂商 ROM 通信
  • 2、分为 Client 端和 Server 端,Server 端由厂商零碎侧自行实现
  • 3、它们间接采纳 LocalSocket 形式,Hardcoder 是 Native 实现的,应用了 Linux 的 Socket 接口 实现了一套本人的 LocalSocket。

整体收益不是特地显著。

GC 克制

网上讲的很多文章都是 4.4 版本的 GC 克制,因为在 ART 虚拟机之前,Android 的 GC 回收算法是进行所有,所有克制 GC 收益很大。

ART 虚拟机后,采纳并行回收的算法,GC 回收对性能的影响大大降低。然而通过 systrace 剖析,在启动过程中,GC 线程也存在抢占系统资源的状况。

Google 也留神到了后盾 GC 对于利用启动速度的影响,并尝试了在 Android 中对这一场景进行优化。在 Android 10 的代码中。有如下提交:cs.android.com/android/_/a…

这个改变的逻辑是:利用启动时 Zygote Fork 出新的过程之后,在 2 秒内临时进步 Background GC 工作触发的阈值。这样 Background GC 将会更难被触发。

那么 Google 这个提交的优化成果如何?Comments 中蕴含了测试成果,能够看到各个利用的启动速度都有晋升。

能够看出克制 GC 有较显著的成果,然而 Google 这个改变只存在于 Android 10 及以上的机型。那么能够找找办法在 Android 10 之前的机器也享受到这个优化的成果。

6 Hook 框架

开源框架 epic
利用 hook 框架发现问题,比方监控大 io 读取,获取零碎服务等。

7 主线程优先级问题

Android 的离奇陷阱 — 设置线程优先级导致的微信卡顿惨案
在 Anroid11 以下,在线程没有 start 实现设置线程优先级可能导致批改的是主线程优先级,导致主线程优先级升高,影响运行效率。

8 后继

至此,相干的优化内容曾经实现,接下来分享怎么放弃咱们的优化成绩和疾速发现问题。

文章转自 https://juejin.cn/post/701734… 如有侵权,请分割删除。

相干视频举荐:

【2021 最新版】Android studio 装置教程 +Android(安卓)零基础教程视频(适宜 Android 0 根底,Android 初学入门)含音视频_哔哩哔哩_bilibili

【Android 进阶教程】——App 启动速度的优化_哔哩哔哩_bilibili

Android 进阶零碎学习——高级 UI 卡顿性能优化_哔哩哔哩_bilibili

退出移动版