Android 性能優(yōu)化小結(jié)

本周有個(gè)需求,對(duì)某個(gè)界面進(jìn)行優(yōu)化,然后看了一些文章,并進(jìn)行小結(jié),為了方便以后回頭查看。

僅供個(gè)人參考

我還可以繼續(xù)戰(zhàn)斗

一、界面繪制優(yōu)化

1. 頁(yè)面卡頓原因

  • 布局 Layout 過(guò)于復(fù)雜,無(wú)法在16 ms 內(nèi)完成渲染。
  • 同一時(shí)間動(dòng)畫(huà)執(zhí)行的次數(shù)過(guò)多,導(dǎo)致 CPU 或 GPU 負(fù)載過(guò)重
  • View 過(guò)度繪制,導(dǎo)致某些像素在同一幀時(shí)間內(nèi)被繪制多次
  • UI 線程中做了稍微耗時(shí)的操作

2. 解決工具

  • 開(kāi)發(fā)者選項(xiàng)-打開(kāi)GPU渲染
  • 使用 Systrace
  • 使用 TraceView
  • 使用 Hierarchy Viewer 觀察每個(gè) View 的繪制時(shí)間

3. 解決策略

  • 如果布局層數(shù)比較多的時(shí)候,推薦使用 RelativeLayout
  • 如果布局嵌套比較多,推薦使用 LinearLayout (RelativeLayout 的view的排列方式是基于彼此于彼此依賴)
  • 使用 include 標(biāo)簽進(jìn)行布局復(fù)用
  • 使用 merge 標(biāo)簽去除多余層級(jí)
    • merge 標(biāo)簽最好是替代 FrameLayout 或者是布局一致的 LinearLayout,比如當(dāng)前布局的 LinearLayout 是垂直方向的,被包含的布局的 LinearLayout 也是垂直方向的則可以使用 merge 標(biāo)簽。
  • 使用 ViewStub 延遲加載布局提高加載速度
    • ViewStub 只能加載一次,加載后 ViewStub 被置為空
    • ViewStub 不能嵌套 merge 標(biāo)簽
    • ViewStub 操作的是布局文件,如果想操作具體的 view,還是要使用 view 的visible 屬性
  • 避免過(guò)度繪制、重繪
    • 移除不需要的 background
    • 在自定義 view 的 onDraw 方法中,用 canvas.clipRect 來(lái)指定繪制的區(qū)域,放置重疊的組件發(fā)生過(guò)度繪制

二、內(nèi)存泄露

1. 主要原因分類

  1. 開(kāi)發(fā)人員自己編寫(xiě)代碼造成的內(nèi)存泄漏
  2. 第三方框架造成的泄漏
  3. 由 Android 系統(tǒng)或者第三方 ROM 造成的內(nèi)存泄漏

2. 泄露場(chǎng)景

  • 非靜態(tài)內(nèi)部類的靜態(tài)實(shí)例
    • 如果非靜態(tài)內(nèi)部類里面創(chuàng)建的實(shí)例是靜態(tài)的,那么它會(huì)間接的長(zhǎng)期維持著外部的引用,阻止被系統(tǒng)回收
  • 匿名內(nèi)部類的靜態(tài)實(shí)例
  • Handler 的內(nèi)存泄露
    • 如果 Handler 是非靜態(tài)的,那么 Handler 也會(huì)導(dǎo)致引用它的 Activity、Service or Fragment,導(dǎo)致內(nèi)存泄露
  • 未正確使用 Context (最常見(jiàn)的就是單例模式)
  • 靜態(tài)的 view
  • 資源對(duì)象未關(guān)閉(curson file)
  • 集合中對(duì)象未清理
  • Bitmap 對(duì)象
    • 避免靜態(tài)變量持有比較大的 btimap 對(duì)象或者其他大的數(shù)據(jù)對(duì)象,如果已持有,要盡快置空靜態(tài)變量
  • 監(jiān)聽(tīng)器未關(guān)閉
    • 很多系統(tǒng)的服務(wù) TelephonyManager SensorManager 記得取消注冊(cè),或者注冊(cè) null

三、開(kāi)發(fā)過(guò)程中遵循的守則

1. 編程思想

應(yīng)用層的性能優(yōu)化通常可以從以下幾個(gè)方面考慮:

  • 了解編程語(yǔ)言的編譯原理,使用高效編碼方式從語(yǔ)法上提高程序性能;
  • 采用合理的數(shù)據(jù)結(jié)構(gòu)和算法提高程序性能,這往往是決定程序性能的關(guān)鍵;
  • 重視界面布局優(yōu)化;
  • 采用多線程、緩存數(shù)據(jù)、延遲加載、提前加載等手段,解決嚴(yán)重的性能瓶頸;
  • 合理配置虛擬機(jī)堆內(nèi)存使用上限和使用率,減少垃圾回收頻率;
  • 合理使用native代碼;
  • 合理配置數(shù)據(jù)庫(kù)緩存類型和優(yōu)化SQL語(yǔ)句加快讀取速度,使用事務(wù)加快寫(xiě)入速度;
  • 使用工具分析性能問(wèn)題,找出性能瓶頸;

2. 編程技巧

不執(zhí)行不必要的操作(CPU)、不分配不必要的內(nèi)存(內(nèi)存)

  • 避免創(chuàng)建不必要的對(duì)象
    • 分配內(nèi)存本身需要時(shí)間,虛擬機(jī)運(yùn)行時(shí)堆內(nèi)存使用量是有上限的,容易出發(fā) GC,使進(jìn)程暫停,造成嚴(yán)重卡頓。
  • 合理使用 static 成員
  • 不需要操作運(yùn)行時(shí)的動(dòng)態(tài)變量和方法,那么可以講方法設(shè)置為 static
  • 常量字段要聲明為 static final,因?yàn)槌A繒?huì)被放在 dex 文件的靜態(tài)字段初始化器中被直接訪問(wèn)。否在運(yùn)行時(shí)會(huì)通過(guò)編譯器自動(dòng)生成一些函數(shù)來(lái)初始化此規(guī)則只對(duì)基本類型和 String 類型有效
  • 避免創(chuàng)建 static 的 view or context,持有 Activity 的引用容易造成內(nèi)存泄露
  • 避免內(nèi)部的 getter 和 setter
    • 盡量直接聲明為 public,直接訪問(wèn)的速度比間接訪問(wèn)要快7倍
  • 合理使用浮點(diǎn)類型
    • 在 Android 設(shè)備中,浮點(diǎn)型大概比整形數(shù)據(jù)處理速度慢兩倍
  • 移除 Activity 默認(rèn)背景,提升 Activity 加載速度
    • getWindow().setBackgroundDrawable(null);
  • cursor stream 的關(guān)閉
  • 廣播的注冊(cè)和取消注冊(cè)
  • 合理使用 StringBuffer StringBuilder String
  • 盡量使用局部變量
  • 調(diào)用方法時(shí)傳遞的參數(shù)已經(jīng)調(diào)用中創(chuàng)建的臨時(shí)變量都保存在 stack 中,速度較快,其他變量(靜態(tài)變量、成員變量)都在 heap 中創(chuàng)建,速度較慢
  • IntentService 代替 Service
  • 使用 ApplicationCotext 代替 Activity 的 Context
  • 集合中的對(duì)象及時(shí)清理
  • 記得在 onDestory() 方法中,及時(shí)銷毀 webView
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,983評(píng)論 25 709
  • 太長(zhǎng)不看版:在 Android UI 布局過(guò)程中,遵守一些慣用、有效的布局原則,可以制作出高效且復(fù)用性高的 UI。...
    Mupceet閱讀 4,024評(píng)論 0 14
  • 性能優(yōu)化系列閱讀 Android性能優(yōu)化 性能優(yōu)化 - 消除卡頓 性能優(yōu)化- 內(nèi)存優(yōu)化 性能分析工具 - Trac...
    JackChen1024閱讀 1,449評(píng)論 1 20
  • 昨天,與一久未謀面事業(yè)有成的老朋友聊天敘舊,相談甚歡。朋友突然話題一轉(zhuǎn),滿懷心事地和我說(shuō): “你知道么?我特別怕回...
    于工移山閱讀 937評(píng)論 0 2
  • 某一天,小白蓮在寢室蹲坑的時(shí)候發(fā)表了一些感想,“我每次在寢室拉粑粑都要拉好久,但是去別人寢室借廁所都不敢拉粑粑?!?..
    涵簫琪閱讀 331評(píng)論 0 0

友情鏈接更多精彩內(nèi)容