activity 的優(yōu)化算是一個(gè)重點(diǎn)吧聚唐,activity 的啟動(dòng)本來(lái)就是挺耗時(shí)的丐重,我們需要優(yōu)化的是那種啟動(dòng)極其耗時(shí)的,比如啟動(dòng)新 activity 杆查,會(huì)讓用戶看 1秒多的黑屏扮惦,這就不好的了,可能不是所有的朋友的會(huì)碰到這個(gè)問(wèn)題亲桦,產(chǎn)生這樣的 activity 原因時(shí)多種多樣的崖蜜,根本原因則是:
- 上個(gè)頁(yè)面的 handle 任務(wù)沒(méi)有銷毀
- activity 啟動(dòng)中有大量非系統(tǒng)耗時(shí)任務(wù)
- activity xml 布局非常復(fù)雜,渲染界面很耗時(shí)
不管大家寫的怎么樣客峭,基本就是這幾個(gè)原因會(huì)造成 activity 啟動(dòng)慢
我們先來(lái)看看一個(gè)經(jīng)典的圖豫领,activity 和 view 的渲染過(guò)程
新界面啟動(dòng),先執(zhí)行 activity 3個(gè)初始化生命周期函數(shù)舔琅,執(zhí)行完之后才會(huì)對(duì)界面元素 view 執(zhí)行測(cè)量等恐,繪制,渲染备蚓,這時(shí)我們才能看到實(shí)際界面內(nèi)容课蔬,然后還會(huì)執(zhí)行 activity 啟動(dòng)動(dòng)畫(huà)
上面的任何任務(wù)卡頓都會(huì)造成,我們延遲看到頁(yè)面
解決思路
1. handle 問(wèn)題
對(duì)于handle 問(wèn)題郊尝,我們可以用 StallBuster 工具查看頁(yè)面啟動(dòng)時(shí) handle 系統(tǒng)任務(wù)棧的情況购笆,比如下圖就是 handle 任務(wù)沒(méi)有清空,影響下個(gè)頁(yè)面啟動(dòng)
所以我們?cè)陧?yè)面關(guān)閉或是不顯示時(shí)虚循,該關(guān)的一定要關(guān)
2. xml 布局效率
xml 布局層級(jí)一定要精簡(jiǎn)同欠,要不真的非常耗時(shí)的,我碰到過(guò)自己寫的 xml 耗時(shí) 1秒多的 ~
這里我們可以用 Hierarchy Viewer 工具 查看 xml 布局效率横缔,用 ConstraintLayout 約束布局 來(lái)減少xml 層級(jí)铺遂,遵照Android UI性能優(yōu)化實(shí)戰(zhàn) 的思路,去掉不必需要的背景茎刚,減少過(guò)度繪制
3. 延遲操作
activity 的 oncreate 我們一箱習(xí)慣寫各種初始化操作的襟锐,但是很多時(shí)候這里面就有耗時(shí)操作,所有我們可以 activity 頁(yè)面渲染完畢再去做這些初始化操作及其后面的獲取數(shù)據(jù)的操作
activity 的延遲操作有2個(gè)思路:
private Handler myHandler = new Handler();
private Runnable mLoadingRunnable = new Runnable() {
@Override
public void run() {
updateText(); //更新UI線程
}
};
getWindow().getDecorView().post(new Runnable() {
@Override
public void run() {
myHandler.post(mLoadingRunnable);
}
});
這2種寫法有區(qū)別嗎膛锭,有粮坞,而且很大蚊荣。系統(tǒng) UI 線程的所有操作都是通過(guò)在 handle 里面添加任務(wù)執(zhí)行的,當(dāng)我們?cè)谡l(shuí)的初始化時(shí)添加 handle 任務(wù)莫杈,就是表示在誰(shuí)的渲染之后執(zhí)行
- 寫法1 表示在 activity 的初始化完成后執(zhí)行任務(wù)互例,也就是 onresume 之后執(zhí)行
- 寫法1 表示在 view 控件的初始化完成后執(zhí)行任務(wù),也就是 view 顯示之后執(zhí)行
大家可以看 trace 圖
可以明顯的看到寫法1 的 handle 任務(wù)是在 rootviewimpl 渲染 view 之前執(zhí)行的