1故事的起因
程序猿自古以來和產品汪就是一段悲慘的孽緣偿曙,經(jīng)歷了千百年的風吹雨打,他們還是堅強的“在一起”罩阵,也許這就是“愛”,由恨生愛的“愛”幽钢,簡單愛的“愛”傅是,羅密歐對朱麗葉的“愛”...
話說喧笔,那是一個沉悶而太陽高照的下午,產品汪坐在一個程序猿的旁邊溃斋,只見臺面上擺著各種道具梗劫,水果刀、砍柴刀...不對蛉威,是Macbook走哺、鍵盤丙躏、鼠標,還有那臺27寸的顯示器...
程序猿抖著腳栅盲,深情的望著坐在旁邊的產品汪废恋,而產品汪則手指著桌面上的一部殘破并且古老的Android手機。
故事拟烫,就這么發(fā)生了...
2故事的開始
“不是硕淑,你到底想怎樣啊?需求和UI都按你說的做完了啊曹阔,現(xiàn)在還在嘰嘰歪歪的干哈霸叻荨?纠永!”程序猿飆出一段質問產品汪的話谒拴,產品汪沉穩(wěn)的指著手機英上,“沒錯,是做完了惭聂,但是你看下這個界面相恃,滑動一下拦耐,你不覺得頓卡頓卡的嗎?還有這個幽邓、那個...”火脉,“這不挺好的嗎?你的需求完美的實現(xiàn)了啊畸颅,就要付出這樣的代價啦方援,還想怎樣胺赶贰拳话?”程序猿抱怨著弃衍,“不行坚俗!一定要解決這個低端機卡頓的問題猖败,不然這個用戶體驗太差了!”產品汪非常果斷而堅決的說艺糜。
程序猿心里瞬間千萬只草泥馬飛奔而過,手握著桌面上的水果刀幢尚,額倦踢,不對,是鼠標...戴上耳機侠草,噼里啪啦啦的敲著鍵盤辱挥,開啟了改就改誰怕誰模式...但是心里默念著:小樣,小心有一天掉坑里去了...
3故事的經(jīng)過
注:以下都是程序猿的個人秀和心理變化歷程边涕,可能會引起某些人不適晤碘,但是還是堅持下去吧,sorry功蜓。
只見他打開最熟悉的開發(fā)工具Android Studio园爷,把手機插上式撼,“噔”童社,連接成功,打開親生孕育的APP著隆,滑了兩下扰楼,確實是有點卡啊,怎么剛開始就虛了啊美浦。讓我好好瞧瞧弦赖。
打開對應的界面xml文件和代碼文件,一看浦辨,這是哪個傻*寫的代碼啊蹬竖,ListView的convertView都沒復用,每次都重新繪制了一次,也沒用ViewHolder币厕,這圖片加載也沒異步處理列另,而且還全加載了大圖,讓我再滑一下旦装,滑動過程還繼續(xù)加載圖片啊页衙,你當Android手機是超級計算器啊同辣?拷姿!
不對惭载,這好像是我自己寫的啊旱函,當時因為快下班了,急急忙忙就寫了描滔,忘記優(yōu)化了啊棒妨,被這該死的產品汪抓到把柄了!以后不管項目時間多趕都不能把代碼寫得那么爛才行含长,來吧券腔,趕緊優(yōu)化一下吧...
嗯,這樣看起來就舒服多了嘛(圖片異步加載可使用第三方圖片加載庫如Glide拘泞,這里就忽略了哈)纷纫。
來,跑上去看下陪腌。嗯...確實好了挺多了辱魁,咦,不對啊诗鸭,怎么感覺還是有點卡頓染簇,該優(yōu)化的我也優(yōu)化了啊,還有哪呢强岸?
是不是布局層級太深了岸凸?讓我打開手機開發(fā)者設置里的GPU過度繪制看下蝌箍,我了個天青灼,打開之后一片深紅深紅的...
注:
1、原色 – 沒有被過度繪制– 繪制了兩次妓盲。
2聚至、藍色 – 1次過度繪制 – 繪制了兩次。
3本橙、綠色 – 2次過度繪制 – 繪制了三次扳躬。
4、粉色 – 3次過度繪制 – 繪制了四次。
5贷币、紅色 – 4次過度繪制 – 繪制了四次以上击胜。
深呼吸...繼續(xù)吧,革命尚未成功役纹,讓我想想有哪些可以優(yōu)化的點呢偶摔?
布局優(yōu)化呢,要減少層級促脉、減少測量和繪制時間辰斋,并且提高View的復用性。
要達到這幾點瘸味,可以通過如下方法:
合理使用RelativeLayout和LinerLayout宫仗,怎么個合理使用呢?
RelativeLayout比LinearLayout慢旁仿,是因為它會讓子View調用2次measure過程藕夫,而LinearLayout只需一次,但是有weight屬性存在時枯冈,LinearLayout也需要兩次measure毅贮;
RelativeLayout的子View如果高度和RelativeLayout不同,會導致RelativeLayout在onMeasure()方法中做橫向測量時尘奏,縱向的測量結果尚未完成滩褥,只好暫時使用自己的高度傳入子View系統(tǒng)。而父View給子View傳入的值也沒有變化就不會做無謂的測量的優(yōu)化會失效炫加,可以使用padding代替margin以優(yōu)化瑰煎;
在不響應層級深度的情況下,使用Linearlayout而不是RelativeLayout琢感。
學會使用Merge丢间,可以刪減多余的層級,merge多用于替換FrameLayout或者當一個布局包含另一個時驹针,merge標簽消除視圖層次結構中多余的視圖組烘挫。例如你的主布局文件是垂直布局,引入了一個垂直布局的include柬甥,這是如果include布局使用的LinearLayout就沒意義了饮六,使用的話反而減慢你的UI表現(xiàn)。
使用 ViewStub苛蒲,它是一個看不見的卤橄、不占布局位置、占用資源非常小的視圖對象臂外,提高顯示的速度窟扑。
ViewStub最大的優(yōu)點是當你需要時才會加載喇颁,使用他并不會影響UI初始化時的性能。各種不常用的布局想進度條嚎货、顯示錯誤消息等可以使用ViewStub橘霎,以減少內存使用量,加快渲染速度殖属。ViewStub是一個不可見的姐叁,大小為0的View。
使用include標簽來提高View布局的復用性洗显。
盡可能少用wrap_content外潜。wrap_content 會增加布局 measure 時計算成本,在已知寬高為固定值時挠唆,不用wrap_content 处窥。
刪除控件中無用的屬性。
還有就是界面的避免過度繪制损搬。
移除 XML 中非必須的背景碧库,移除 Window 默認的背景柜与、按需顯示占位背景圖片巧勤。
使用自定義View,使用 canvas.clipRect()來幫助系統(tǒng)識別那些可見的區(qū)域弄匕,只有在這個區(qū)域內才會被繪制颅悉。
對了,還有要保持合理的一個刷界面的機制迁匠,避免頻繁的刷新剩瓶,還應該盡量避免將其他處理放在主線程中,比如特別復雜的數(shù)據(jù)計算和網(wǎng)絡請求等城丧。
想都想好了延曙,是時候展示一波了啊亡哄!
不對枝缔,好像還差點啥的。
用什么工具來分析呢蚊惯?
NO.1 Profile GPU Rendering
在手機開發(fā)者模式下愿卸,有一個卡頓檢測工具叫做:Profile GPU Rendering,如圖:
它的功能特點如下:
一個圖形監(jiān)測工具截型,能實時反應當前繪制的耗時趴荸;
橫軸表示時間,縱軸表示每一幀的耗時宦焦;
隨著時間推移发钝,從左到右的刷新呈現(xiàn)顿涣;
提供一個標準的耗時,如果高于標準耗時酝豪,就表示當前這一幀丟失园骆。
NO.2 TraceView
TraceView 是 Android SDK 自帶的工具,用來分析函數(shù)調用過程寓调,可以對 Android 的應用程序以及 Framework 層的代碼進行性能分析锌唾。它是一個圖形化的工具,最終會產生一個圖表夺英,用于對性能分析進行說明晌涕,可以分析到每一個方法的執(zhí)行時間,其中可以統(tǒng)計出該方法調用次數(shù)和遞歸次數(shù)痛悯,實際時長等參數(shù)維度余黎。
NO.3 Systrace UI 性能分析
Systrace 是 Android 4.1及以上版本提供的性能數(shù)據(jù)采樣和分析工具,它是通過系統(tǒng)的角度來返回一些信息载萌。它可以幫助開發(fā)者收集 Android 關鍵子系統(tǒng)惧财,如 surfaceflinger、WindowManagerService 等 Framework 部分關鍵模塊扭仁、服務垮衷、View系統(tǒng)等運行信息,從而幫助開發(fā)者更直觀地分析系統(tǒng)瓶頸乖坠,改進性能搀突。Systrace 的功能包括跟蹤系統(tǒng)的 I/O 操作、內核工作隊列熊泵、CPU 負載等仰迁,在 UI 顯示性能分析上提供很好的數(shù)據(jù),特別是在動畫播放不流暢顽分、渲染卡等問題上徐许。
NO.4 HierarchyViewer
HierarchyViewer工具可以查看當前界面的View的層級關系,使用它可以清晰明了的查看到當前界面有哪些View是多余的卒蘸,當然也要結合布局XML文件來分析啦雌隅。
OJBK了,開始展現(xiàn)實力的時候到了P3尾健!
優(yōu)化過程會導致觀看的不適和泌,所以忽略了啊村缸,敬請原諒,不原諒也沒啥武氓,就這么著了梯皿,哈哈仇箱!
4故事的尾聲
“我就說你可以嘛,你看东羹,這不就流暢多了啊剂桥,之前還那么多抱怨啊...”產品汪露出了他那鋒利的鋼牙,程序猿貌似感覺到了接下來肯定又沒啥好事發(fā)生了属提。
“來來來权逗,咱們過來看看這個需求...”
To Be Continue...