Android比較實用的性能優化

来源:https://www.cnblogs.com/rsq-Celtic/archive/2018/06/08/9154665.html
-Advertisement-
Play Games

Android設備作為一種移動設備,無論是記憶體還是CPU的性能都受到了很大的限制,這導致Android程式的性能問題異常突出,隨著產品的不斷更新迭代,對於性能優化提出了更高的要求。本篇文章從穩定性、流暢性、耗損、安裝包大小四個方面對Android開發提供了一些容易上手、切實有效的性能優化方法,為An ...


  Android設備作為一種移動設備,無論是記憶體還是CPU的性能都受到了很大的限制,這導致Android程式的性能問題異常突出,隨著產品的不斷更新迭代,對於性能優化提出了更高的要求。本篇文章從穩定性、流暢性、耗損、安裝包大小四個方面對Android開發提供了一些容易上手、切實有效的性能優化方法,為Android開發中有關性能優化方面的學習提供一個參考。

1.穩定性(解決記憶體溢出、崩潰等問題),記憶體優化

瞭解記憶體如何分配和回收機制,對記憶體優化會有一定的認識和掌握。可以藉助記憶體分析工具,方便定位需要記憶體優化的代碼。

(1)Memory Monitor 工具:

  Android Studio自帶的一個記憶體監視工具,它可以很好地幫助我們進行記憶體實時分析。通過點擊Android Studio右下角的Memory Monitor標簽,打開工具可以看見較淺藍色代表free的記憶體,而深色的部分代表使用的記憶體從記憶體變換的走勢圖變換,可以判斷關於記憶體的使用狀態,例如當記憶體持續增高時,可能發生記憶體泄漏;當記憶體突然減少時,可能發生GC等

(2)Memory Analyzer 工具:

  MAT(Memory Analyzer Tool) 是一個快速,功能豐富的 Java Heap 分析工具,通過分析 Java 進程的記憶體快照 HPROF 分析,從眾多的對象中分析,快速計算出在記憶體中對象占用的大小,查看哪些對象不能被垃圾收集器回收,並可以通過視圖直觀地查看可能造成這種結果的對象。 檢測步驟如下:

(a)屏幕多次翻轉,出現記憶體持續增高時。點擊 Dump java Heap就會生成運行記憶體快照hprof文件。

(b)然後將APP完全退出,重新啟動,打開Android Monitor 再次點擊Dump java Heap 生成一份還沒操作(旋轉屏幕)前的記憶體快照hprof文件。現在就已經生成好了2份hprof文件, 一份是沒有旋轉過屏幕的 ,一份是旋轉過屏幕多次的。

(c)然後選中Android Studio 最左邊的Captures 進行將hprof文件導出。導出的時候需要選擇保存的目錄以及文件名。

(d)打開MAT ,導入我們的2個hprof文件 Open File-->選擇文件-->Leak Suspects Report-->Finish

可以通過檢索包名,查看某個類的實例個數和所在記憶體數據,還可以查看被引用的記憶體數據。

  Objects:實例個數
  Shallow Heap:所占記憶體大小
  Retained Heap:釋放後能回收多少記憶體

(3)LeakCanary工具:

  簡單,傻瓜式操作。可以在GitHup官網查閱https://github.com/square/leakcanary,我們可以在Gradle文件里添加依賴。這個工具是Square公司在Github開源的。行業內不是有一句話嘛,Square出品必屬精品,主流的庫像okhttp、Picasso、retrofit、Dagger等都出自Square之手。說到這不得不讓我聯想到一位在Android開發領域神一般存在的人物,他就是大名鼎鼎的Jake Wharton(傑克.沃頓),ButterKnife的創造者,也參與貢獻了Retrofit, okhttp等。

 

(4)Android Lint 工具:

 

    Android Lint Tool 是Android Sutido種集成的一個Android代碼提示工具,它可以給你佈局、代碼提供非常強大的幫助。 硬編碼會提示以級別警告,例如:在佈局文件中寫了三層冗餘的LinearLayout佈局、直接在TextView中寫要顯示的文字、字體大小使用dp而不是sp為單位,就會在編輯器右邊看到提示。使用Android Studio的lint可以清除無用的資源文件(點擊菜單欄的Analyze -> Run Inspection by Name, 輸入unused resource)。     當然以上都是一個簡單的舉例,Lint的功能非常強大,大家應該養成寫完代碼查看Lint的習慣,這不僅讓你及時發現代碼種隱藏的一些問題,更能讓你養成良好的代碼風格,要知道,這些Lint提示可都是Google大牛們汗水合智慧的結晶。

小結

    影響穩定性的原因很多,比如記憶體使用不合理、代碼異常場景考慮不周全、代碼邏輯不合理等,都會對應用的穩定性造成影響。其中最常見的兩個場景是:Crash 和 ANR,這兩個錯誤將會使得程式無法使用。所以做好Crash全局監控,處理閃退同時把崩潰信息、異常信息收集記錄起來,以便後續分析;合理使用主線程處理業務,不要在主線程中做耗時操作,防止ANR程式無響應發生。

 

2.流暢性(卡頓優化)

卡頓的場景通常是發生在用戶交互體驗最直接的方面。影響卡頓的兩大因素,分別是界面繪製和數據處理。
  • 界面繪製:主要原因是繪製的層級深、頁面複雜、刷新不合理,由於這些原因導致卡頓的場景更多出現在 UI 和啟動後的初始界面以及跳轉到頁面的繪製上。
  • 數據處理:導致這種卡頓場景的原因是數據處理量太大,一般分為三種情況,一是數據在處理 UI 線程,二是數據處理占用 CPU 高,導致主線程拿不到時間片,三是記憶體增加導致 GC 頻繁,從而引起卡頓。
卡頓場景大概分為四個方面,如下圖所示。  

分析UI卡頓:

    我們知道Android的繪製步驟是:Measure、Layout、Draw,所以佈局的層級越深、元素越多、耗時也就越長。還有就是Android操作系統每隔 16ms 發出 VSYNC 信號,觸發對 UI 進行渲染,如果每次渲染都成功,這樣就能夠達到流暢的畫面所需的 60FPS。如果某個操作花費的時間是 24ms ,系統在得到 VSYNC 信號時就無法正常進行正常渲染,這樣就發生了丟幀現象。那麼用戶在 32ms 內看到的會是同一幀畫面,無法在 16ms 完成渲染,最終引起刷新不及時。

    總結以上,兩個根本原因:1、繪製任務太重,繪製一幀內容耗時太長;2、主線程太忙,根據系統傳遞過來的 VSYNC 信號來時,還沒準備好數據,導致丟幀。

(1)佈局優化

    在Android種系統對View進行測量、佈局和繪製時,都是通過對View數的遍歷來進行操作的。如果一個View數的高度太高就會嚴重影響測量、佈局和繪製的速度。Google也在其API文檔中建議View高度不宜哦過10層。現在版本種Google使用RelativeLayout替代LineraLayout作為預設根佈局,目的就是降低LineraLayout嵌套產生佈局樹的高度,從而提高UI渲染的效率。
  • 佈局復用,使用<include>標簽重用layout;
  • 提高顯示速度,使用<ViewStub>延遲View載入;
  • 減少層級,使用<merge>標簽替換父級佈局;
  • 註意使用wrap_content,會增加measure計算成本;

  • 刪除控制項中無用屬性;

(2)繪製優化

    過度繪製是指在屏幕上的某個像素在同一幀的時間內被繪製了多次。在多層次重疊的 UI 結構中,如果不可見的 UI 也在做繪製的操作,就會導致某些像素區域被繪製了多次,從而浪費了多餘的 CPU 以及 GPU 資源。如何避免過度繪製?
  • 佈局上的優化。移除 XML 中非必須的背景,移除 Window 預設的背景、按需顯示占位背景圖片

  • 自定義View優化。使用 canvas.clipRect() 幫助系統識別那些可見的區域,只有在這個區域內才會被繪製。

(3)啟動優化

    應用一般都有閃屏頁SplashActivity,優化閃屏頁的 UI 佈局,可以通過 Profile GPU Rendering 檢測丟幀情況。

    (另外,還可以IDE自帶的一款UI繪製檢測圖形化數據分析工具 Systrace ,4.0版本以上版本可以使用。)

 閃屏頁的存在可以說就是啟動優化,通常在閃屏頁延遲2秒跳轉到主界面但是在進入首頁的時候,首頁複雜的View渲染以及必須在UI線程執行的業務邏輯,必然拖慢了啟動速度。啟動閃屏頁雖然簡單執行快,首頁卻複雜執行慢,應用啟動前輕後重。

    所以要啟動載入邏輯優化。可以採用分佈載入、非同步載入、延期載入策略來提高應用啟動速。例如,把SplashActivity改成SplashFragment,應用程式的入口變成MainActivity,在MainActivity中先展示SplashFragment,顯示完畢後再移除SplashFragment。這樣,在SplashFragment的2S的友好時間內進行數據準備的同時,首頁的View就能夠被載入,首頁的業務邏輯就能夠被執行。在閃屏頁視窗載入完畢後,我們載入activity_main的佈局,考慮到這個佈局有可能比較複雜,耽誤View的解析時間,可以採用ViewStub的形式進行懶載入。

(4)刷新優化

  1. 減少刷新次數;
  2. 縮小刷新區域;

(5)動畫優化

      需要實現動畫效果時,需要根據不同場景選擇合適的動畫框架來實現。有些情況下,可以用硬體加速方式來提供流暢度降低動畫卡頓。

3.耗損(耗電、流量消耗)

 3.1耗電優化

在移動設備中,電池的重要性自然不言而喻,如果手機沒電了應用功能技術實現再怎麼牛逼,用戶也什麼都幹不成。對於Android操作系統和設備各大開發商來說,對手機耗電的優化從沒有停止過,不斷地追求更長的待機時間。而對於開發一款應用來說,絕不可以忽略電量耗損的問題,被歸為“電池殺手”的應用,最終的結果無疑是走向被用戶卸載的道路。比如,有些應用為了保持應用進程長期在後臺存活,使用各種不合理進程保活方案,破壞操作系統“生態平衡”,導致用戶電量嚴重耗損,雖然這種流氓開發行為並不違法吧,但是也屬於不道德的行為,也同樣會被同行所被鄙視的行為。

 

    在 Android5.0 以前,關於應用電量消耗的測試即麻煩又不准確,而5.0 之後Google專門引入了一個獲取設備上電量消耗信息的API—— Battery Historian。Battery Historian 是一款由 Google 提供的 Android 系統電量分析工具,直觀地展示出手機的電量消耗過程,通過輸入電量分析文件,顯示消耗情況。

 

    最後提供一些可供參考耗電優化的方法:

(1)計算優化。演算法for迴圈優化Switch..case替代if..else、避開浮點運算。

        浮點運算:電腦里整數和小數形式就是按普通格式進行存儲,例如1024、3.1415926等等,這個沒什麼特點,但是這樣的數精度不高,表達也不夠全面,為了能夠有一種數的通用表示法,就發明瞭浮點數。浮點數的表示形式有點像科學計數法(*.*****×10^***),它的表示形式是0.*****×10^***,在電腦中的形式為 .***** e ±***),其中前面的星號代表定點小數,也就是整數部分為0的純小數,後面的指數部分是定點整數。利用這樣的形式就能表示出任意一個整數和小數,例如1024就能表示成0.1024×10^4,也就是 .1024e+004,3.1415926就能表示成0.31415926×10^1,也就是 .31415926e+001,這就是浮點數。浮點數進行的運算就是浮點運算。浮點運算比常規運算更複雜,因此電腦進行浮點運算速度要比進行常規運算慢得多。

(2)避免 Wake Lock 使用不當。

    Wake Lock是一種鎖的機制,主要是相對系統的休眠而言的,,只要有人拿著這個鎖,系統就無法進入休眠意思就是我的程式給CPU加了這個鎖那系統就不會休眠了,這樣做的目的是為了全力配合我們程式的運行。有的情況如果不這麼做就會出現一些問題,比如微信等及時通訊的心跳包會在熄屏不久後停止網路訪問等問題。所以微信裡面是有大量使用到了Wake_Lock鎖。系統為了節省電量,CPU在沒有任務忙的時候就會自動進入休眠。有任務需要喚醒CPU高效執行的時候,就會給CPU加Wake_Lock鎖。大家經常犯的錯誤,我們很容易去喚醒CPU來工作,但是很容易忘記釋放Wake_Lock。  

(3)使用 Job Scheduler 管理後臺任務。

   在Android 5.0 API 21 中,google提供了一個叫做JobScheduler API的組件,來處理當某個時間點或者當滿足某個特定的條件時執行一個任務的場景,例如當用戶在夜間休息時或設備接通電源適配器連接WiFi啟動下載更新的任務。這樣可以在減少資源消耗的同時提升應用的效率。

 3.2流量優化

3.2.1 對通訊錄式、個人信息式的數據進行資料庫的存儲; 3.2.2 對瀏覽類的數據進行三級緩存

4.安裝包(縮小apk大小)

 詳見本人的另一篇文章——Android性能優化之apk終極瘦身策略
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 重要術語 1. KDC 全稱:key distributed center 作用:整個安全認證過程的票據生成管理服務,其中包含兩個服務,AS和TGS 2. AS 全稱:authentication service 作用:為client生成TGT的服務 3. TGS 全稱:ticket grantin... ...
  • OGG Error opening module ggjava_ue.dll ...
  • 1. Android 分區: 2. Android各個分區的作用: 2.1 modem分區 實現手機必需的通信功能,大家通常所的刷RADIO就是刷寫modem分區,在所有適配的ROM中這部分是不動,否則會造成通話不穩定 2.2 bootloader分區 針對高通而言,bootloader分區的內容為 ...
  • 只要是view都能設置點擊事件,不必要非得是Button。 要想實現跳轉得三步走: 第一步、綁定 每個Layout都有一個一個java文件跟它綁定,這個Layout相關的代碼都寫在這個java文件里 跳轉之前得有一個目標界面,我定義為testlayout,相關的java文件時TestActivity ...
  • 原文鏈接:https://developer.android.google.cn/guide/components/activities/intro-activitiesSS 一, 對activit的介紹 activity類是很重要的組件在安卓app中,並且activit被啟動的方式和組合方式是平臺 ...
  • 剛開始學Android開發的時候,沒有H5的基礎總是分不清android佈局文件的用法,真正要學會android佈局還是得實戰一次,下麵不多說,直接上代碼。 這是一個登陸界面,LinerLayout嵌套RelativeLayout的佈局,去掉我寫的註釋就可以直接使用: 上面展示了幾個常用的控制項用法, ...
  • 本例簡單地實現Android客戶端與伺服器端交互,主要是通過客戶端輸入內容(學號)提交到伺服器端,伺服器端與資料庫交互去查詢相應信息(姓名)。根據這個做個完整的安卓登錄是沒問題的。本例資料庫伺服器都採用本地,測試時Android客戶端與服務端在同一網路中! 1、本例演示截圖: 當輸入錯誤的學號(與數 ...
  • 本文來自 網易雲社區 。 CocoaPods是iOS非常好用的類庫管理工具,可以非常方便的管理和更新項目中使用到的第三方庫,以及將自己項目中的公共組件交由它管理。 一、創建私有podspec 1、創建私有Spec Repc Spec Repo是Pods的一個索引,是一個容器,實際是一個Git倉庫,r ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...