Android 车载性能优化-启动优化
统计启动耗时统计
adb shell 命令
PS C:\Users\EDY> adb shell pidof com.autolink.launcher
2975
PS C:\Users\EDY> adb shell kill 2975
/system/bin/sh: kill: 2975: Operation not permitted
PS C:\Users\EDY> adb root
restarting adbd as root
PS C:\Users\EDY> adb shell kill 2975
PS C:\Users\EDY> adb shell am start -W com.autolink.launcher/com.autolink.launcher.MainActivity
Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.autolink.launcher/.MainActivity }
Status: ok
LaunchState: WARM
Activity: com.autolink.launcher/.MainActivity
TotalTime: 3098
WaitTime: 3101
Complete
PS C:\Users\EDY>
需要关注的数据为 TotalTime 、WaitTime
- TotalTime 所有 Activity 启动耗时
- WaitTime AMS 启动 Activity 的耗时
adb 命令只能线下使用,不能带到线上,获取的耗时并非严谨精确
手动打点
// 在 attachBaseContext 中记录开始时间
override fun attachBaseContext(base: Context?) {
super.attachBaseContext(base)
LauncherTime.startTime()
}
// 在 MainActivity 中的 onWindowFocusChanged 中记录结束时间
override fun onWindowFocusChanged(hasFocus: Boolean) {
super.onWindowFocusChanged(hasFocus)
LauncherTime.endTime("onWindowFocusChanged")
}
结束时间,更准确的地方应该是 Feed 的第一帧 addOnDrawListener,这个值比在 onWindowFocusChanged要大,为了方便就在 onWindowFocusChanged中记录结束时间
花费时间为 onWindowFocusChanged costTime = 3494
- 埋点方式获取的数据比 adb 要准确
- 埋点方式可以在线上使用
工具选择 traceView & profile
traceview
Debug.startMethodTracing("App") Debug.stopMethodTracing() 生成文件在 sd 卡:Android/data/packagename/files
方式一:Executors.newFixedThreadPool
正常在
Application中初始化
NaviApplication.onCreate(this)
CarSdkManager.init(this)
CarHelper.init(this)
UserLockHelper.init(this)
MMKV.initialize(this)
耗时为 :APP onCreate costTime = 305
采用 Executors 后时间为
// 根据机型核数来确定线程池大小
val count = Runtime.getRuntime().availableProcessors()
val corePoolSize = 2.coerceAtLeast((count - 1).coerceAtMost(4))
val execute = Executors.newFixedThreadPool(corePoolSize)
execute.submit { NaviApplication.onCreate(this) }
execute.submit { CarSdkManager.init(this) }
execute.submit { CarHelper.init(this) }
execute.submit { UserLockHelper.init(this) }
execute.submit { MMKV.initialize(this) }
耗时为 :APP onCreate costTime = 50
Q:以上初始化放到一个 submit 中是否可行?
A:如果放到一个 submit 中,就只使用了一个线程去完成异步任务,其余的线程闲置。
方式二:利用 CountDownLatch 控制初始化
val countDownLatch = CountDownLatch(1)
execute.submit {
MMKV.initialize(this)
countDownLatch.countDown()
}
// 保证 MMkv 初始化完成
countDownLatch.await()