啟動(dòng)類型
冷啟動(dòng)
click event -> IPC -> Process.start -> ActivityThread -> bindApplication -> LifeCycle -> ViewRootImpl
熱啟動(dòng)
后臺 -> 前臺
溫啟動(dòng)
Lifecycle
啟動(dòng)相關(guān)任務(wù)
- 啟動(dòng)App
- 加載空白window
- 創(chuàng)建進(jìn)程
- 創(chuàng)建Application
- 啟動(dòng)主線程
- 創(chuàng)建MainActivity
- 加載布局
- 布置屏幕
- 首幀繪制
優(yōu)化方向
Application和Activity生命周期
啟動(dòng)時(shí)間的測量
方式1:adb命令(適合本地使用)
adb shell am start -W packagename/首屏Activity(含有包名)
JamesdeMBP:~ zhanxuzhao$ adb shell am start -W com.example.demo_0227/com.example.demo_0227.SplashActivity
Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.example.demo_0227/.SplashActivity }
Status: ok
Activity: com.example.demo_0227/.MainActivity
ThisTime: 123
TotalTime: 285
WaitTime: 304
Complete
ThisTime:最后一個(gè)Activity啟動(dòng)耗時(shí)(如MainActivity,不會包含前面的SplashActivity)
TotalTime:所有Activity啟動(dòng)耗時(shí)
WaitTime:AMS啟動(dòng)Activity總耗時(shí)
ThisTime < TotalTime < WaitTime
方式二:手動(dòng)打點(diǎn)(可以線上統(tǒng)計(jì))
開始點(diǎn):
Application#attachBaseContext()
結(jié)束點(diǎn):
方案一:首幀開始繪制(不推薦)
onWindowFocusChanged
方案二:真實(shí)數(shù)據(jù)展示(第一條feed加載:onBindViewHolder)
onBindViewHolder
holder.linearLayout.getViewTreeOvserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener(){
@Override
public boolean onPregraw(){
LaunchTimer.endRecord();
holder.linearLayout.getViewTreeObserver().removeOnPredrwaListener(this);
return true;}
}
性能檢測工具
traceview
Debug.startMethodTracing("fileName"); // 方法開始
Debug.stopMethodTracing(); // 方法結(jié)束
生成文件路徑:sdcard/android/data/packagename/files
image
特點(diǎn):
可以統(tǒng)計(jì)方法調(diào)用關(guān)系理澎、耗費(fèi)時(shí)間嗜逻。
缺點(diǎn):
運(yùn)行時(shí)開銷嚴(yán)重,整體都會變慢。
systrace
結(jié)合 Android 內(nèi)核數(shù)據(jù)尿贫, 生成 html 報(bào)告
TraceCompat.beginSection("section name");
TraceCompat.endSection();
特點(diǎn)
輕量級,開銷小个少。
直觀反映CPU利用率。