Android性能優(yōu)化主要從卡頓捌治、內(nèi)存泄漏和崩潰、代碼質(zhì)量和邏輯纽窟、安裝包過大四方面入手肖油。在使用時(shí)避免出現(xiàn)卡頓,響應(yīng)速度快臂港,減少用戶等待的時(shí)間森枪,滿足用戶期望视搏;同時(shí)減低 crash 率和 ANR 率,不要在用戶使用過程中崩潰和無響應(yīng)疲恢;節(jié)省流量和耗電凶朗,減少用戶使用成本,避免使用時(shí)導(dǎo)致手機(jī)發(fā)燙显拳;安裝包小可以降低用戶的安裝成本棚愤。
1、卡頓優(yōu)化
Android 系統(tǒng)每隔 16ms 發(fā)出 VSYNC 信號(hào)杂数,觸發(fā)對 UI 進(jìn)行渲染宛畦,如果每次渲染都成功,這樣就能夠達(dá)到流暢的畫面所需的 60FPS揍移。在理想情況下次和,60 FPS 就感覺不到卡,這意味著每個(gè)繪制時(shí)長應(yīng)該在16 ms 左右那伐。如果某個(gè)操作花費(fèi)的時(shí)間是 24ms 踏施,系統(tǒng)在得到 VSYNC 信號(hào)時(shí)就無法正常進(jìn)行正常渲染,這樣就發(fā)生了丟幀現(xiàn)象罕邀。也就是延遲了畅形。
布局優(yōu)化:
合理使用背景色,避免重復(fù)繪制背景色诉探,例如:父布局和子布局的背景色一樣的日熬,子布局無需在設(shè)背景色,父布局設(shè)置即可
減少布局嵌套肾胯,一般不建議超過5層竖席,google推出ConstraintLayout可以使用
合理使用 include、merge 和 ViewStub,使用include和merge增加復(fù)用敬肚,減少層級; ViewStub 按需加載
盡可能少用wrap_content毕荐。wrap_content 會(huì)增加布局 measure 時(shí)計(jì)算成本,在已知寬高為固定值時(shí)艳馒,不用wrap_content
刪除控件中無用的屬性
繪制優(yōu)化:在onDraw中不要?jiǎng)?chuàng)建嵌套對象和做耗時(shí)的任務(wù)东跪;在databinding數(shù)據(jù)刷新的是盡量局部刷新,不要全局刷新鹰溜。
啟動(dòng)優(yōu)化:盡量在Application和Activity onCreate中進(jìn)行耗時(shí)操作虽填,同時(shí)避免在生命周期避免 I/O 操作、反序列化曹动、網(wǎng)絡(luò)操作斋日、布局嵌套等
2、內(nèi)存優(yōu)化
通常在以下的場景容易導(dǎo)致內(nèi)存泄漏:
資源性對象未關(guān)閉墓陈。比如Cursor恶守、File第献、Bitmap等,往往都用了一些緩沖兔港,在不使用時(shí)庸毫,應(yīng)該及時(shí)關(guān)閉它們
注冊對象未注銷。比如事件注冊后未注銷衫樊,會(huì)導(dǎo)致觀察者列表中維持著對象的引用飒赃。例如EventBus或者RxJava
單類或者靜態(tài)變量持有大數(shù)據(jù)對象
引用的context是生命周期短造成,比如Toast科侈,我們傳入的是MainActivity载佳,但MainActivity沒有用了,需要被銷毀臀栈,但我們的Tost依然持有其引用導(dǎo)致無法回收蔫慧,這就導(dǎo)致了內(nèi)存泄漏
匿名內(nèi)部類或非靜態(tài)內(nèi)部類的靜態(tài)實(shí)例
Handler臨時(shí)性內(nèi)存泄漏。如果Handler是非靜態(tài)的权薯,容易導(dǎo)致 Activity 或 Service 不會(huì)被回收
容器中的對象沒清理造成的內(nèi)存泄漏
WebView姑躲。WebView 存在著內(nèi)存泄漏的問題,在應(yīng)用中只要使用一次 WebView盟蚣,內(nèi)存就不會(huì)被釋放掉
手動(dòng)注冊廣播時(shí)黍析,退出時(shí)忘記 unregisterReceiver()
Service 執(zhí)行完后忘記 stopSelf()
3、穩(wěn)定性和耗電優(yōu)化
Android 應(yīng)用的穩(wěn)定性影響穩(wěn)定性的原因很多刁俭,比如內(nèi)存使用不合理、代碼異常場景考慮不周全韧涨、代碼邏輯不合理等牍戚。其中最常見的兩個(gè)場景是:Crash 和 ANR,這兩個(gè)錯(cuò)誤將會(huì)使得程序無法使用虑粥∪缧ⅲ可以下面的方法進(jìn)行解決:
提高代碼質(zhì)量,例如代碼審查娩贷、checkstyle統(tǒng)一風(fēng)格第晰、處理復(fù)雜邏輯時(shí)最好自己畫下流程圖
代碼靜態(tài)掃描工具。常見工具有Android Lint彬祖、Findbugs茁瘦、Checkstyle、PMD等
Crash監(jiān)控和上傳储笑。把一些崩潰的信息甜熔,異常信息及時(shí)地記錄下來,以便后續(xù)分析解決突倍;或者有條件的可以使用bugly腔稀,把異常信息上報(bào)
推薦使用 JobScheduler盆昙,來調(diào)整任務(wù)優(yōu)先級等策略來達(dá)到降低損耗的目的
計(jì)算優(yōu)化,避開浮點(diǎn)運(yùn)算等耗時(shí)計(jì)算
避免 WaleLock 使用不當(dāng)
4焊虏、安裝包大小優(yōu)化
安裝包過大淡喜,對用戶的下載欲望有影響,特別是在移動(dòng)網(wǎng)絡(luò)下诵闭,提高用戶進(jìn)入門檻炼团,雖然現(xiàn)在移動(dòng)網(wǎng)絡(luò)已經(jīng)無限流量,但apk過大加大了安裝時(shí)間涂圆,常用應(yīng)用安裝包的構(gòu)成们镜,如圖所示:
lib文件夾:存放一些第三方庫文件。
assets文件夾:存放一些配置文件润歉、資源文件模狭,assets不會(huì)自動(dòng)生成對應(yīng)的 ID,而是通過 AssetManager 類的接口獲取踩衩。
res文件夾:res 是 resource 的縮寫嚼鹉,這個(gè)目錄存放資源文件,會(huì)自動(dòng)生成對應(yīng)的 ID 并映射到 .R 文件中驱富,訪問直接使用資源 ID锚赤。
META-INF。保存應(yīng)用的簽名信息褐鸥,簽名信息可以驗(yàn)證 APK 文件的完整性线脚。
AndroidManifest.xml。這個(gè)文件用來描述 Android 應(yīng)用的配置信息叫榕,一些組件的注冊信息浑侥、可使用權(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 尋找資源仰税。
減少安裝包大小的常用方案
代碼混淆。使用proGuard 代碼混淆器工具抽诉,它包括壓縮肖卧、優(yōu)化、混淆等功能掸鹅。
資源優(yōu)化塞帐。比如使用 Android Lint 刪除冗余資源拦赠,資源文件最少化等。
圖片優(yōu)化葵姥。比如利用 AAPT 工具對 PNG 格式的圖片做壓縮處理荷鼠,降低圖片色彩位數(shù)等,或者使用webp格式圖片榔幸。
插件化允乐。比如功能模塊放在服務(wù)器上,按需下載削咆,可以減少安裝包大小牍疏。
減少lib。能自己寫的lib盡量自己寫拨齐,第三方lib可能會(huì)帶有你未必需要的代碼鳞陨;還有就是如果不想支持x86架構(gòu)的手機(jī),可以刪除x86lib瞻惋,或者打包的時(shí)候排除x86包厦滤。
刪除lombok。這個(gè)apk使用lombok歼狼,雖然帶來了get,set的方便掏导,但是apk也增大了,可以根據(jù)具體需求來決定是否使用羽峰。