android性能優(yōu)化總結(jié)

image.png

NimbleDroid 是美國哥倫比亞大學(xué)的博士創(chuàng)業(yè)團(tuán)隊(duì)研發(fā)出來的分析Android app性能指標(biāo)的系統(tǒng),分析的方式有靜態(tài)和動態(tài)兩種方式,

流暢度優(yōu)化

顯示原理

  1. cpu計(jì)算: measure layout draw => displayList
  2. gpu柵格化: displayList => 位圖
  3. 屏幕顯示: 位圖 => 顯示 60hz = 1000/60 = 16.67ms

檢測流暢度的幾種方式

  1. 騰訊GT https://github.com/Tencent/GT
  2. BlockCanary https://github.com/seiginonakama/BlockCanaryEx
  3. 開啟GPU渲染模式 水平的綠色橫線是 16ms android 6.0以上顏色多種
image.png

image.png
  1. Swap Buffers:表示處理任務(wù)的時間,也可以說是CPU等待GPU完成任務(wù)的時間,線條越高,表示GPU做的事情越多;
  2. Command Issue:表示執(zhí)行任務(wù)的時間,這部分主要是Android進(jìn)行2D渲染顯示列表的時間,為了將內(nèi)容繪制到屏幕上,Android需要使用Open GL ES的API接口來繪制顯示列表,紅色線條越高表示需要繪制的視圖更多
  3. Sync & Upload:表示的是準(zhǔn)備當(dāng)前界面上有待繪制的圖片所耗費(fèi)的時間,為了減少該段區(qū)域的執(zhí)行時間,我們可以減少屏幕上的圖片數(shù)量或者是縮小圖片的大小;
  4. Draw:表示測量和繪制視圖列表所需要的時間,藍(lán)色線條越高表示每一幀需要更新很多視圖,或者View的onDraw方法中做了耗時操作;
  5. Measure/Layout:表示布局的onMeasure與onLayout所花費(fèi)的時間,一旦時間過長,就需要仔細(xì)檢查自己的布局是不是存在嚴(yán)重的性能問題;
  6. Animation:表示計(jì)算執(zhí)行動畫所需要花費(fèi)的時間,包含的動畫有ObjectAnimator,ViewPropertyAnimator,Transition等等。一旦這里的執(zhí)行時間過長,就需要檢查是不是使用了非官方的動畫工具或者是檢查動畫執(zhí)行的過程中是不是觸發(fā)了讀寫操作等等;
  7. Input Handling:表示系統(tǒng)處理輸入事件所耗費(fèi)的時間,粗略等于對事件處理方法所執(zhí)行的時間。一旦執(zhí)行時間過長,意味著在處理用戶的輸入事件的地方執(zhí)行了復(fù)雜的操作;
  8. Misc Time/Vsync Delay:表示在主線程執(zhí)行了太多的任務(wù),導(dǎo)致UI渲染跟不上vSync的信號而出現(xiàn)掉幀的情況; 是重點(diǎn)優(yōu)化對象 配合cpu profile 看看耗時任務(wù)
  1. StrictMode 可檢測耗時

  2. 過度繪制問題:一個像素點(diǎn)被繪制多次


    image.png
  3. androidStudio 的布局分析器 查看布局結(jié)構(gòu)
    第三方布局分析器 https://github.com/romainguy/ViewServer
    布局嵌套太深導(dǎo)致 measure 計(jì)算太多 盡量減少布局嵌套 少用 wrap_content

流暢度優(yōu)化手段:

  1. 避免過度重繪,移除不必要的背景,降低布局嵌套層數(shù) 和 wrap_content 減少measure次數(shù)
    可使用 約束布局 減少 組合嵌套 線性布局和相對布局, 可使用 include merge等等 還可以用viewStub延遲初始化一部分view 第三方工具x2c 把xml布局 轉(zhuǎn)換為代碼實(shí)現(xiàn), 減少讀取布局文件占用的時間
  2. 避免主線程耗時 (gpu模式 深綠色),比如與視圖有關(guān)的 model 要在io線程處理好 再在主線程渲染
  3. 大殺招:用IdleHandler 進(jìn)行預(yù)處理
  4. 避免頻繁gc 一般來說瞬間大量產(chǎn)生對象一般是因?yàn)槲覀冊诖a的循環(huán)中new對象, 或是在onDraw中創(chuàng)建對象等. 所以說這些地方是我們尤其需要注意的...
  5. 刷新的時候局部刷新

網(wǎng)絡(luò)優(yōu)化

1.抓包工具Wireshark, Fiddler, Charles

2.解決方案

  1. 減少Radio(頻射模塊)活躍時間
  • 也就是減少網(wǎng)絡(luò)數(shù)據(jù)獲取的頻次.
  • 這就減少了radio的電量消耗, 控制電量使用.
  1. 減少獲取數(shù)據(jù)包的大小
  • 可以減少流量消耗
  • 也可以讓每次請求更快, 在網(wǎng)絡(luò)情況不好的情況下也有良好表現(xiàn), 提升用戶體驗(yàn).

圖片上傳與展示 實(shí)戰(zhàn)
a.api網(wǎng)關(guān),避免一個頁面的數(shù)據(jù)來自多個接口
b.壓縮
c.網(wǎng)絡(luò)緩存
d.弱網(wǎng)優(yōu)化
e.不適用域名 使用ip 繞過dns解析步驟

圖片上傳 和 圖片查看器

  1. 采用魯班壓縮 和gzip 對上傳的圖片和數(shù)據(jù)進(jìn)行壓縮
  2. 顯示時采用縮略圖策略,魔圖規(guī)則
  3. 減少不必要的網(wǎng)絡(luò)請求,而采用客戶端的基本邏輯去改變頁面 例如點(diǎn)贊按鈕后 直接本地+1
  4. 打包網(wǎng)絡(luò)請求
  5. 動態(tài)超時時間
  6. wifi下與拉取網(wǎng)絡(luò)數(shù)據(jù) 例如網(wǎng)易的離線新聞 或者 離線更新包
  7. 本地緩存
  8. http緩存
  9. 控制網(wǎng)絡(luò)請求頻率
  10. 網(wǎng)絡(luò)請求 接口降級
  11. 重試機(jī)制 重試次數(shù)
  12. 弱網(wǎng) 無圖模式
  13. ip直連 避免dns 或者使用 httpdns
  14. webp圖片 能省1/3
  15. http2 二進(jìn)制多路復(fù)用
  16. 避免輪詢 采用長連接

電量優(yōu)化

檢測工具 energy profile
用adb命令 Batterystats 導(dǎo)出 電量記錄文件
然后用 谷歌開源的 batteryHistorian 導(dǎo)入記錄文件 分析電量情況

  1. 和網(wǎng)絡(luò)優(yōu)化息息相關(guān),因?yàn)榫W(wǎng)絡(luò)非常耗電量,做好網(wǎng)絡(luò)優(yōu)化 手機(jī)的通過內(nèi)置的射頻模塊和基站 而這個射頻模塊(radio)是非常耗電的.
  2. 及時釋放wakeLock (保持屏幕常亮)
  3. 合理釋放GPS的監(jiān)聽
  4. BatteryManager 監(jiān)聽充電狀態(tài),一些耗電操作可以在充電情況去做
  5. 定時任務(wù) 可以做暫停 例如 輪播圖 不可見時 要及時停止

啟動優(yōu)化

冷啟動:直接啟動
熱啟動:退到后臺后進(jìn)程沒死,activity沒死
溫啟動:退到后臺進(jìn)程沒死,但activity被回收

檢測工具 GT

app啟動優(yōu)化

  1. 將application oncreate中的方法 拆分成 同步和異步, 并且延遲初始化一部分 加入一個
  2. windowBackground 作為啟動頁背景 首屏盡量簡單 可以寫一個什么都不做的activity 只顧跳轉(zhuǎn), 不做setcontentview
  3. 善用分析工具
  4. 優(yōu)化包體積可以加速啟動,優(yōu)化dex分包可以加速啟動
  5. 這里可以說下方舟編譯器的原理

安卓系統(tǒng)中也有這樣的編譯器,目前有兩個編譯器,分別是Art和Jit,Art是在你首次安裝APP時,對大約20%的核心程序代碼翻譯成0、1這樣的機(jī)器語言保存在手機(jī)中,另外的80%非核心代碼則在運(yùn)行時用Jit編譯器來翻譯,所以才有了華為所說的連執(zhí)行連翻譯,自然效率不高了。
而如果APP通過方舟編譯器開發(fā),打包之后的APP就直接以0、1這樣的機(jī)器碼存在,這樣安裝到手機(jī)之中后,就是0、1這樣的機(jī)器碼,不存在翻譯過程,機(jī)器就直接可以執(zhí)行,不需要轉(zhuǎn)換,自然效率更高,體現(xiàn)在操作上自然就是啟動更快,操作更流暢了
https://baijiahao.baidu.com/s?id=1631785697366805454&wfr=spider&for=pc

  1. 把一些方法抽取出來. 在頁面繪制后, 等到UI線程空閑的時候, 再去執(zhí)行這些耗時方法.idlehandler

包體積優(yōu)化

  1. 圖片資源壓縮 tinypng ,也可使用webp 有損壓縮, 支持透明通道
  2. 盡量用 xml shape 替代切圖,或者使用.9png 替代大圖
  3. release去除多余so,保留 arm-v7
  4. 只保留一xxhdpi的切圖 可使用字節(jié)跳動的方案 解決適配問題
    原理 px = dp * density 去根據(jù)寬度修改 density,保證 寫死dp的和寬度的比例 去適配不同的寬度
  5. 方舟編譯器
  6. 混淆
  7. 去除無用資源 ,去除用的語言支持
defaultConfig {
        resConfigs "zh"
    }
 buildTypes {
        release {
            shrinkResources true
        }
    }
  1. 大殺器 插件化
  2. gradle provided ,根據(jù)不同渠道,可能有不同的功能, 使用provider,會讓你通過編譯,但不會加入到apk
  3. redex 是 Facebook 開源的一款字節(jié)碼優(yōu)化工具
  4. 減少gc次數(shù)

內(nèi)存優(yōu)化

檢測工具:leakCanary mat
避免頻繁gc 每次gcandroid系統(tǒng)可能會凍結(jié)200ms

image.png

避免內(nèi)存占用過多

  1. 使用 高效的數(shù)據(jù)結(jié)構(gòu) SparseArray 不是線程安全的
    sparseArray<E> 替代 hashmap<Integer,E>
    sparseBooleanArray 替代 hashmap<Integer,Boolean
    sparseIntArray替代 hashmap<Integer,Integer>
  2. 大圖加載 使用 瓦片的形式 加載 顯示的部分
  3. Lru 過期內(nèi)存中的對象,防止長期占用
  4. 內(nèi)存告警的時候及時釋放對象,(圖片)
  5. 避免使用線程池自帶的四種構(gòu)造方式 可能oom

避免內(nèi)存泄漏

  1. context被靜態(tài)變量持有
  2. context被單例持有
  3. context被屬性動畫持有, ondestory 要cancel動畫
  4. context1被內(nèi)部類持有 被handler持有, 要使用靜態(tài)內(nèi)部類
  5. context被application持有
  6. 資源沒關(guān)閉造成內(nèi)存泄露 bitmap

總結(jié)

1、對于生命周期比Activity長的對象如果需要應(yīng)該使用ApplicationContext,在需要使用Context參數(shù)的時候先考慮Application.Context.
2、在引用組件Activity,F(xiàn)ragment時,優(yōu)先考慮使用弱引用。
3、在使用異步操作時注意Activity銷毀時,需要清空任務(wù)列表,如果有使用集合,將集合清空并置空,釋放相應(yīng)的資源。
4、內(nèi)部類持有外部類的引用盡量修改成靜態(tài)內(nèi)部類中使用弱引用持有外部類的引用。
5、 留意活動的生命周期,在使用單例,靜態(tài)對象,全局性集合的時候應(yīng)該特別注意置空。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,739評論 6 534
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,634評論 3 419
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,653評論 0 377
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,063評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,835評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,235評論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,315評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,459評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,000評論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,819評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,004評論 1 370
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,560評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,257評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,676評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,937評論 1 288
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,717評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,003評論 2 374