1 減少過渡繪制
1.1 怎么查看是否存在過度繪制?
我們可以通過手機(jī)設(shè)置里面的開發(fā)者選項(xiàng),打開Show GPU Overdraw的選項(xiàng),可以觀察UI上的Overdraw情況。

藍(lán)色,淡綠,淡紅,深紅代表了4種不同程度的Overdraw情況,我們的目標(biāo)就是盡量減少紅色Overdraw,看到更多的藍(lán)色區(qū)域
1.2 怎么解決過度繪制?
1.2.1 移除Window默認(rèn)的Background
在onCreate方法中加入,getWindow().setBackgroundDrawable(null);
1.2.2 移除XML布局文件中非必需的Background
1.2.3 自定義 View 時(shí)重寫 hasOverlappingRendering 方法返回false。
該方法用來標(biāo)記當(dāng)前view是否存在過度繪制,存在返回ture,不存在返回false,默認(rèn)返回為true。
當(dāng)繼承了hasOverlappingRendering()方法返回false后,android會自動進(jìn)行合理的優(yōu)化,避免使用offscreen buffer。
2 布局優(yōu)化
2.1 減少布局的嵌套層級
可以hierarchyviewer去看布局的嵌套層級
原則:
1,用RelativeLayout減少嵌套的層級。
2,同等層級情況下可以實(shí)現(xiàn)的選用LinearLayout而不是RelativeLayout。
2.2 當(dāng)某些UI滿足某種條件才顯示復(fù)雜UI就用ViewStub
在開發(fā)過程中,經(jīng)常會遇到這樣一種情況,有些布局很復(fù)雜但是卻很少使用。例如條目詳情、進(jìn)度條標(biāo)識或者未讀消息等,這些情況如果在一開始初始化,雖然設(shè)置可見性 View.GONE ,但是在Inflate的時(shí)候View仍然會被Inflate,仍然會創(chuàng)建對象,由于這些布局又想到復(fù)雜,所以會很消耗系統(tǒng)資源。
ViewStub就是為了解決上面問題的,ViewStub是一個(gè)輕量級的View,它一個(gè)看不見的,不占布局位置,占用資源非常小的控件。
2.3 有些大像素有規(guī)律的圖片用.9去代替
2.4 去掉無用的UI
2.5 合并布局,用TextView代替圖片加文字
3 分析代碼耗時(shí)情況
可以通過traceview去分析代碼的耗時(shí)情況。
traceView雖然很牛逼。但是網(wǎng)上大部分文章都是淺淺說一下。
經(jīng)過這段時(shí)間不段試錯,整理一個(gè)可行的套路。
套路開始:
3.1 生成.trace 文件
首先肯定生成用TraceView生成.trace文件。
生成.trace文件是方式有兩種。
3.1.1 在DDMS工具中生成
最常用的使用方式
1,選擇到DDMS界面,選擇要檢測耗時(shí)的進(jìn)程,比如我的就是com.android.dialer

2,點(diǎn)擊采集如下圖

會出現(xiàn)這樣的對話框(這個(gè)就是多長時(shí)間采集一次數(shù)據(jù)),點(diǎn)擊ok即可。

這時(shí)候開啟采集按鈕會編程停止采集的按鈕(帶黑色正方形)

3,在手機(jī)執(zhí)行你檢測耗時(shí)的操作。比如:我想測試最近通話和聯(lián)系人Tab的切換耗時(shí)。就去手動去不斷去切換Tab界面或者也可以用腳本
4,執(zhí)行完操作后,點(diǎn)擊停止采集的按鈕(帶黑色正方形)停止采集,就會生成.trace文件,如下圖:

3.1.2 在代碼中用代碼設(shè)置開始采集的點(diǎn)和停止采集的點(diǎn)
比如應(yīng)用的冷啟動,進(jìn)程還沒有出現(xiàn)是無法選擇進(jìn)程的。比如界面跳轉(zhuǎn)的耗時(shí)情況想精確到哪里開啟采集,哪里結(jié)束采集。就需要在代碼中用代碼設(shè)置。
下面以冷啟動舉個(gè)栗子
1,設(shè)置開始采集點(diǎn)--Debug.startMethodTracing();
在Application的onCreate()方法中寫上Debug.startMethodTracing();為開始采集

2,設(shè)置結(jié)束采集點(diǎn) -- Debug.stopMethodTracing();
我們就在主界面顯示的時(shí)候設(shè)置采集結(jié)束點(diǎn),可以在onResume的末尾,也可以在onWindowFocusChanged參數(shù)出入為true的時(shí)候設(shè)置結(jié)束點(diǎn)。

3,運(yùn)行代碼,生成.trace文件
那么.trace文件在哪里呢?
只可能在兩個(gè)地方。
一就是在SD根目錄

二就是在/sdcard/Android/data/包名/files/dmtrace.trace
4.取出來。相信大家都會。
注意:不采集了要把Debug.startMethodTracing();和Debug.stopMethodTracing();刪掉。
3.2 打開.trace 文件
打開.trace文件也有兩種方式:
3.2.1 在Eclipse上打開(建議你忘記這種方式)
為什么要忘記這種方式?
因?yàn)檫@個(gè)搜索用不了。

如果搜索用不了,那么3.3的快速找到耗時(shí)的方法就就進(jìn)行不了。但是還是能找到耗時(shí)的方法的。但是就是體力活,說得更準(zhǔn)確一點(diǎn)就是眼力活,我保證看到你想哭。所以忘記這樣方式吧。
3,.2.2 用命令打開(推薦)
1,怎么用命令打開?
把.trace 文件拷貝到\sdk\tools這個(gè)文件夾下。

1.trace(因?yàn)槲腋拿至硕眩?br> 在這文件夾打開命令行輸入 traceview.bat 1.trace (.trace的全名稱),如下圖

就打開了,如下圖

用命令打開有什么好處呢?當(dāng)然就是能搜索關(guān)鍵字?。∪缦聢D

但是在DDMS工具中生成.trace 文件默認(rèn)就是在Eclipse上打開的。怎么辦?
但是是找到這個(gè)DDMS生成的.trace 文件啊,但是在哪里呢?
鼠標(biāo)放在這塊區(qū)域,

看到?jīng)]有,在這路徑下。

就在這里了。最好點(diǎn)擊修改日期排序,第一個(gè)就你要找的文件了。

3.3 快速找到耗時(shí)的方法
打開了,最重要的一步來了。這段時(shí)間的試錯主要是在哪里試錯,怎么快速找到耗時(shí)方法,而不是有了traceView還得用眼睛一行行去看,這是要累死人的節(jié)奏啊。

圈中的從左到右
Name :該線程運(yùn)行過程中所調(diào)用的函數(shù)名
Incl Cpu Time %: 某函數(shù)占用的CPU時(shí)間,包含內(nèi)部調(diào)用其它函數(shù)的CPU時(shí)間的百分比
Incl Real Time : 某函數(shù)運(yùn)行的真實(shí)時(shí)間(以毫秒為單位),內(nèi)含調(diào)用其它函數(shù)所占用的真實(shí)時(shí)間
Call+Recur Calls/Total:某函數(shù)被調(diào)用次數(shù)以及遞歸調(diào)用占總調(diào)用次數(shù)的百分比
Real Time/Call: 同CPU Time/Call類似,只不過統(tǒng)計(jì)單位換成了真實(shí)時(shí)間
這上面是五個(gè)列是最重要的。其他列沒有什么作用,為了不受影響,我們把這個(gè)五個(gè)列放到一起。

這樣就可以排除干擾列了,同時(shí)又有更大的空間看清楚Name列的函數(shù)名。
然后呢?
還記得Incl Real Time這列嗎?這列就是函數(shù)的耗時(shí)時(shí)間。
我們就讓這列的耗時(shí)時(shí)間從大到小排列。
點(diǎn)一下列名,就看到

函數(shù)的耗時(shí)時(shí)間從大到小排列了。
這樣有什么用?
這時(shí)候就用到搜索功能了。
舉個(gè)栗子

我就搜索com.andr(因?yàn)槲业陌莄om.android.dialer但是每一個(gè)類的命名都是以com.android.diaer開頭的,所以我搜索了com.andr盡量搜索多一下結(jié)果,再判斷是不是我程序的類)。
輸入com.andr,一個(gè)個(gè)回車,直到找到自己的類的

onPageScrolled這方法總耗時(shí)436ms,調(diào)用一次耗時(shí)1.857ms。
他的函數(shù)里面方法
getRtlPosition(position);總耗時(shí)175.106ms,占了百分之45.5
再看代碼。

這是viewpager的回調(diào)方法onPageScrolled,在切換的viewpager的時(shí)候會回調(diào)很多次。真的有必要在哪里判斷是不是從右到左的語言嗎?
所以改成:只要在onPageSelected的方法判斷就行了。這個(gè)方法在切換完成后只回調(diào)一次。

改完之后,運(yùn)行代碼。再traceView一下。對比是否改好了。
用命令打開,優(yōu)化的.trace 文件。
搜索onPageScrolled這個(gè)優(yōu)化后的代碼看總耗時(shí)和每次耗時(shí)多少。

很明顯看出來上面的沒有優(yōu)化前的被調(diào)用235次一共耗時(shí)436.367ms。每次調(diào)用1.857ms
和優(yōu)化后的被調(diào)用了319次才一共耗時(shí)279.367ms要小得多。每次調(diào)用1.721ms
接下就在原來的trace文件找耗時(shí)方法了。同上。
總結(jié) : 就是根據(jù)Incl Real Time進(jìn)行從耗時(shí)時(shí)間從長到短排序,然后搜索關(guān)鍵字符串,找屬于自己的代碼的耗時(shí)方法,優(yōu)化即可
注意:traceView寫的多少ms都不等同于代碼的執(zhí)行的真實(shí)時(shí)間。但是是代碼執(zhí)行真實(shí)時(shí)間的倍數(shù)。有可能是2倍,5倍,10倍什么的,但是一定具備參考意義。
關(guān)于這個(gè)套路和TraceView具體使用http://www.itdecent.cn/p/2ef139f5dfac