最近看完了《Android開發(fā)藝術(shù)探索》這本書沈跨,這里算是一個筆記幾率,算是加深一遍記憶诀紊,首先是性能優(yōu)化的幾個方法
- 布局優(yōu)化
- 繪制優(yōu)化
- 內(nèi)存泄漏優(yōu)化
- 響應(yīng)速度優(yōu)化和ANR日志分析
- ListView和Bitmap優(yōu)化
- 線程優(yōu)化
- 一些性能優(yōu)化建議
布局優(yōu)化
優(yōu)化的思路就是盡量減少布局的層數(shù),下面是相應(yīng)的做法
刪除布局中沒有用的層級和控件隅俘,去掉過度的顏色繪制邻奠。
盡量少的采用性能較低的ViewGroup,能使用LinearLayout和FrameLayout的情況下不要去使用RelativeLayout(當(dāng)然,是在層級不會增加的時候,如果因為放棄用RelativeLayout而使層級變多的話那就得不償失了)
采用<merge>为居、<include>碌宴,<include>用來引入布局,當(dāng)被引入布局的最外層和引入位置(也就是include所在的父布局)是相同的布局時蒙畴,顯然有一層多余的布局,這時就用<merge>替換掉被引入布局的最外層贰镣。
-
采用ViewStub,用ViewStub引入某個布局
<ViewStub android:id="@+id/view_stub_left" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout="@layout/item_translation_left" android:inflatedId="@+id/import_layout"/>
其中view_stub_left是ViewStub的id,import_layout是引入布局的根元素id,如果要加載的話可以用setVisibility或者inflate膳凝,ViewStub就會被引入的布局替換掉碑隆,這里要注意的是ViewStub目前還不支持<merge>標(biāo)簽。
使用ConstraintLayout約束布局蹬音,這是一個為了解決嵌套層數(shù)而設(shè)計出來的布局上煤,用法也很簡單,在可視化界面將控件拖入框內(nèi)著淆,控制各種相對條件劫狠。具體可以看這篇文章拴疤。
繪制優(yōu)化
繪制優(yōu)化主要是注意onDraw方法,因為此方法可能頻繁調(diào)用独泞。所以在此方法里不要做創(chuàng)建對象和耗時任務(wù)的操作呐矾,盡量降低onDraw方法的復(fù)雜度。
內(nèi)存泄漏優(yōu)化
內(nèi)存泄漏在開發(fā)過程中是一個需要重視的問題懦砂,但是由于內(nèi)存泄漏問題對開發(fā)人員的經(jīng)驗和開發(fā)意識有較高的要求蜒犯,因此這也是開發(fā)人員最容易犯的錯誤之一。
想要解決這個問題有兩方面:
-
在開發(fā)過程避免寫出有內(nèi)存泄漏的代碼孕惜,下面列舉幾個開發(fā)中要注意的點愧薛。
- 頻繁使用不必要的靜態(tài)變量,使用的靜態(tài)對象持有大的引用比如activity衫画。
- 單例對象持有activity毫炉,比如單例對象的監(jiān)聽回調(diào)是activity繼承的,注冊監(jiān)聽時把activity傳了進去削罩,如果沒有解注冊這一步瞄勾,那activity就會一直存在,從而導(dǎo)致內(nèi)存泄漏弥激。
- 屬性動畫無限循環(huán)的模式下进陡,在onDestory中沒有去停止,此時動畫雖然看不見了微服,但是卻依然在播放趾疚,而且此動畫持有的上下文對象也不會被釋放,從而導(dǎo)致內(nèi)存泄漏以蕴。
- 在適用Handler發(fā)送延遲消息時糙麦,在onDestory中沒有清除消息,很多時候丛肮,我們關(guān)閉頁面之后Handler已經(jīng)不需要接收消息了赡磅,但是延遲消息還在隊列里。這個消息包含了Handler的引用宝与。而很多人使用Handler的時候都是匿名類方式焚廊,導(dǎo)致Handler持有當(dāng)前activity對象,因此同樣造成了內(nèi)存泄漏习劫。
通過分析工具比如LeakCanary咆瘟、BlockCanaryEx來找出內(nèi)存泄漏的點,然后解決诽里。
響應(yīng)速度優(yōu)化以及ANR日志分析
響應(yīng)速度優(yōu)化的思路就是在主線程避免耗時操作搞疗,耗時操作要放到子線程中處理,其實就是異步。這兩個放到一起匿乃,也是因為桩皿,響應(yīng)速度和ANR有關(guān),當(dāng)activity在5秒內(nèi)沒有響應(yīng)時幢炸,或者BroadcastReceiver在10秒內(nèi)未執(zhí)行完操作時也會產(chǎn)生ANR泄隔。
ANR產(chǎn)生以后直接從代碼是很難發(fā)現(xiàn)原因的,要定位問題需要分析一個系統(tǒng)輸出的文件宛徊,系統(tǒng)會在/data/anr目錄下創(chuàng)建一個traces.txt的文件里面有具體產(chǎn)生ANR的原因佛嬉,通過分析該文件就能找到問題所在。
ListView和Bitmap優(yōu)化
ListView的優(yōu)化主要是三點:
1. 采用ViewHolder進行復(fù)用闸天,并且避免在getView里面進行耗時操作
2. 要根據(jù)滑動狀態(tài)控制任務(wù)執(zhí)行的頻率暖呕,滑動快時用戶其實是看不到頁面上的內(nèi)容的,這時高頻率的異步加載其實很沒有必要苞氮。
3. 開啟硬件加速使滑動更流暢湾揽。這里簡單說一下硬件加速到底是干嘛,我們手機里有CPU(中央處理器)和GPU(圖形處理器)兩個處理器笼吟,兩者擅長的計算不同库物,前者主要解釋計算機指令,后者主要是圖形計算贷帮。開啟硬件加速就是將CPU不擅長的圖形計算轉(zhuǎn)換成GPU指令由GPU來完成戚揭。
Bitmap優(yōu)化主要就是通過BitmapFactory.Options來根據(jù)加載需要對圖片進行采樣,避免過度加載撵枢。
線程優(yōu)化
主要思路是避免程序中存在大量線程民晒,具體就是采用線程池來管理線程,避免頻繁創(chuàng)建和銷毀帶來的不必要的消耗锄禽。
一些性能優(yōu)化建議
- 避免創(chuàng)建過多的對象
- 不要過多的使用枚舉潜必,枚舉占用的內(nèi)存空間要比整形大
- 常量請適用static final來修飾
- 使用一些Android特有的書記結(jié)構(gòu),比如SparseArray和Pair等沟绪,它們都具有更好的性能
- 適當(dāng)適用軟引用和弱引用
- 采用內(nèi)存緩存和磁盤緩存
- 盡量采用靜態(tài)內(nèi)部類刮便,這樣可以避免潛在的由于內(nèi)部類而導(dǎo)致的內(nèi)存泄漏