一. Android 启动时间优化

系统启动过程:
1)开机打开电源
2)BootLoader程序
3)Linux的 init.rc

  1. init进程
    5)Zygote的JVM
    6)SystemServer进程
    Binder线程池
    SystemServiceManager(AMS、WMS、PMS、CameraService等等被启动)

1)启动页白屏及黑屏解决?
2)启动太慢怎么解决?
3)怎么保证应用启动不卡顿?
4)App启动崩溃异常捕捉
5)统计启动时长,标准

App启动速度是用户的第一印象,本章会介绍精准度量启动速度的方式,启动优化的相关工具、常规优化手段等,同时我会介绍异步初始化以及延迟初始化的最优解,以最优雅、可维护性高的的方式获得闪电般的启动速度。...

一. App 启动优化介绍

App Startup time
冷启动:耗时最多、衡量标准。
启动App、加载空白Window、创建进程
随后任务,创建Application、启动主线程、创建MainActivity。

热启动:后台 ——> 前台。最快
温启动:较快。仅仅重走LifeCycle。

优化方向:
Application和Activity生命周期

二. 启动时间测量方式

两种方式:adb 命令 / 手动打点

  1. adb方式
    adb shell am start -W packagename/首屏Activity
    ThisTime:最后一个Activity启动耗时
    TotalTime:所有Activity启动耗时
    WaitTime:AMS启动Activity的总耗时
    (此方式线下使用方便,不能带到线上。非严谨、精确时间)

  2. 手动打点:
    启动时埋点,启动结束时埋点,两者差值。
    写个工具类,读取SystemCurrentTimeMillis

结束时间的记录位置?真实数据展示出来,Feed第一条展示。
onWindowFocusChanged不够准确。
getViewTreeObserver 的 addOnPreDrawListener

三. 启动优化工具选择

主要两个工具:TraceView、Systrace

1. TraceView

图形的形式展现执行时间、调用等。信息全面,包含所有线程

使用方式:Debug.startMethodTracing("");
Debug.stopMethodTracing("");

生成文件在sd卡:Android/data/packagename/files
最大能有 8MB的信息。

图像分析:
Top Down:Self Time、Total Time (Wall Clock Time、Thread Time)是call Chart 的详细文字版本
Call Chart:a调用b,那么a 就在 b 的上面。系统API 橙色、应用自己的绿色,第三放的就是蓝色
Flame Chart:相同调用顺序的过程会合并在一起。
BottomUp:和Top Down相反。
TraceView 运行时开销严重,整体都会变慢。

与CpuProfiler相比,此工具Android Studio中直接使用。可能需要手速很快才能获取到。

2.Systrace

结合Android 内核的数据,生成一个Html报告

API 18 以上使用,推荐TraceCompact

使用方式:
python systrace.py -t 10 [other-options] [categories]

https://developer.android.com/studio/command-line/systrace#command_options

Systrace指令

查看CPU 核心运行状况

UIThread 和 Other Threads的对比

通过Slice 查看 start 、wall Duration(代码执行时间)、CPU Duration (代码消耗cpu的时间)

举例:锁冲突

四. 优雅获取方法耗时讲解

常规方法的侵入性太强。重复编辑。

所以,采用AOP方法(Aspect Oriented Programming 面向切面编程)

  • 针对同一类问题的统一处理
  • 无侵入添加代码

AspectJ使用:

classPath ‘com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.0’

implementation 'org.aspectj:aspectjrt:1.8.+'

apply plugin: 'android-aspectjx'

Join Points:程序运行时的执行点,可以作为切面的地方。

  • 函数调用、执行
  • 获取、设置变量
  • 类初始化

PointCut:带条件的JoinPoints (筛选一下某些点)
一种Hook,要插入代码的位置

Before:PointCut之前执行。Advice,具体插入位置。

After:PointCut之后执行

Around:PointCut之前和之后分别执行

execution:处理Join Point 的类型,call、execution
(* android.app.Activity.on**(..)):匹配规则

onActivityCalled:要插入的代码

4.1优雅获取方法耗时实操

4.2 异步优化详解
优化技巧:
Theme切换:感觉上的快。

异步优化:
子线程分担住线程任务,并行减少时间。

ExecutorService service = Executors.newFixedThreadPool(CORE_POOL_SIZE);

service.submit(new Runnable(){
      public void run(){
          方法分别放入;
      }
});

不符合异步要求的。部分代码必须运行在主线程当中,那么放弃这种异步优化的方案。

需要在某阶段完成。由于异步执行不知道 子任务何时结束,跳转新界面时 该方法是否完成,

添加

private CountDownLatch mCountDownLatch = new CountDownLatch(1); // 一个简单的开/关锁存器

在条件被满足后

mCountDownLatch.countDown();
try {
          mCountDownLatch.await();
} catch(InterruptedException e){
          e.printStackTrace;
}

4.3 异步初始化最优解-启动器-1
充分利用CPU多核,自动梳理执行顺序

  • 代码Task化,启动逻辑抽象为Task。
  • 根据所有任务以来关系排序生成一个有向无环图
  • 多线程按照排序后的优先级依次执行

4.4 异步初始化最优解-启动器-2
TaskDispatcher。并向当中要执行的Task 分别继承,在run方法中进行执行。

4.5 更优秀的延迟初始化方案
常规方式,回调方法中执行耗时。很有可能导致feed 卡顿。
对延迟任务进行分批初始化。

  • 利用IdleHandler特性,空闲时执行

4.6 启动优化其它方案
异步、延迟、懒加载。
技术、业务相结合。
cpu time才是优化方向
按照systrace 及 cpu time 跑满cpu

IO密集型 和 CPU密集型 操作。
收敛启动代码修改权限。

结合Ci修改启动代码需要Review通知

其他方案:

  • 提前加载SharedPreferences。getSharedPreference load到内存中。如果没有完成一直阻塞进行等待。
  • Multidex之前加载,利用此阶段CPU覆写 getApplicationContext() 返回 this。 attachBaseContext中
    启动阶段不启动子进程,子进程会共享CPU资源,导致主进程CPU紧张。注意启动顺序:App onCreate 之前是ContentProvider

类加载优化:提前异步加载(可以替换掉系统的ClassLoader,每个类加载的时候都打印一个Log)Class.forName() 只加载类本身及其静态变量的引用类。
new 类实例 可以额外加载类成员变量的引用类
启动阶段抑制GC

  • CPU锁频

启动速度模拟面试
1)你做启动优化是怎么做的?

  • 分析现状、确认问题。(目前启动流程复杂,主线程执行了太多的代码)
  • 针对性优化(实现异步初始化)简单异步 指向了启动器。
  • 长期保持优化效果。

2)是怎么异步的,异步遇到问题没有?

  • 异步演进过程
  • 详细介绍启动器

3)有哪些容易忽略的点?

  • cpu time 和 wall time。
  • 注意延迟初始化的优化
  • 介绍黑科技,类加载。Systrace 可能没有给满的CPU,拉高CPU。

4)版本迭代导致的启动变慢有好的解决方式吗?

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

推荐阅读更多精彩内容