1,UI
UI是最直觀的反映APP卡頓的因素胁艰,Android系統(tǒng)中,應(yīng)用程序把經(jīng)過測量,布局腾么、繪制后的 surface 緩存數(shù)據(jù)杈湾,通過 SurfaceFlinger 把數(shù)據(jù)渲染到顯示屏幕上, 通過 Android 的刷新機制來刷新數(shù)據(jù)殴泰。簡單來說就是應(yīng)用層負責繪制于宙,系統(tǒng)層負責渲染進程間通信把應(yīng)用層需要繪制的數(shù)據(jù)傳遞到系統(tǒng)層服務(wù)悍汛,系統(tǒng)層服務(wù)通過刷新機制把數(shù)據(jù)更新到屏幕上。
理想的情況下离咐,讓人的眼睛不覺的卡頓,每秒傳遞的幀數(shù)要達到60昆著,Android系統(tǒng)每隔16ms發(fā)送一次VSYNC信號,1000(1秒)/16=62.5凑懂,在這種情況下人的眼睛便不會覺得卡頓梧宫,也就是說16ms的繪制時長是符合要求的。如果某一操作的繪制耗時30ms疤坝,就會發(fā)生丟幀現(xiàn)象兆解,這種現(xiàn)象在動畫或者列表滑動中比較常見。
解決方法
- 布局優(yōu)化
- include merge viewstub的合理使用
- 減少嵌套锅睛,推薦使用ConstraintLayout
- 合理使用背景色
- 不能使用ScrollView包裹ListView/GridView/ExpandableListView,因為這樣會把ListView的所有Item都加載到內(nèi)存中现拒,要消耗巨大的內(nèi)存和cpu去繪制圖面。為了較好的UI體驗勋桶,推薦使用NestedcrollView
- 繪制優(yōu)化
- onDraw 中不要創(chuàng)建新的局部對象
- onDraw 方法中不要做耗時的任務(wù)
2侥猬,關(guān)于啟動
- 冷啟動
冷啟動是指安裝 apk 后首次啟動應(yīng)用程序,或者應(yīng)用程序上次結(jié)束退唠,進程被殺死后重新打開app。
冷啟動后系統(tǒng)需要做一下三個任務(wù):
1屎债,加載并啟動應(yīng)用程序
2,啟動后立即顯示應(yīng)用程序的空白啟動窗口
3盆驹,創(chuàng)建應(yīng)用程序進程
應(yīng)用程序創(chuàng)建之后,會執(zhí)行以下操作:- application的初始化
- 啟動UI線程
- 創(chuàng)建activity
- inflate view
- onMesure
- onLayout
- onDraw
- 暖啟動
暖啟動比冷啟動時間更短运褪。在暖啟動中,系統(tǒng)都會把你的 Activity 帶到前臺玖瘸。如果應(yīng)用程序的 Activity 仍然駐留在內(nèi)存中秸讹,那么應(yīng)用程序可以避免重復(fù)對象初始化、布局加載和渲染雅倒,但系統(tǒng)依然會展示閃屏頁璃诀,直到第一個 Activity 的內(nèi)容呈現(xiàn)為止。比如:當應(yīng)用中的 Activities 被銷毀蔑匣,但在內(nèi)存中常駐時劣欢,應(yīng)用的啟動方式就會變?yōu)榕瘑?。 - 熱啟動
熱啟動的啟動時間比暖啟動還要更短裁良。你比如凿将,我用戶 Back 退出應(yīng)用程序,然后又重新啟動价脾,應(yīng)用程序會再次執(zhí)行 Activity 的 onCreate()牧抵。
解決方法
application 的創(chuàng)建過程中盡量減少耗時的操作,非必須的操作可在異步線程中執(zhí)行侨把。
3,內(nèi)存優(yōu)化
- 匿名內(nèi)部類/非靜態(tài)內(nèi)部類获枝,可以使用android引用機制解決
- 集合類及時置空
- 資源及時關(guān)閉(廣播省店,service笨触,文件,eventbus谎脯,bitmap)
- context生命周期
- 圖片處理(Glide采用的是Lrucache和LruDiskCache)
- 線程池處理多線程
- 集合如果是插入和刪除用的多源梭,建議使用 LinkList,如果修改用的多废麻,建議 ArrayList
- 對常量使用 static final烛愧,適用于基本類型和 String 常量
- 使用增強的 for 循環(huán)語法(foreach)
- 數(shù)據(jù)量比較大或者內(nèi)存比較寬粤耍考慮 HashMap,其他建議使用 SpareArray
- 避免在Service#onStartCommand()/onBind()方法中執(zhí)行耗時操作蚁堤,如果有需求但狭,應(yīng)改為IntentService立磁,或采用其他異步機制完成。
- 避免在BroadcastReceiver#onReceive()中執(zhí)行耗時操作宪摧,如果有耗時工作绍刮,應(yīng)該創(chuàng)建IntentService完成挨摸,而不應(yīng)該在BroadcastReceiver內(nèi)創(chuàng)建子線程去做得运。
- 不要在Android的Application地對象中緩存數(shù)據(jù)熔掺》翘辏基礎(chǔ)組件之間的數(shù)據(jù)共享使用Intent機制备绽,也可以使用SharedPreferences等數(shù)據(jù)持久化機制鬓催。
- 在Activity中顯示對話框或彈出浮層時宇驾,盡量使用DialogFragment课舍,而非Dialog/AlertDialog筝尾,這樣便于隨Activity生命周期管理對話框/彈出浮層的生命周期办桨。
- 不要通過Intent在Android基礎(chǔ)組件之間傳遞大數(shù)據(jù),可能導致OOM贸街。
- png圖片使用tinypng或者類似工具壓縮處理薛匪,減少包體積逸尖。