最近遇到一個很奇怪的問題,團(tuán)隊開發(fā)的app在一般安卓手機(jī)上運行正常,但是在華為榮耀8、nova青春版這兩款手機(jī)中卻異??D,系統(tǒng)均是android 7.0。其中主頁面及重要的頁面耗時多達(dá)5s,簡直不能忍受。
真的有無從下手的感覺。首先能想到的是對比競品或其他第三方app,然并卵,其他app表現(xiàn)正常,運行流暢。這app卡頓的鍋就不能甩給華為的android系統(tǒng)了。
接著去找華為終端的同學(xué)求救,收獲了。。。的回復(fù)。他建議我看下trace分析卡頓原因,腦袋突然不靈光的我質(zhì)問:都沒有產(chǎn)生anr,沒有traces.txt產(chǎn)生?。。?!還好后來想起他說的是性能分析的traceview,這才踏上正軌開始分析問題。

打開Android Device Monitor開始分析關(guān)鍵頁面啟動的耗時,使用方法我就不介紹了,網(wǎng)上都可以找到。上圖就是抓到的一個trace文件,可以看到排名靠前的耗時都是系統(tǒng)方法,Handler,LayoutInflater,updateConfiguration等。挨個檢查靠前方法的parent,children調(diào)用,終于在Resources.updateConfiguration這處發(fā)現(xiàn)了不尋常的地方。
可以看到Parents的三處調(diào)用,都是我們項目工程自定義的Activity。觀看源碼,均重寫了getResource方法,代碼如下:
/**
* 重寫此方法目的是app不隨系統(tǒng)字體變化
* @return Resources
*/
@Override
public Resources getResources() {
Resources res = super.getResources();
Configuration config = new Configuration();
config.setToDefaults();
res.updateConfiguration(config, res.getDisplayMetrics());
return res;
}
根據(jù)前人注釋可知,這段代碼是為了保證app的字體不隨系統(tǒng)字體的變化而變化,這也是網(wǎng)上常見的解決方案。為了確定是否是這段代碼導(dǎo)致app界面啟動卡頓,我將代碼注釋后重新編譯運行。運氣不錯,界面啟動速度從5s下降到了700毫秒左右,這段代碼竟然是卡頓的元兇。
確實updateConfiguration是耗時的操作,尤其在華為榮耀8,nova的手機(jī)上。getResource在界面繪制時頻繁調(diào)用,導(dǎo)致updateConfiguration調(diào)用的太頻繁。解決的思路就是減少updateConfiguration的調(diào)用次數(shù)。
根據(jù)系統(tǒng)更改字體大小的原理可知,android通過修改Configuration的fontScale的數(shù)值來實現(xiàn)字體大小的變化。正常字體大小的fontScale為1??芍v上述代碼優(yōu)化為如下代碼:
@Override
public Resources getResources() {
Resources res = super.getResources();
if (res.getConfiguration().fontScale != 1) {//非默認(rèn)值
Configuration newConfig = new Configuration();
newConfig.setToDefaults();//設(shè)置默認(rèn)
res.updateConfiguration(newConfig, res.getDisplayMetrics());
}
return res;
}
經(jīng)過測試,該方案的界面啟動速度也維持在700毫秒左右。經(jīng)過這個小小的改動,界面啟動速度從5s-》700毫秒,收益時巨大的。后續(xù)也會花時間繼續(xù)優(yōu)化界面的啟動速度,traceView工具用起來!
參考文檔:
Android系統(tǒng)字體大小如何影響app的字體大???
Android 解決APP字體隨系字體大小改變造成的布局錯位問題。
關(guān)于網(wǎng)上解決Android4.x系統(tǒng)設(shè)置字體大小導(dǎo)致應(yīng)用布局混亂引起的問題