幾乎是史上最全最實用的Android性能全面分析與優化方案研究

2021-02-25 Android技術之家
結合以下四個部分講解:

性能問題分類

性能優化原則和方法

藉助性能優化工具分析解決問題

性能優化指標

性能問題分類

1、渲染問題: 過度繪製、布局冗雜

2、內存問題: 內存浪費(內存管理)、內存洩漏

3、功耗問題: 耗電

性能優化原則和方法

1、性能優化原則

堅持性能測試(開發和測試同學的測試方法略有不同):不要憑感覺去檢測性能問題、評估性能優化的效果,應該保持足夠多的測量,用數據說話(主要針對測試同學)。使用各種性能工具測試及快速定位問題(主要針對開發同學)。

使用低配置的設備:同樣的程序,在低端配置的設備中,相同的問題會暴露得更為明顯。

權衡利弊:在能夠保證產品穩定、按時完成需求的前提下去做優化。

2、優化方法

了解問題(分為可感知和不可感知的性能問題):對於性能問題來講,這個步驟只適用於某些明顯的性能問題,很多無法感知的性能問題需要通過工具定位。例如:內存洩漏、層級冗雜、過度繪製等無法感知。滑動卡頓是可以感知到的。

定位問題:通過工具檢測、分析數據,定位在什麼地方存在性能問題。

分析問題:找到問題後,分析針對這個問題該如何解決,確定解決方案。

解決問題:根據分析結果尋找解決方案。

驗證問題:保證優化有效,沒有產生新的問題,以及產品穩定性。

性能優化工具

以下優化工具在下面文章中具體介紹使用方法。

1、手機開發者選項:調試GPU過度繪製、啟用嚴格模式、顯示CPU使用情況、GPU呈現模式分析、顯示所有"應用程式無響應"。(小米手機開發開發者選項中名字)

2、IDE中:Android Studio,比如靜態代碼檢測工具、Memory Monitor、CPU Monitor、NetWork Monitor、GPU Monitor、Layout Inspector、Analyze APK等。

3、SDK中:sdk\tools,比如DDMS、HierarchyViewer、TraceView等。

4、第三方工具:MAT、LeakCanary、GT等。

性能優化指標

1、渲染

滑動流暢度:FPS,即Frame per Second,一秒內的刷新幀數,越接近60幀越好;

過度繪製:單頁面的3X(粉紅色區域) Overdraw小於25%

啟動時間:這裡主要說的是Activity界面啟動時間,一般低於300ms,需要用高頻攝像機計算時間。

2、內存

內存大小:峰值越低越好,需要優化前後做對比

內存洩漏:需要用工具檢查對比優化前後

3、功耗

一、渲染問題

先來看看造成應用UI卡頓的常見原因都有哪些?

1、人為在UI線程中做輕微耗時操作,導致UI線程卡頓;

2、布局Layout過於複雜,無法在16ms內完成渲染;

3、同一時間動畫執行的次數過多,導致CPU或GPU負載過重;

4、View過度繪製,導致某些像素在同一幀時間內被繪製多次,從而使CPU或GPU負載過重;

5、View頻繁的觸發measure、layout,導致measure、layout累計耗時過多及整個View頻繁的重新渲染;

6、內存頻繁觸發GC過多(同一幀中頻繁創建內存),導致暫時阻塞渲染操作;

7、冗餘資源及邏輯等導致加載和執行緩慢;

8、臭名昭著的ANR;

大多數用戶感知到的卡頓等性能問題的最主要根源都是因為渲染性能。(Google官方說的)

Android系統每隔16ms發出VSYNC信號(vertical synchronization --場掃描同步,場同步,垂直同步),觸發對UI進行渲染,如果每次渲染都成功,這樣就能夠達到流暢的畫面所需要的60fps,為了能夠實現60fps,這意味著程序的大多數操作都必須在16ms(1000/60=16.67ms)內完成。

如果你的某個操作花費時間是24ms,系統在得到VSYNC信號的時候就無法進行正常渲染,這樣就發生了丟幀現象。那麼用戶在32ms內看到的會是同一幀畫面。

1、過度繪製

Overdraw(過度繪製)描述的是屏幕上的某個像素在同一幀的時間內被繪製了多次。在多層次的UI結構裡面,如果不可見的UI也在做繪製的操作,這就會導致某些像素區域被繪製了多次。這就浪費大量的CPU以及GPU資源,找出界面滑動不流暢、界面啟動速度慢、手機發熱。

如何查看過度繪製?

設置 — 開發中選項 — 調試GPU過度繪製

來看看手雷裡的過度繪製和優化效果(目前手雷還存在很多待優化的頁面)

上圖中的各種顏色都代表什麼意思?

 每個顏色的說明如下:  原色:沒有過度繪製  紫色:1 次過度繪製  綠色:2 次過度繪製  粉色:3 次過度繪製  紅色:4 次及以上過度繪製

造成過度優化的關鍵是什麼?多餘的背景(Background)

接下來舉例說明:

1、MainTabActivity

在MainTabActivity的Theme中修改背景

去除布局(main_activity_linerlayout.xml)中的background

如果不給當前Activity設置主題,默認主題是什麼,默認主題背景是什麼?

 可以在默認主題中添加通用主題背景  <item name="android:windowBackground">@drawable/common_layout_content_bkg</item>  去除背景  <item name="android:windowBackground">null</item>

2、除了布局中多餘背景,還有可能在代碼裡添加了多餘的背景。

查看分享彈窗的布局代碼發現只有一個background,但為什麼會過度繪製呢?

代碼修改(SharePlatformsDialog.java)

3、彈窗底部布局不會導致彈窗本身過度繪製

彈窗的繪製是屬於剪切式繪製不是覆蓋繪製,蒙層是透明度亮度的調節不是繪製一層灰色。如果我們不想用系統dialog而是自定義一個彈窗view,就需要考慮過度繪製問題。

4、自定義view時,通過Canvas的clipRect方法控制每個視圖每次刷新的區域,這樣可以避免刷新不必要的區域,從而規避過渡繪製的問題。還可以使用canvas.quickreject()來判斷是否和某個矩形相交,從而跳過那些非矩形區域內的繪製操作。參考:jaeger.itscoder.com/android/201…

優化方法和步驟關鍵總結

 總結一下,優化步驟如下:  1、移除或修改Window默認的Background  2、移除XML布局文件中非必需的Background  3、按需顯示佔位背景圖片  4、控制繪製區域

2、布局優化

布局太過複雜,層級嵌套太深導致繪製操作耗時,且增加內存的消耗。

我們的目標就是,層級扁平化

3、介紹一下查看渲染性能的工具二、內存問題1、內存浪費

程序內存的管理是否合理高效對應用的性能有著很大的影響。

推薦閱讀Android性能優化典範-第3季,參考:hukai.me/android-per…

 1、對象個數的數量級最好是千以內,沒有頻繁的插入刪除操作  2、數據組織形式包含Map結構

Autoboxing(避免自動裝箱)

Autoboxing的行為還經常發生在類似HashMap這樣的容器裡面,對HashMap的增刪改查操作都會發生了大量的autoboxing的行為。當key是int類型的時候,HashMap和ArrayMap都有Autoboxing行為。

SparseArray(項目中用到較多 -- 後面再說如何利用工具查找該用SparseArray而沒有用到的地方)

為了避免Autoboxing行為Android提供了SparseArray,此容器使用於key為int類型

SparseBooleanMap,SparseIntMap,SparseLongMap等容器,是key為int,value類型相應為boolean、int、long等。

Enum(枚舉,項目中較多使用,應儘量避免)

Enums often require more than twice as much memory as static constants. You should strictly avoid using enums on Android.

Android官方強烈建議不要在Android程序裡面使用到enum。

關於enum的效率,請看下面的討論。假設我們有這樣一份代碼,編譯之後的dex大小是2556 bytes,在此基礎之上,添加一些如下代碼,這些代碼使用普通static常量相關作為判斷值:

增加上面那段代碼之後,編譯成dex的大小是2680 bytes,相比起之前的2556 bytes只增加124 bytes。假如換做使用enum,情況如下:


使用enum之後的dex大小是4188 bytes,相比起2556增加了1632 bytes,增長量是使用static int的13倍。不僅僅如此,使用enum,運行時還會產生額外的內存佔用,如下圖所示:


推薦一些文章:

HashMap,ArrayMap,SparseArray源碼分析及性能對比,參考:www.jianshu.com/p/7b9a1b386…

Android性能優化--小心自動裝箱:blog.csdn.net/lgz_ei/arti…

Android性能優化篇:Android中如何避免創建不必要的對象:blog.csdn.net/jia635/arti…

HashMap、ArrayMap、SparseArray分析比較:blog.csdn.net/chen_lifeng…

Android性能優化之String篇:www.androidchina.net/5940.html

SharedPreferences的commit和apply分析:blog.csdn.net/u010198148/…

2、內存洩漏

什麼是內存洩漏?

一些不用的對象被長期持有,導致內存無法被釋放。

可能發生內存洩漏的地方有哪些?

內部類引用導致Activity的洩漏

在Java中,非靜態(匿名)內部類會默認隱性引用外部類對象。而靜態內部類不會引用外部類對象。

最典型的場景是Handler導致的Activity洩漏,如果Handler中有延遲的任務或者是等待執行的任務隊列過長,都有可能因為Handler繼續執行而導致Activity發生洩漏。

為了解決這個問題,可以在UI退出之前,執行remove Handler消息隊列中的消息與runnable對象。或者是使用Static + WeakReference的方式來達到斷開Handler與Activity之間存在引用關係的目的。

舉例,MainTabActivity - MainTabHandler:


如何修復?

Android Weak Handler:可以避免內存洩漏的Handler庫,參考:www.jcodecraeer.com/a/anzhuokai…

Activity Context被傳遞到其他實例中,這可能導致自身被引用而發生洩漏。

考慮使用Application Context而不是Activity Context。

例如:全局Dialog或者Context被單例持有。

靜態造成的內存洩漏

還有靜態變量持有View,例如:

 private static View view;  void setStaticView() {      view = findViewById(R.id.sv_button);  }

注意監聽器的註銷(稍後利用工具分析一個例子)

regist就要unregist

注意Cursor對象是否及時關閉(項目中也存在,不再列舉)

WebView的引起的洩漏(暫時沒有研究)

使用工具分析定位解決內存洩漏

內存使用策略優化

onLowMemory():Android系統提供了一些回調來通知當前應用的內存使用情況,通常來說,當所有的background應用都被kill掉的時候,forground應用會收到onLowMemory()的回調。在這種情況下,需要儘快釋放當前應用的非必須的內存資源,從而確保系統能夠繼續穩定運行。

onTrimMemory(int):Android系統從4.0開始還提供了onTrimMemory()的回調,當系統內存達到某些條件的時候,所有正在運行的應用都會收到這個回調,同時在這個回調裡面會傳遞參數,代表不同的內存使用情況,收到onTrimMemory()回調的時候,需要根據傳遞的參數類型進行判斷,合理的選擇釋放自身的一些內存佔用,一方面可以提高系統的整體運行流暢度,另外也可以避免自己被系統判斷為優先需要殺掉的應用。

看看下載一個視頻加上瀏覽一下精選頁,然後將應用切到後臺,內存使用情況

有什麼優化內存的策略

文章推薦:

Android內存優化之OOM:hukai.me/android-per…

內存洩露從入門到精通三部曲之基礎知識篇:bugly.qq.com/bbs/forum.p…

內存洩露從入門到精通三部曲之排查方法篇:bugly.qq.com/bbs/forum.p…

內存洩露從入門到精通三部曲之常見原因與用戶實踐:bugly.qq.com/bbs/forum.p…

胡凱Android性能典範系列

3、性能優化必備神器推薦(Lint)

上面分析的一些項目中的問題,怎麼找到的呢?

Lint:靜態代碼分析工具

如何通過Lint查找項目中的問題,如何使用?

如果只想分析某個文件夾的代碼

設置代碼分析選項

作者:李通
連結:https://juejin.im/post/5ad2bfaf51882555867fdd09
來源:掘金
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。

相關焦點

  • Android性能優化:手把手帶你全面實現內存優化
    最近有想換工作的同學們,可參考《5月技術崗位內推|RN開發招聘啦》,再往下看,一篇關於性能優化的好文章,很值得去學習。前言在 Android開發中,性能優化策略十分重要本文主要講解性能優化中的內存優化,希望你們會喜歡目錄
  • Android性能優化:帶你全面實現內存優化
    本文主要講解性能優化中的內存優化,希望你們會喜歡目錄1.常見的內存問題 & 優化方案常見的內存問題如下內存洩露內存抖動圖片Bitmap相關代碼質量 & 數量日常不正確使用下面,我將詳細分析每項的內存問題 & 給出優化方案4.1 內存洩露簡介即 ML
  • Android開發必備的「80」個開源庫
    你所不知道的Android Studio調試技巧https://www.jianshu.com/p/011eb88f4e0d一份系統、全面的安卓進階學習指南https://github.com/iwannabetop/Awesome-Android-Learning-GuideTrinea - 性能優化系列總篇
  • Android性能優化--內存優化
    本文來自Dotry投稿,連結:https://www.jianshu.com/p/38b627adaecd上一篇文章關於Android性能優化--啟動優化探討了啟動優化相關的知識點,在本篇將介紹內存優化的相關優化。
  • 最全的Android內存優化技巧
    本文主要介紹性能優化的一些手段,但是為了便於理解以及融會貫通,建議先了解Android內存管理機制,本文將從四個角度來介紹內存優化技巧減小對象的內存佔用儘量減少新分配出來的對象佔用內存的大小,使用更加輕量的對象1.
  • Android性能優化典範
    摘要:Google在Udacity上的《Android性能優化》在線課程詳細介紹了該如何優化性能,這些課程是Google之前在Youtube上發布的Android性能優化典範專題課程的細化與補充。本文是對渲染、運算、內存、電量四個篇章的學習筆記。
  • Android性能優化總結
    這是來自一位粉絲「MeloDev」的投稿,講真,我這裡投稿的不少,但是只有我自己覺得很不錯的才會通過,這篇文章我覺得對大家有用,而且性能優化也算是我面試必問的一個話題了,所以這裡推薦給大家。寫在前面公司給了我一周的時間去學習Android性能的優化,參考了張明雲老師的一片文章,並且用公司的實際項目進行測試(附有截圖),還進行了一些知識點,注意事項以及很多網址連結的補充,希望這篇博文能讓做性能測試的朋友們少走一些彎路。文中沒有貼出大段代碼,但是幾乎所有的知識點都有連結,點進去就能看你想看的。轉載註明出處。
  • Android應用耗電量分析與優化建議
    ,從手機中導出bugreport文件上傳至頁面,在網頁中生成詳細的圖表數據來展示手機上各模塊電量消耗過程,最後通過App數據的分析制定出相關的電量優化的方法。可參考:https://github.com/google/battery-historianApp電量消耗分析工具安裝成功後我們需要從手機上導出數據進行分析# 將bugreport的信息保存到.zip文件中$ adb bugreport bugreport.zipAndroid 6.0以下系統請使用以下導出命令# 將bugreport
  • Android性能優化典範(一)
    首先你需要在activity處於前臺的時候使用Heap Tool獲取一份當前狀態的內存快照,然後你需要創建一個幾乎不這麼佔用內存的空白activity用來給前一個Activity進行跳轉,其次在跳轉到這個空白的activity的時候主動調用System.gc()方法來確保觸發一個GC操作。
  • ​吹爆系列:深入探索 Android 包體積優化
    瘦身優化,瘦身優化 最主要的好處是對應用 下載轉化率 的影響,它是 App 業務運營的重要指標之一,在項目精細化運營的階段是非常重要的。2、So 移除方案優化版上面我們說到了想要完美支持所有類型的設備代價太大,那麼,我們能不能採取一個 折中的方案,就是 對於性能敏感的模塊,它使用到的 So,我們都放在 armeabi 目錄當中隨著 Apk 發出去,然後我們在代碼中來判斷一下當前設備所屬的 CPU 類型,根據不同設備 CPU 類型來加載對應架構的 So 文件。
  • 丹佛斯解決方案:讓您的冷藏展示櫃性能最優化
    2015年,F-Gas法規出臺了,被譽為歐盟史上最嚴控制溫室氣體法規,進一步減少氟化氣體(包括HFCs、PFCs、SF6)的排放,以期最大程度降低全球變暖潛值(GWP)。  隨著F-Gas法規的推出,主導產業逐漸走向綠色環保的道路,需要尋找替代的冷媒來支持低 GWP 製冷劑的玻璃門陳列櫃的生產和其他食品服務設備的增長。但是在選擇低 GWP 值製冷劑時冷藏展示櫃將隨之發生怎樣的變化?
  • 可能是目前最全的《Android面試題及解析》(379頁)
    趁著這段時間,小夥伴們可以參考這份可能是市面上最全面的安卓面試題解析大全!從基礎到架構進階,包含了騰訊、百度、小米、阿里、樂視、美團、58、獵豹、360、新浪、搜狐等一線網際網路公司面試被問到的題目,涵蓋了初中高級安卓技術點。文章中所列主要為大綱部分,詳細內容可以在文末自行獲取哈!
  • 最全最實用!2019最新增值稅稅率表
    最全最實用!
  • QQ音樂Android客戶端Web頁面通用性能優化實踐
    QQ音樂 Android 客戶端的 Web 頁面日均 PV 達到千萬量級,然而頁面的打開耗時與 Native 頁面相距甚遠,需要系統性優化。本文將介紹 QQ 音樂 Android 客戶端在進行 Web 頁面通用性能優化過程中的問題、思路、方案和效果,並嘗試對跨端場景的常見瓶頸和對策進行歸納。文章作者:關嶽,QQ音樂客戶端開發工程師。
  • 吹爆系列:深入探索Android穩定性優化
    https://github.com/JsonChao/Awesome-Android-Exercise眾所周知,移動開發已經來到了後半場,為了能夠在眾多開發者中脫穎而出,我們需要對某一個領域有深入地研究與心得,對於Android開發者來說,目前,有幾個好的細分領域值得我們去建立自己的技術壁壘,如下所示:性能優化專家:具備深度性能優化與體系化APM建設的能力
  • Google 發布 Android 性能優化典範 - OSCHINA - 中文開源技術交流...
    課程專題不僅僅介紹了Android系統中有關性能問題的底層工作原理,同時也介紹了如何通過工具來找出性能問題以及提升性能的建議。主要從三個方面展開,Android的渲染機制,內存與GC,電量優化。下面是對這些問題和建議的總結梳理。0)Render Performance大多數用戶感知到的卡頓等性能問題的最主要根源都是因為渲染性能。
  • 2019年建築業最新增值稅稅率表,最全最實用!
    2019年建築業最新增值稅稅率表,最全最實用!
  • [JAVA] 85天 精通JAVAEE+Android 黑馬程式設計師JavaEE+Android培訓課程60G
    該項目採用經典的MVC設計模式,從需求分析到編碼將涉及到Java Web大部分常見的技術,讓學員理解真實項目的軟體開發流程(分析、設計、編碼、測試、部署),通過此項目的鍛鍊學員可以熟練掌握基本的Java Web開發和複雜問題的解決方案,為後面的學習奠定基礎., 同時又為成功就職軟體企業邁出堅實的一步。.
  • android 復用 布局優化專題及常見問題 - CSDN
    在布局優化中,Androi的官方提到了這三種布局<include />、<merge />、<ViewStub />,並介紹了這三種布局各有的優勢,下面也是簡單說一下怎麼使用.
  • android內存優化總結
    而內存使用長時間不降低下來肯定是因為對象使用後還被引用著導致未被銷毀,當遇到這些情況後,我們要引入下一個工具了MAT使用MAT分析內存http://my.oschina.net/biezhi/blog/286223,這塊內容比較多,我也是參考博文進行分析的,具體的大家可以通過這篇文章來了解和發現內存使用情況。