參考文章:Android性能優(yōu)化總結(jié)
android性能優(yōu)化典范
Android性能優(yōu)化的方向
1.復(fù)雜的布局
2.耗電量
3.內(nèi)存的占用
4.頻繁的網(wǎng)絡(luò)請求
5.代碼的執(zhí)行效率
一、復(fù)雜的布局影響:
復(fù)雜的布局會造成界面的過度繪制,過度繪制是指屏幕上的某一個像素點被多次繪制。例如我們有一些不可見或者沒有必要的布局,它也再做繪制操作(可以參考布局源碼)。這時就造成了GPU和CPU的流失。參考Android中RelativeLayout和LinearLayout性能分析線性布局和測量時間要比相對布局的測量時間快3倍左右,這是因為相對布局中的view依靠依賴關(guān)系進行了位置的擺放,所以在源碼中相對布局首先橫向測量一次子View然后縱向又測量了一次子view。
第一次是進行了橫向的測量,第二次進行了縱向的測量。
而線性布局的測量只進行了一次
根據(jù)設(shè)定的不同方向,進行不同的測量。
同時Relativelayout的測量方法還有一個問題:(摘抄自Android中RelativeLayout和LinearLayout性能分析)
View的measure方法里對繪制過程做了一個優(yōu)化,如果我們或者我們的子View沒有要求強制刷新,而父View給子View的傳入值也沒有變化(也就是說子View的位置沒變化),就不會做無謂的measure。但是上面已經(jīng)說了RelativeLayout要做兩次measure,而在做橫向的測量時,縱向的測量結(jié)果尚未完成,只好暫時使用myHeight傳入子View系統(tǒng),假如子View的Height不等于(設(shè)置了margin)myHeight的高度,那么measure中上面代碼所做得優(yōu)化將不起作用,這一過程將進一步影響RelativeLayout的繪制性能。而LinearLayout則無這方面的擔(dān)憂。解決這個問題也很好辦,如果可以,盡量使用padding代替margin。
測試過度繪制的方法:部分手機的開發(fā)者選項里有GPU測試這一選項。
GPU測試實例:
1.紅色位置采用的是相對布局。所以在布局的使用上推薦FrameLayout>LinearLaytou>Relativelayout
2.盡量減少沒有必要的布局嵌套
推薦測試工具:無線UIViewer—強烈推薦App工具,可在手機端直接實現(xiàn)HierarchyViewer的功能,查看任意界面的UI布局。
二、使用布局標簽優(yōu)化
include引入重復(fù)的布局。
當(dāng)多個頁面使用一種樣式的布局時,可以將重復(fù)的布局抽出來,單獨成立一個新的布局,當(dāng)其他布局需要的時候,可以使用include標簽引入進去。
merge合并布局
當(dāng)子布局和父布局是同一類型時,可以使用merge標簽作為子布局的布局標簽。解決布局重復(fù)的問題。
ViewStub
ViewStub是一個在加載前不可見的,并且可以延時加載的布局。ViewStub在不調(diào)用infalte方法,或visable方法前,它所指定的布局是不可見的。
<viewstub
id=test_viewstub
layout="@layout/test"
/>
ViewStub test=findviewbyId(R.id.test_viewstub);
if(可以顯示){
test.inflate();
}
影響耗電量的部分重要因素:
大量的數(shù)據(jù)傳輸
頻繁的網(wǎng)絡(luò)切換
長時間的后臺服務(wù)
某些方法在斷網(wǎng)情況下還不斷的去嘗試請求網(wǎng)絡(luò)。
參考android性能優(yōu)化典范和Android開發(fā)者文檔發(fā)現(xiàn),使用無線電波進行數(shù)據(jù)傳輸是最為耗電的,使用預(yù)取(prefetching),捆綁(bundle)的方式進行數(shù)據(jù)的傳輸,這些操作都是為了最小化電量的消耗,批量處理請求和根據(jù)網(wǎng)絡(luò)連接類型來處理來解決耗電量的問題
典型的 3G 無線電網(wǎng)絡(luò)有三種能量狀態(tài):
Full power:當(dāng)無線連接被激活的時候,允許設(shè)備以最大的傳輸速率進行操作。
Low power:一種中間狀態(tài),對電量的消耗差不多是 Full power 狀態(tài)下的50%。
Standby:最小的能量狀態(tài),沒有被激活或者需求的網(wǎng)絡(luò)連接。
也就是說我們在使用無線電波進行數(shù)據(jù)傳輸時,可能會在一下3種狀態(tài)下進行。每一個新建立的連接開始都處于Full Power狀態(tài)。這會相當(dāng)耗電。(關(guān)于無線電傳播數(shù)據(jù)具體內(nèi)容請閱讀http://www.research.att.com/articles/featured_stories/2011_03/201102_Energy_efficient?fbid=8xEDul3FFK0)
解決方式
1.預(yù)取數(shù)據(jù)方式:單詞連接以最大能力將用戶所有可能需要到的數(shù)據(jù)請求下來。個人理解為將數(shù)據(jù)請求下來后,保存到本地數(shù)據(jù)庫內(nèi),用戶再次進入app后,優(yōu)先閱讀本地保存的數(shù)據(jù),當(dāng)用戶需要請求最新的數(shù)據(jù)時,只比本地數(shù)據(jù)更新的數(shù)據(jù),這樣也可以有效的減少數(shù)據(jù)傳輸?shù)娜萘俊?br> 2.批量處理:參照android開發(fā)文檔給出的例子,我們可以將所有可能要請求的數(shù)據(jù)放在請求隊列,執(zhí)行請求隊列的任務(wù)時只發(fā)起一次無線電波進行請求,而不是發(fā)現(xiàn)有新的任務(wù)就發(fā)出無線電進行請求。
如何做到批處理呢:
使用Job Scheduler
1.首先定義一個JobService
下面是筆者結(jié)合googlesample寫的JobService的列子,JobServcie的工作是將日志統(tǒng)一收集后一并發(fā)送的工作。
2.定義要執(zhí)行的任務(wù),該任務(wù)在JobService中執(zhí)行
LogGroup里面裝的是配置好的日志信息,myLogStore負責(zé)把所有的日志上傳。里面是多個請求
3.將任務(wù)交給JobServcie
將任務(wù)交給JobService時需要配置一些信息,這些信息表示在滿足什么情況條件下執(zhí)行任務(wù)
JobInfo. Builder負責(zé)配置滿足的信息。schedule負責(zé)執(zhí)行任務(wù)。
使用ArrayMap和SparseArray代替HashMap
http://blog.csdn.net/u010687392/article/details/47809295
http://blog.csdn.net/u010687392/article/details/47809295