在Android應(yīng)用優(yōu)化方面荐虐,主要從以下4個(gè)方面進(jìn)行優(yōu)化:
- 穩(wěn)定(內(nèi)存溢出、崩潰)
- 流暢(卡頓)
- 耗損(耗電丸凭、流量福扬、網(wǎng)絡(luò))
- 安裝包(APK瘦身)
內(nèi)存優(yōu)化
由于Android應(yīng)用的沙箱機(jī)制,每個(gè)應(yīng)用所分配的內(nèi)存大小是有限度的惜犀,可用內(nèi)存太低就會(huì)觸發(fā)LMK(Low Memory Killer)機(jī)制铛碑,進(jìn)而會(huì)出現(xiàn)閃退現(xiàn)象。
分析工具
Memory Monitor
Memory Monitor是Android Studio自帶的一個(gè)內(nèi)存監(jiān)視工具虽界,它可以很好地幫助我們進(jìn)行內(nèi)存實(shí)時(shí)分析汽烦。通過點(diǎn)擊Android Studio右下角的Memory Monitor標(biāo)簽,打開工具可以看見較淺藍(lán)色代表free的內(nèi)存莉御,而深色的部分代表使用的內(nèi)存從內(nèi)存變換的走勢(shì)圖變換撇吞,可以判斷關(guān)于內(nèi)存的使用狀態(tài),例如當(dāng)內(nèi)存持續(xù)增高時(shí)礁叔,可能發(fā)生內(nèi)存泄漏牍颈;當(dāng)內(nèi)存突然減少時(shí),可能發(fā)生GC等晴圾。
Memory Analyzer
MAT 是一個(gè)快速颂砸,功能豐富的 Java Heap 分析工具,通過分析 Java 進(jìn)程的內(nèi)存快照 HPROF 分析死姚,從眾多的對(duì)象中分析人乓,快速計(jì)算出在內(nèi)存中對(duì)象占用的大小,查看哪些對(duì)象不能被垃圾收集器回收都毒,并可以通過視圖直觀地查看可能造成這種結(jié)果的對(duì)象色罚。
LeakCanary
LeakCanary是一個(gè)內(nèi)存監(jiān)測工具,該工具是Square公司出品的账劲,所謂Square出品必屬精品戳护,LeakCanary的官方地址為https://github.com/square/leakcanar金抡,我們可以在Gradle里引用它。
Android Lint
Android Lint 是Android Sutido種集成的一個(gè)Android代碼提示工具腌且,它可以給布局梗肝、代碼提供非常強(qiáng)大的幫助。如果在布局文件中寫了三層冗余的LinearLayout布局铺董,就會(huì)在編輯器右邊看到提示巫击。當(dāng)然這個(gè)是一個(gè)簡單的舉例,Lint的功能非常強(qiáng)大精续,大家應(yīng)該養(yǎng)成寫完代碼查看Lint的習(xí)慣坝锰,這不僅讓你及時(shí)發(fā)現(xiàn)代碼種隱藏的一些問題,更能讓你養(yǎng)成良好的代碼風(fēng)格重付。
交互優(yōu)化
交互是與用戶體驗(yàn)最直接的方面顷级,交互場景大概可以分為四個(gè)部分:UI 繪制、應(yīng)用啟動(dòng)确垫、頁面跳轉(zhuǎn)弓颈、事件響應(yīng)。對(duì)于上面四個(gè)方面森爽,大致可以從以下兩個(gè)方面來進(jìn)行優(yōu)化:
- 界面繪制:主要原因是繪制的層級(jí)深恨豁、頁面復(fù)雜、刷新不合理爬迟,由于這些原因?qū)е驴D的場景更多出現(xiàn)在 UI 和啟動(dòng)后的初始界面以及跳轉(zhuǎn)到頁面的繪制上。
- 數(shù)據(jù)處理:導(dǎo)致這種卡頓場景的原因是數(shù)據(jù)處理量太大菊匿,一般分為三種情況付呕,一是數(shù)據(jù)在處理 UI 線程,二是數(shù)據(jù)處理占用 CPU 高跌捆,導(dǎo)致主線程拿不到時(shí)間片徽职,三是內(nèi)存增加導(dǎo)致 GC 頻繁,從而引起卡頓佩厚。
Android的繪制需要經(jīng)過onMeasure姆钉、onLayout、onDraw等幾個(gè)步驟抄瓦,所以布局的層級(jí)越深潮瓶、元素越多、耗時(shí)也就越長钙姊。還有就是Android 系統(tǒng)每隔 16ms 發(fā)出 VSYNC 信號(hào)毯辅,觸發(fā)對(duì) UI 進(jìn)行渲染,如果每次渲染都成功煞额,這樣就能夠達(dá)到流暢的畫面所需的 60FPS思恐。如果某個(gè)操作花費(fèi)的時(shí)間是 24ms 沾谜,系統(tǒng)在得到 VSYNC 信號(hào)時(shí)就無法正常進(jìn)行正常渲染,這樣就發(fā)生了丟幀現(xiàn)象胀莹。
之所以出現(xiàn)卡頓現(xiàn)象基跑,是因?yàn)橛袃蓚€(gè)原因:
- 繪制任務(wù)太重,繪制一幀內(nèi)容耗時(shí)太長
- 主線程太忙描焰,根據(jù)系統(tǒng)傳遞過來的 VSYNC 信號(hào)來時(shí)還沒準(zhǔn)備好數(shù)據(jù)導(dǎo)致丟幀
基于問題產(chǎn)生的原因涩僻,我們可以從以下幾個(gè)方面進(jìn)行優(yōu)化:
布局優(yōu)化
在Android中系統(tǒng)對(duì)View進(jìn)行測量、布局和繪制時(shí)栈顷,都是通過對(duì)View樹的遍歷來進(jìn)行操作的逆日。如果一個(gè)View樹的高度太高就會(huì)嚴(yán)重影響測量、布局和繪制的速度萄凤。Google也在其API文檔中建議View高度不宜超過10層∈页椋現(xiàn)在版本中Google使用RelativeLayout替代LineraLayout作為默認(rèn)根布局,目的就是降低LineraLayout嵌套產(chǎn)生布局樹的高度靡努,從而提高UI渲染的效率坪圾。
在布局優(yōu)化方面,我們可以從以下幾個(gè)方面進(jìn)行優(yōu)化:
- 布局復(fù)用惑朦,使用
<include>
標(biāo)簽重用layout兽泄; - 提高顯示速度,使用
<ViewStub>
延遲View加載漾月; - 減少層級(jí)病梢,使用
<merge>
標(biāo)簽替換父級(jí)布局; - 注意使用wrap_content梁肿,會(huì)增加measure計(jì)算成本蜓陌;
- 刪除控件中無用屬性;
渲染優(yōu)化
過度繪制是指在屏幕上的某個(gè)像素在同一幀的時(shí)間內(nèi)被繪制了多次吩蔑。在多層次重疊的 UI 結(jié)構(gòu)中钮热,如果不可見的 UI 也在做繪制的操作,就會(huì)導(dǎo)致某些像素區(qū)域被繪制了多次烛芬,從而浪費(fèi)了多余的 CPU 以及 GPU 資源隧期。我們可以通過開啟手機(jī)的過渡繪制功能來檢測頁面是否被過度繪制。
為了避免過度繪制赘娄,我們可以從以下幾個(gè)方面進(jìn)行優(yōu)化:
- 布局上的優(yōu)化仆潮,移除 XML 中非必須的背景,移除 Window 默認(rèn)的背景擅憔、按需顯示占位背景圖片鸵闪。
- 自定義View優(yōu)化,使用 canvas.clipRect()來幫助系統(tǒng)識(shí)別那些可見的區(qū)域暑诸,只有在這個(gè)區(qū)域內(nèi)才會(huì)被繪制蚌讼。
啟動(dòng)優(yōu)化
應(yīng)用一般都有閃屏頁辟灰,優(yōu)化閃屏頁的 UI 布局,可以通過 Profile GPU Rendering 檢測丟幀情況篡石。
也可以通過啟動(dòng)加載邏輯優(yōu)化芥喇。可以采用分布加載凰萨、異步加載继控、延期加載策略來提高應(yīng)用啟動(dòng)速度。
數(shù)據(jù)準(zhǔn)備胖眷。數(shù)據(jù)初始化分析武通,加載數(shù)據(jù)可以考慮用線程初始化等策略。
刷新優(yōu)化
Android開發(fā)中珊搀,通常是異步操作頁面的冶忱,因此需要可以從刷新優(yōu)化上來優(yōu)化應(yīng)用,主要有兩個(gè)原則:
- 減少刷新次數(shù)境析;
- 縮小刷新區(qū)域囚枪;
動(dòng)畫優(yōu)化
在實(shí)現(xiàn)動(dòng)畫效果時(shí),需要根據(jù)不同場景選擇合適的動(dòng)畫框架來實(shí)現(xiàn)劳淆。有些情況下链沼,可以用硬件加速方式來提供流暢度。
耗電優(yōu)化
在 Android5.0 以前沛鸵,在應(yīng)用中測試電量消耗比較麻煩括勺,也不準(zhǔn)確,5.0 之后專門引入了一個(gè)獲取設(shè)備上電量消耗信息的 API谒臼,即Battery Historian朝刊。Battery Historian 是一款由 Google 提供的 Android 系統(tǒng)電量分析工具,和Systrace 一樣蜈缤,是一款圖形化數(shù)據(jù)分析工具,直觀地展示出手機(jī)的電量消耗過程冯挎,通過輸入電量分析文件底哥,顯示消耗情況,最后提供一些可供參考電量優(yōu)化的方法房官。
網(wǎng)絡(luò)優(yōu)化
對(duì)于網(wǎng)絡(luò)的優(yōu)化趾徽,可以從以下幾個(gè)方面著手進(jìn)行:
圖片網(wǎng)絡(luò)優(yōu)化
例如,針對(duì)網(wǎng)絡(luò)情況翰守,返回不同的圖片數(shù)據(jù)孵奶,一種是高清大圖,一種是正常圖片蜡峰,一種是縮略小圖了袁。當(dāng)用戶處于wifi下給控件設(shè)置高清大圖朗恳,當(dāng)4g或者3g模式下加載正常圖片,當(dāng)弱網(wǎng)條件下加載縮略圖载绿。
網(wǎng)絡(luò)數(shù)據(jù)優(yōu)化
- 連接復(fù)用:節(jié)省連接建立時(shí)間粥诫,如開啟 keep-alive。
對(duì)于Android來說默認(rèn)情況下HttpURLConnection和HttpClient都開啟了keep-alive崭庸。只是2.2之前HttpURLConnection存在影響連接池的Bug怀浆,具體可見:Android HttpURLConnection及HttpClient選擇 - 請(qǐng)求合并:即將多個(gè)請(qǐng)求合并為一個(gè)進(jìn)行請(qǐng)求,比較常見的就是網(wǎng)頁中的CSS Image Sprites怕享。如果某個(gè)頁面內(nèi)請(qǐng)求過多执赡,也可以考慮做一定的請(qǐng)求合并。
- 減少請(qǐng)求數(shù)據(jù)的大泻睢:對(duì)于post請(qǐng)求沙合,body可以做gzip壓縮的,header也可以做數(shù)據(jù)壓縮驻呐。返回?cái)?shù)據(jù)的body也可以做gzip壓縮灌诅,body數(shù)據(jù)體積可以縮小到原來的30%左右。
異常攔截優(yōu)化
在獲取數(shù)據(jù)的流程中含末,訪問接口和解析數(shù)據(jù)時(shí)都有可能會(huì)出錯(cuò)猜拾,我們可以通過攔截器在這兩層攔截錯(cuò)誤。
- 在訪問接口時(shí)佣盒,我們不用設(shè)置攔截器挎袜,因?yàn)橐坏┏霈F(xiàn)錯(cuò)誤,Retrofit會(huì)自動(dòng)拋出異常肥惭。比如盯仪,常見請(qǐng)求異常404,500蜜葱,503等等全景。
- 在解析數(shù)據(jù)時(shí),我們?cè)O(shè)置一個(gè)攔截器牵囤,判斷Result里面的code是否為成功爸黄,如果不成功,則要根據(jù)與服務(wù)器約定好的錯(cuò)誤碼來拋出對(duì)應(yīng)的異常揭鳞。比如炕贵,token失效,禁用同賬號(hào)登陸多臺(tái)設(shè)備野崇,缺少參數(shù)称开,參數(shù)傳遞異常等等。
APK瘦身
Android的apk主要有以下信息構(gòu)成:
- assets文件夾乓梨。存放一些配置文件鳖轰、資源文件清酥,assets不會(huì)自動(dòng)生成對(duì)應(yīng)的 ID,而是通過 AssetManager 類的接口獲取脆霎。
- res总处。res 是 resource 的縮寫,這個(gè)目錄存放資源文件睛蛛,會(huì)自動(dòng)生成對(duì)應(yīng)的 ID 并映射到 .R 文件中鹦马,訪問直接使用資源ID。
- META-INF忆肾。保存應(yīng)用的簽名信息荸频,簽名信息可以驗(yàn)證 APK 文件的完整性。
- AndroidManifest.xml客冈。這個(gè)文件用來描述 Android 應(yīng)用的配置信息旭从,一些組件的注冊(cè)信息、可使用權(quán)限等场仲。
- classes.dex和悦。Dalvik 字節(jié)碼程序,讓 Dalvik 虛擬機(jī)可執(zhí)行渠缕,一般情況下鸽素,Android 應(yīng)用在打包時(shí)通過Android SDK 中的 dx 工具將 Java 字節(jié)碼轉(zhuǎn)換為 Dalvik 字節(jié)碼。
- resources.arsc亦鳞。記錄著資源文件和資源 ID 之間的映射關(guān)系馍忽,用來根據(jù)資源 ID 尋找資源。
基于上面的組成部分燕差,那么優(yōu)化也可以從以下幾個(gè)方面著手:
- 代碼混淆遭笋。使用proGuard 代碼混淆器工具,它包括壓縮徒探、優(yōu)化瓦呼、混淆等功能。
- 資源優(yōu)化测暗。比如使用 Android Lint 刪除冗余資源吵血,資源文件最少化等。
- 圖片優(yōu)化偷溺。比如利用 AAPT 工具對(duì) PNG 格式的圖片做壓縮處理,降低圖片色彩位數(shù)等钱贯。
- 避免重復(fù)功能的庫挫掏,使用 WebP圖片格式等。
- 插件化秩命,比如功能模塊放在服務(wù)器上尉共,按需下載褒傅,可以減少安裝包大小。
針對(duì)Android的性能優(yōu)化袄友,主要有以下幾個(gè)有效的優(yōu)化方法:
- 布局優(yōu)化
- 繪制優(yōu)化
- 內(nèi)存泄漏優(yōu)化
- 響應(yīng)速度優(yōu)化
- ListView/RecycleView及Bitmap優(yōu)化
- 線程優(yōu)化
- 其他性能優(yōu)化的建議
布局優(yōu)化
關(guān)于布局優(yōu)化的思想很簡單殿托,就是盡量減少布局文件的層級(jí)。這個(gè)道理很淺顯剧蚣,布局中的層級(jí)少了支竹,就意味著Android繪制時(shí)的工作量少了,那么程序的性能自然就提高了鸠按。
1. 刪除布局中無用的控件和層次礼搁,其次有選擇地使用性能比較低的ViewGroup。
關(guān)于有選擇地使用性能比較低的ViewGroup,這就需要我們開發(fā)就實(shí)際靈活選擇了目尖。
例如:如果布局中既可以使用LinearLayout也可以使用RelativeLayout馒吴,那么就采用LinearLayout,這是因?yàn)镽elativeLayout的功能比較復(fù)雜瑟曲,它的布局過程需要花費(fèi)更多的CPU時(shí)間饮戳。FrameLayout和LinearLayout一樣都是一種簡單高效的ViewGroup,因此可以考慮使用它們洞拨,但是很多時(shí)候單純通過一個(gè)LinearLayout或者FrameLayout無法實(shí)現(xiàn)產(chǎn)品效果扯罐,需要通過嵌套的方式來完成。這種情況下還是建議采用RelativeLayout,因?yàn)閂iewGroup的嵌套就相當(dāng)于增加了布局的層級(jí)扣甲,同樣會(huì)降低程序的性能篮赢。
2. ViewStub
ViewStub提供了按需加載的功能,當(dāng)需要時(shí)才會(huì)將ViewStub中的布局加載到內(nèi)存琉挖,提高了程序初始化效率启泣。
3. 避免過度繪制
過度繪制(Overdraw)描述的是屏幕上的某個(gè)像素在同一幀的時(shí)間內(nèi)被繪制了多次。在多層次重疊的 UI 結(jié)構(gòu)里面示辈,如果不可見的 UI 也在做繪制的操作寥茫,會(huì)導(dǎo)致某些像素區(qū)域被繪制了多次,同時(shí)也會(huì)浪費(fèi)大量的 CPU 以及 GPU 資源矾麻。
如下所示纱耻,有些部分在布局時(shí),會(huì)被重復(fù)繪制:
過度繪制優(yōu)化可以參考:Android 過度繪制優(yōu)化
繪制優(yōu)化
繪制優(yōu)化是指View的onDraw方法要避免執(zhí)行大量的操作险耀,這主要體現(xiàn)在兩個(gè)方面:
1. onDraw中不要?jiǎng)?chuàng)建新的局部對(duì)象弄喘。
因?yàn)閛nDraw方法可能會(huì)被頻繁調(diào)用,這樣就會(huì)在一瞬間產(chǎn)生大量的臨時(shí)對(duì)象甩牺,這不僅占用了過多的內(nèi)存而且還會(huì)導(dǎo)致系統(tǒng)更加頻繁gc蘑志,降低了程序的執(zhí)行效率。
2. onDraw方法中不要做耗時(shí)的任務(wù),也不能執(zhí)行成千上萬次的循環(huán)操作急但,盡管每次循環(huán)都很輕量級(jí)澎媒,但是大量的循環(huán)仍然十分搶占CPU的時(shí)間片,這會(huì)造成View的繪制過程不流暢波桩。
按照Google官方給出的性能優(yōu)化典范中的標(biāo)準(zhǔn)戒努,View的繪制頻率保證60fps是最佳的,這就要求每幀繪制時(shí)間不超過16ms(16ms = 1000/60)镐躲,雖然程序很難保證16ms這個(gè)時(shí)間储玫,但是盡量降低onDraw方法中的復(fù)雜度總是切實(shí)有效的。
內(nèi)存泄漏優(yōu)化
內(nèi)存泄漏是開發(fā)過程中的一個(gè)需要重視的問題匀油,但是由于內(nèi)存泄露問題對(duì)開發(fā)人員的經(jīng)驗(yàn)和開發(fā)意識(shí)有較高的要求缘缚,因此也是開發(fā)人員最容易犯的錯(cuò)誤之一肠仪。
內(nèi)存泄露的優(yōu)化分為兩個(gè)方面:
1. 在開發(fā)過程中避免寫出有內(nèi)存泄漏的代碼
2. 通過一些分析工具比如MAT來找出潛在的內(nèi)存泄露浦楣,然后解決缰趋。
什么是內(nèi)存泄漏?
java是有垃圾回收機(jī)制的境肾。java虛擬機(jī)會(huì)派出一些回收線程不定時(shí)地回收那些不再被需要的內(nèi)存空間(注意回收的不是對(duì)象本身百姓,而是對(duì)象占據(jù)的內(nèi)存空間)翎迁。
Q:什么是不再被需要的內(nèi)存空間巷帝?
Java沒有指針往湿,全憑引用來和對(duì)象進(jìn)行關(guān)聯(lián)纷跛,通過引用來操作對(duì)象喻括。如果一個(gè)對(duì)象沒有與任何引用關(guān)聯(lián),那么這個(gè)對(duì)象也就不太可能被使用到了贫奠,回收器便是把這些“無任何引用的對(duì)象”作為目標(biāo)唬血,回收了它們占據(jù)的內(nèi)存空間。
Q:如何分辨為對(duì)象無引用唤崭?
- 引用計(jì)數(shù)法拷恨。直接計(jì)數(shù),簡單高效谢肾,Python便是采用該方法腕侄。但是如果出現(xiàn) 兩個(gè)對(duì)象相互引用,即使它們都無法被外界訪問到芦疏,計(jì)數(shù)器不為0它們也始終不會(huì)被回收冕杠。為了解決該問題,java采用的是方法2酸茴。
- 可達(dá)性分析法分预。這個(gè)方法設(shè)置了一系列的“GC Roots”對(duì)象作為索引起點(diǎn),如果一個(gè)對(duì)象 與起點(diǎn)對(duì)象之間均無可達(dá)路徑薪捍,那么這個(gè)不可達(dá)的對(duì)象就會(huì)成為回收對(duì)象噪舀。這種方法處理 兩個(gè)對(duì)象相互引用的問題魁淳,如果兩個(gè)對(duì)象均沒有外部引用,會(huì)被判斷為不可達(dá)對(duì)象進(jìn)而被回收(如下圖)与倡。
Q:有了回收機(jī)制,為什么還會(huì)發(fā)生內(nèi)存泄漏昆稿?
雖然垃圾回收器會(huì)幫我們回收大部分無用的內(nèi)存空間纺座,但是對(duì)于還保持著引用,但邏輯上已經(jīng)不會(huì)再用到的對(duì)象溉潭,垃圾回收器不會(huì)回收它們净响。這些對(duì)象積累在內(nèi)存中,直到程序結(jié)束喳瓣,這就是所說的“內(nèi)存泄漏”馋贤。 當(dāng)然了,用戶對(duì)單次的內(nèi)存泄漏并沒有什么感知畏陕,但當(dāng)泄漏積累到內(nèi)存都被消耗完配乓,就會(huì)導(dǎo)致卡頓,崩潰惠毁。
下面這張圖可以幫助我們更好地理解對(duì)象的狀態(tài)犹芹,以及內(nèi)存泄漏的情況
左邊未引用的對(duì)象是會(huì)被GC回收的,右邊被引用的對(duì)象不會(huì)被GC回收鞠绰,但是未使用的對(duì)象中除了未引用的對(duì)象腰埂,還包括已被引用的一部分對(duì)象,那么內(nèi)存泄漏久發(fā)生這部分已被引用但未使用的對(duì)象蜈膨。
Android一般在什么情況下會(huì)出現(xiàn)內(nèi)存泄漏屿笼?
①集合類泄漏
②單例/靜態(tài)變量造成的內(nèi)存泄漏
③匿名內(nèi)部類/非靜態(tài)內(nèi)部類
④資源未關(guān)閉造成的內(nèi)存泄漏
大概可以分為以上幾類,還有一些經(jīng)常會(huì)聽到的Hanlder, AsyncTask引起內(nèi)存泄漏翁巍,都屬于上述③中的情況驴一。
Android怎么分析內(nèi)存泄漏?
可以通過 MAT(Memory Analyzer Tool)曙咽,或者 LeakCanary 來檢測 Android 中的內(nèi)存泄漏蛔趴。
內(nèi)存泄漏可參考:Android應(yīng)用內(nèi)存泄漏的定位、分析與解決策略
響應(yīng)速度優(yōu)化
響應(yīng)速度優(yōu)化的核心思想就是避免在主線程中做耗時(shí)操作例朱。
如果有耗時(shí)操作孝情,可以開啟子線程執(zhí)行,即采用異步的方式來執(zhí)行耗時(shí)操作洒嗤。
如果在主線程中做太多事情箫荡,會(huì)導(dǎo)致Activity啟動(dòng)時(shí)出現(xiàn)黑屏現(xiàn)象,甚至ANR渔隶。
Android規(guī)定羔挡,Activity如果5秒鐘之內(nèi)無法響應(yīng)屏幕觸摸事件或者鍵盤輸入事件就會(huì)出現(xiàn)ANR洁奈,而BroadcastReceiver如果10秒鐘之內(nèi)還未執(zhí)行完操作也會(huì)出現(xiàn)ANR。
為了避免ANR绞灼,可以開啟子線程執(zhí)行耗時(shí)操作利术,但是子線程不能更新UI,所以需要子線程與主線程進(jìn)行通信來解決子線程執(zhí)行耗時(shí)任務(wù)后低矮,通知主線程更新UI的場景印叁。關(guān)于這部分,需要掌握Handler消息機(jī)制军掂,AsyncTask轮蜕,IntentService等內(nèi)容。
然而蝗锥,在實(shí)際開發(fā)中跃洛,ANR仍然不可避免的發(fā)生了,而且很難從代碼上發(fā)現(xiàn)终议,這時(shí)候就要用到ANR日志分析汇竭。當(dāng)一個(gè)進(jìn)程發(fā)生了ANR之后,系統(tǒng)會(huì)在/data/anr目錄下創(chuàng)建一個(gè)文件traces.txt痊剖,通過分析這個(gè)文件就能定位出ANR的原因韩玩。
ListView/RecycleView及Bitmap優(yōu)化
ListView/RecycleView的優(yōu)化思想主要從以下幾個(gè)方面入手:
① 使用ViewHolder模式來提高效率
② 異步加載:耗時(shí)的操作放在異步線程中
③ ListView/RecycleView的滑動(dòng)時(shí)停止加載和分頁加載
Bitmap優(yōu)化
對(duì)加載圖片進(jìn)行壓縮,避免加載圖片多大導(dǎo)致OOM出現(xiàn)陆馁。
線程優(yōu)化
線程優(yōu)化的思想就是采用線程池找颓,避免程序中存在大量的Thread。線程池可以重用內(nèi)部的線程叮贩,從而避免了線程的創(chuàng)建和銷毀所帶來的性能開銷击狮,同時(shí)線程池還能有效地控制線程池的最大并發(fā)數(shù),避免大量的線程因互相搶占系統(tǒng)資源從而導(dǎo)致阻塞現(xiàn)象的發(fā)生益老。因此在實(shí)際開發(fā)中彪蓬,盡量采用線程池,而不是每次都要?jiǎng)?chuàng)建一個(gè)Thread對(duì)象捺萌。
其他性能優(yōu)化
①避免過度的創(chuàng)建對(duì)象
②不要過度使用枚舉档冬,枚舉占用的內(nèi)存空間要比整型大
③常量請(qǐng)使用static final來修飾
④使用一些Android特有的數(shù)據(jù)結(jié)構(gòu),比如SparseArray和Pair等
⑤適當(dāng)采用軟引用和弱引用
⑥采用內(nèi)存緩存和磁盤緩存
⑦盡量采用靜態(tài)內(nèi)部類桃纯,這樣可以避免潛在的由于內(nèi)部類而導(dǎo)致的內(nèi)存泄漏酷誓。