Android性能優(yōu)化
一,優(yōu)化內(nèi)容
布局優(yōu)化握玛、繪制優(yōu)化贮缅、內(nèi)存泄漏優(yōu)化改鲫、響應(yīng)速度優(yōu)化、ListView優(yōu)化瘟裸、Bitmap優(yōu)化弦疮、線程優(yōu)化…….
二,優(yōu)化方法
1)布局優(yōu)化:盡量減少布局文件的層級(jí)
?????? ·刪除布局中的無用層級(jí)和控件
?????? ·有選擇的使用性能較高的ViewGroup.如果RelativeLayout和LinearLayout都可以使用,那就使用LinearLayout,因?yàn)镽elativeLayout功能比較復(fù)雜,繪制需要花費(fèi)更多的CPU時(shí)間.FrameLayout和LinearLayout一樣的簡(jiǎn)單高效.當(dāng)一個(gè)LinearLayout或FrameLayout無法滿足需求,需要多層嵌套時(shí),建議使用RelativeLayout,因?yàn)槎鄬忧短紫喈?dāng)于增加了布局的層級(jí),會(huì)降低程序的性能
?????? ·合理使用標(biāo)簽.《merge》可以合并相同的布局文件诱建,比如一個(gè)豎直方向的LinearLayout里面嵌套另一個(gè)豎直方向的LinearLayout钮蛛,可以使用《merge》標(biāo)簽,可以減少一個(gè)層級(jí)受神∨撞《include》標(biāo)簽用于布局的重用,指定的布局只支持layout開頭的屬性鼻听,且android:layout_width和android:layout_height必須存在财著。一般情況下沒《merge》和《include》配合使用【悖《ViewStub》是非常輕量級(jí)的控件,寬高都為0碎连,不參與任何布局的繪制灰羽,只有在使用的時(shí)候才會(huì)加載,提高了程序初始化的性能
2)繪制優(yōu)化
?????? ·onDraw中不要?jiǎng)?chuàng)建新的局部對(duì)象鱼辙,因?yàn)閛nDraw方法會(huì)被頻繁調(diào)用廉嚼,這樣會(huì)產(chǎn)生大量的臨時(shí)對(duì)象,導(dǎo)致占用過多的內(nèi)存倒戏,系統(tǒng)頻繁GC怠噪,降低程序的執(zhí)行效率
?????? ·onDraw方法中不要做耗時(shí)操作,也不能執(zhí)行次數(shù)較多的循環(huán)操作杜跷,因?yàn)榇罅康难h(huán)會(huì)搶占CPU的時(shí)間片傍念,導(dǎo)致繪制不流暢。
3)內(nèi)存泄露優(yōu)化(內(nèi)存泄露不會(huì)直接導(dǎo)致內(nèi)存溢出葛闷,但是會(huì)增加內(nèi)存溢出的概率
?????? ·靜態(tài)變量導(dǎo)致的內(nèi)存泄漏憋槐,靜態(tài)變量不正常使用會(huì)導(dǎo)致Activity無法正常銷毀
?????? ·單例模式導(dǎo)致內(nèi)存泄漏,單例模式的生命周期和Application一致,導(dǎo)致Activity對(duì)象無法及時(shí)釋放
4)響應(yīng)速度優(yōu)化
?????? ·避免在主線程中做耗時(shí)操作,如果無法避免,可以使用異步的方式執(zhí)行耗時(shí)操作.一般來講,如果主線程做太多的事情可能會(huì)導(dǎo)致Activity啟動(dòng)時(shí)出現(xiàn)黑屏,甚至出現(xiàn)ANR,對(duì)于Activity如果5s內(nèi)無法響應(yīng)事件,BroadCastReceiver10s無法完成操作均會(huì)出現(xiàn)ANR的情況.所以一定要避免在主線程中做耗時(shí)操作
5)ListView優(yōu)化
?????? ·采用ViewHolder并避免在getView中做耗時(shí)操作
?????? ·根據(jù)列表的滑動(dòng)狀態(tài)來控制執(zhí)行頻率,滑動(dòng)過快的時(shí)候不適合做大量的異步任務(wù)
?????? ·開啟硬件加速使滑動(dòng)更加的流暢
6)Bitmap優(yōu)化
?????? ·采用BitmapFactory.Option(進(jìn)行了采樣處理)加載圖片
????? ·采用緩存策略
7)線程優(yōu)化
?????? ·采用線程池,避免程序中存在大量的Thread
8)性能優(yōu)化
?????? ·避免創(chuàng)建過多的對(duì)象.任何對(duì)象創(chuàng)建都不是免費(fèi)的,每個(gè)線程的分代GC給臨時(shí)對(duì)象分配一個(gè)地址池以降低分配開銷,但是往往內(nèi)存分配要比不分配的代價(jià)大
?????? ·不要過多的使用枚舉,枚舉占用空間是整型的兩倍
?????? ·常量請(qǐng)使用static final 來修飾(不會(huì)進(jìn)行相應(yīng)的初始化,避免了冗余操作)
?????? ·使用Android特有的數(shù)據(jù)結(jié)構(gòu),比如SparseArray和Pair等
?????? ·適當(dāng)使用軟引用和弱引用
?????? ·采用內(nèi)存緩存和磁盤緩存
?????? ·盡量使用靜態(tài)內(nèi)部類,避免由于潛在的內(nèi)部類而出現(xiàn)內(nèi)存泄漏
9)代碼優(yōu)化(提高代碼的可維護(hù)性和可擴(kuò)展性)
???? ? ·命名要規(guī)范
???? ? ·排版要合理,預(yù)留合理的控件來區(qū)分不同的代碼塊
?????? ·為關(guān)鍵的代碼添加注釋
?????? ·代碼層次性要分明
10)其他優(yōu)化
?????? ·冒泡排序:原理簡(jiǎn)單,但是包含了很多沒有意義的比較換序操作,算法臃腫,效率不高;二分歸并排序和堆排序:充分利用比較結(jié)果,避免了冗余操作,效率較高
?????? ·盡量使用StringBuffer,讓函數(shù)值直接在其后面添加,如果使用String的話,每次使用都會(huì)創(chuàng)建一個(gè)新的臨時(shí)變量
?????? ·從輸入的數(shù)據(jù)集合中讀取數(shù)據(jù)時(shí),考慮返回原始數(shù)據(jù)的子串,而不是新建一個(gè)拷貝
?????? ·Int類型的數(shù)據(jù)效率比較高,兩個(gè)平行的Int數(shù)據(jù)要比一個(gè)(int,int)的對(duì)象數(shù)組高很多
?????? ·避免使用getter和setter.在c++中g(shù)etter和setter方法在調(diào)用的時(shí)候會(huì)被編譯器直接翻譯成相應(yīng)的字段訪問,帶來的額外的開銷,java也是相識(shí)的
?????? ·盡量使用增強(qiáng)for循環(huán),使用迭代器遍歷數(shù)據(jù),要比一般的迭代高效
?????? ·合理使用浮點(diǎn)數(shù),浮點(diǎn)數(shù)要比整型慢兩倍,運(yùn)算絕對(duì)速度大約相差10倍
?????? ·合理使用本地方法,本地方法不一定比java高效,java和native之間的關(guān)聯(lián)是有消耗的,分配本地資源的時(shí)候往往回收比較困難,有時(shí)候會(huì)針對(duì)相同的架構(gòu)編譯出不同的版本,不能充分利用手機(jī)的ARM
三,優(yōu)化總結(jié)
????? ·優(yōu)化體現(xiàn)在方方面面,不要認(rèn)為小就不去優(yōu)化,只有有好的優(yōu)化方法,一行代碼也不能放過
????? ·利用已有的規(guī)則將優(yōu)化最大化,使程序整體性能優(yōu)化
???? ·時(shí)間精力有限的情況下,不要為一些微不足道的優(yōu)化投入大量的精力