溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android 全方位性能調優(yōu)詳解

發(fā)布時間:2020-06-20 07:03:47 來源:網絡 閱讀:828 作者:Android飛魚 欄目:移動開發(fā)

前言

說到 Android 系統(tǒng)手機,大部分人的印象是用了一段時間就變得有點卡頓,有些程序在運行期間莫名其妙的出現(xiàn)崩潰,打開系統(tǒng)文件夾一看,發(fā)現(xiàn)多了很多文件,然后用手機管家 APP 不斷地進行清理優(yōu)化 ,才感覺運行速度稍微提高了點,就算手機在各種性能跑分軟件面前分數(shù)遙遙領先,還是感覺無論有多大的內存空間都遠遠不夠用。

相信每個使用 Android 系統(tǒng)的用戶都有過以上類似經歷,確實,Android 系統(tǒng)在流暢性方面不如 IOS 系統(tǒng),為何呢,明明在看手機硬件配置上時,Android 設備都不會輸于 IOS 設備,甚至都強于它,關鍵是在于軟件上。造成這種現(xiàn)象的原因是多方面的,簡單羅列幾點如下:

  • 其實近年來,隨著 Android 版本不斷迭代,Google 提供的Android 系統(tǒng)已經越來越流暢,目前最新發(fā)布的版本是?Android 8.0 Oreo?。但是在國內大部分用戶用的 Android 手機系是各大廠商定制過的版本,往往不是最新的原生系統(tǒng)內核,可能絕大多數(shù)還停留在 Android 5.0 系統(tǒng)上,甚至 Android 6.0 以上所占比例還偏小,更新存在延遲性。

  • 由于 Android 系統(tǒng)源碼是開放的,每個人只要遵從相應的協(xié)議,就可以對源碼進行修改,那么國內各個廠商就把基于 Android 源碼改造成自己對外發(fā)布的系統(tǒng),比如我們熟悉的小米手機 Miui 系統(tǒng)、華為手機 EMUI 系統(tǒng)、Oppo 手機 ColorOS 系統(tǒng)等。由于每個廠商都修改過 Android 原生系統(tǒng)源碼,這里面就會引發(fā)一個問題,那就是著名的Android 碎片化問題,本質就是不同 Android 系統(tǒng)的應用兼容性不同,達不到一致性。

  • 由于存在著各種?Android 碎片化和兼容性問題,導致 Android 開發(fā)者在開發(fā)應用時需要對不同系統(tǒng)進行適配,同時每個 Android 開發(fā)者的開發(fā)水平參差不齊,寫出來的應用性能也都存在不同類型的問題,導致用戶在使用過程中用戶體驗感受不同,那么有些問題用戶就會轉化為 Android 系統(tǒng)問題,進而影響對Android 手機的評價。

性能優(yōu)化

今天想說的重點是**Android APP **性能優(yōu)化,也就是在開發(fā)應用程序時應該注意的點有哪些,如何更好地提高用戶體驗。一個好的應用,除了要有吸引人的功能和交互之外,在性能上也應該有高的要求,即時應用非常具有特色,在產品前期可能吸引了部分用戶,但是用戶體驗不好的話,也會給產品帶來不好的口碑。那么一個好的應用應該如何定義呢?主要有以下三方面:

  • 業(yè)務/功能

  • 符合邏輯的交互

  • 優(yōu)秀的性能

眾所周知,Android 系統(tǒng)作為以移動設備為主的操作系統(tǒng),硬件配置是有一定的限制的,雖然配置現(xiàn)在越來越高級,但仍然無法與 PC 相比,在 CPU 和內存上使用不合理或者耗費資源多時,就會碰到內存不足導致的穩(wěn)定性問題、CPU 消耗太多導致的卡頓問題等。

面對問題時,大家想到的都是聯(lián)系用戶,然后查看日志,但殊不知有關性能類問題的反饋,原因也非常難找,日志大多用處不大,為何呢?因為性能問題大部分是非必現(xiàn)的問題,問題定位很難復現(xiàn),而又沒有關鍵的日志,當然就無法找到原因了。這些問題非常影響用戶體驗和功能使用,所以了解一些性能優(yōu)化的一些解決方案就顯得很重要了,并在實際的項目中優(yōu)化我們的應用,進而提高用戶體驗。

四個方面

可以把用戶體驗的性能問題主要總結為4個類別:

  • 流暢

  • 穩(wěn)定

  • 省電、省流量

  • 安裝包小

性能問題的主要原因是什么,原因有相同的,也有不同的,但歸根到底,不外乎內存使用、代碼效率、合適的策略邏輯、代碼質量、安裝包體積這一類問題,整理歸類如下:

Android 全方位性能調優(yōu)詳解


從圖中可以看到,打造一個高質量的應用應該以4個方向為目標:快、穩(wěn)、省、小。

快:使用時避免出現(xiàn)卡頓,響應速度快,減少用戶等待的時間,滿足用戶期望。

穩(wěn):減低 crash 率和 ANR 率,不要在用戶使用過程中崩潰和無響應。

?。汗?jié)省流量和耗電,減少用戶使用成本,避免使用時導致手機發(fā)燙。

?。喊惭b包小可以降低用戶的安裝成本。

要想達到這4個目標,具體實現(xiàn)是在右邊框里的問題:卡頓、內存使用不合理、代碼質量差、代碼邏輯亂、安裝包過大,這些問題也是在開發(fā)過程中碰到最多的問題,在實現(xiàn)業(yè)務需求同時,也需要考慮到這點,多花時間去思考,如何避免功能完成后再來做優(yōu)化,不然的話等功能實現(xiàn)后帶來的維護成本會增加。

卡頓優(yōu)化

Android 應用啟動慢,使用時經常卡頓,是非常影響用戶體驗的,應該盡量避免出現(xiàn)。卡頓的場景有很多,按場景可以分為4類:UI 繪制、應用啟動、頁面跳轉、事件響應,如圖:

Android 全方位性能調優(yōu)詳解


這4種卡頓場景的根本原因可以分為兩大類:

  • 界面繪制。主要原因是繪制的層級深、頁面復雜、刷新不合理,由于這些原因導致卡頓的場景更多出現(xiàn)在 UI 和啟動后的初始界面以及跳轉到頁面的繪制上。

  • 數(shù)據處理。導致這種卡頓場景的原因是數(shù)據處理量太大,一般分為三種情況,一是數(shù)據在處理 UI 線程,二是數(shù)據處理占用 CPU 高,導致主線程拿不到時間片,三是內存增加導致 GC 頻繁,從而引起卡頓。

引起卡頓的原因很多,但不管怎么樣的原因和場景,最終都是通過設備屏幕上顯示來達到用戶,歸根到底就是顯示有問題,所以,要解決卡頓,就要先了解 Android 系統(tǒng)的顯示原理。

Android系統(tǒng)顯示原理

Android 顯示過程可以簡單概括為:Android 應用程序把經過測量、布局、繪制后的 surface 緩存數(shù)據,通過 SurfaceFlinger 把數(shù)據渲染到顯示屏幕上, 通過 Android 的刷新機制來刷新數(shù)據。也就是說應用層負責繪制,系統(tǒng)層負責渲染,通過進程間通信把應用層需要繪制的數(shù)據傳遞到系統(tǒng)層服務,系統(tǒng)層服務通過刷新機制把數(shù)據更新到屏幕上。

我們都知道在 Android 的每個 View 繪制中有三個核心步驟:Measure、Layout、Draw。具體實現(xiàn)是從 ViewRootImp 類的performTraversals() 方法開始執(zhí)行,Measure 和 Layout都是通過遞歸來獲取 View 的大小和位置,并且以深度作為優(yōu)先級,可以看出層級越深、元素越多、耗時也就越長。

真正把需要顯示的數(shù)據渲染到屏幕上,是通過系統(tǒng)級進程中的 SurfaceFlinger 服務來實現(xiàn)的,那么這個SurfaceFlinger 服務主要做了哪些工作呢?如下:

  • 響應客戶端事件,創(chuàng)建 Layer 與客戶端的 Surface 建立連接。

  • 接收客戶端數(shù)據及屬性,修改 Layer 屬性,如尺寸、顏色、透明度等。

  • 將創(chuàng)建的 Layer 內容刷新到屏幕上。

  • 維持 Layer 的序列,并對 Layer 最終輸出做出裁剪計算。

既然是兩個不同的進程,那么肯定是需要一個跨進程的通信機制來實現(xiàn)數(shù)據傳遞,在 Android 顯示系統(tǒng)中,使用了 Android 的匿名共享內存:SharedClient,每一個應用和 SurfaceFlinger 之間都會創(chuàng)建一個SharedClient ,然后在每個 SharedClient 中,最多可以創(chuàng)建 31 個 SharedBufferStack,每個 Surface 都對應一個 SharedBufferStack,也就是一個 Window。

一個 SharedClient 對應一個Android 應用程序,而一個 Android 應用程序可能包含多個窗口,即 Surface 。也就是說 SharedClient 包含的是 SharedBufferStack的集合,其中在顯示刷新機制中用到了雙緩沖和三重緩沖技術。最后總結起來顯示整體流程分為三個模塊:應用層繪制到緩存區(qū),SurfaceFlinger 把緩存區(qū)數(shù)據渲染到屏幕,由于是不同的進程,所以使用 Android 的匿名共享內存 SharedClient 緩存需要顯示的數(shù)據來達到目的。

除此之外,我們還需要一個名詞:FPS。FPS 表示每秒傳遞的幀數(shù)。在理想情況下,60 FPS 就感覺不到卡,這意味著每個繪制時長應該在16 ms 以內。但是 Android 系統(tǒng)很有可能無法及時完成那些復雜的頁面渲染操作。Android 系統(tǒng)每隔 16ms 發(fā)出 VSYNC 信號,觸發(fā)對 UI 進行渲染,如果每次渲染都成功,這樣就能夠達到流暢的畫面所需的 60FPS。如果某個操作花費的時間是 24ms ,系統(tǒng)在得到 VSYNC 信號時就無法正常進行正常渲染,這樣就發(fā)生了丟幀現(xiàn)象。那么用戶在 32ms 內看到的會是同一幀畫面,這種現(xiàn)象在執(zhí)行動畫或滑動列表比較常見,還有可能是你的 Layout 太過復雜,層疊太多的繪制單元,無法在 16ms 完成渲染,最終引起刷新不及時。

卡頓根本原因

根據Android 系統(tǒng)顯示原理可以看到,影響繪制的根本原因有以下兩個方面:

  • 繪制任務太重,繪制一幀內容耗時太長。

  • 主線程太忙,根據系統(tǒng)傳遞過來的 VSYNC 信號來時還沒準備好數(shù)據導致丟幀。

繪制耗時太長,有一些工具可以幫助我們定位問題。主線程太忙則需要注意了,主線程關鍵職責是處理用戶交互,在屏幕上繪制像素,并進行加載顯示相關的數(shù)據,所以特別需要避免任何主線程的事情,這樣應用程序才能保持對用戶操作的即時響應??偨Y起來,主線程主要做以下幾個方面工作:

  • UI 生命周期控制

  • 系統(tǒng)事件處理

  • 消息處理

  • 界面布局

  • 界面繪制

  • 界面刷新

除此之外,應該盡量避免將其他處理放在主線程中,特別復雜的數(shù)據計算和網絡請求等。

性能分析工具

性能問題并不容易復現(xiàn),也不好定位,但是真的碰到問題還是需要去解決的,那么分析問題和確認問題是否解決,就需要借助相應的的調試工具,比如查看 Layout 層次的 Hierarchy View、Android 系統(tǒng)上帶的 GPU Profile 工具和靜態(tài)代碼檢查工具 Lint 等,這些工具對性能優(yōu)化起到非常重要的作用,所以要熟悉,知道在什么場景用什么工具來分析。

1,Profile GPU Rendering

在手機開發(fā)者模式下,有一個卡頓檢測工具叫做:Profile GPU Rendering,如圖:

Android 全方位性能調優(yōu)詳解


它的功能特點如下:

  • 一個圖形監(jiān)測工具,能實時反應當前繪制的耗時

  • 橫軸表示時間,縱軸表示每一幀的耗時

  • 隨著時間推移,從左到右的刷新呈現(xiàn)

  • 提供一個標準的耗時,如果高于標準耗時,就表示當前這一幀丟失

2,TraceView

TraceView 是 Android SDK 自帶的工具,用來分析函數(shù)調用過程,可以對 Android 的應用程序以及 Framework 層的代碼進行性能分析。它是一個圖形化的工具,最終會產生一個圖表,用于對性能分析進行說明,可以分析到每一個方法的執(zhí)行時間,其中可以統(tǒng)計出該方法調用次數(shù)和遞歸次數(shù),實際時長等參數(shù)維度,使用非常直觀,分析性能非常方便。

3,Systrace UI 性能分析

Systrace 是 Android 4.1及以上版本提供的性能數(shù)據采樣和分析工具,它是通過系統(tǒng)的角度來返回一些信息。它可以幫助開發(fā)者收集 Android 關鍵子系統(tǒng),如 surfaceflinger、WindowManagerService 等 Framework 部分關鍵模塊、服務、View系統(tǒng)等運行信息,從而幫助開發(fā)者更直觀地分析系統(tǒng)瓶頸,改進性能。Systrace 的功能包括跟蹤系統(tǒng)的 I/O 操作、內核工作隊列、CPU 負載等,在 UI 顯示性能分析上提供很好的數(shù)據,特別是在動畫播放不流暢、渲染卡等問題上。

優(yōu)化建議

1,布局優(yōu)化

布局是否合理主要影響的是頁面測量時間的多少,我們知道一個頁面的顯示測量和繪制過程都是通過遞歸來完成的,多叉樹遍歷的時間與樹的高度h有關,其時間復雜度 O(h),如果層級太深,每增加一層則會增加更多的頁面顯示時間,所以布局的合理性就顯得很重要。

那布局優(yōu)化有哪些方法呢,主要通過減少層級、減少測量和繪制時間、提高復用性三個方面入手??偨Y如下:

  • 減少層級。合理使用 RelativeLayout 和 LinerLayout,合理使用Merge。

  • 提高顯示速度。使用 ViewStub,它是一個看不見的、不占布局位置、占用資源非常小的視圖對象。

  • 布局復用??梢酝ㄟ^ 標簽來提高復用。

  • 盡可能少用wrap_content。wrap_content 會增加布局 measure 時計算成本,在已知寬高為固定值時,不用wrap_content 。

  • 刪除控件中無用的屬性。

2,避免過度繪制

過度繪制是指在屏幕上的某個像素在同一幀的時間內被繪制了多次。在多層次重疊的 UI 結構中,如果不可見的 UI 也在做繪制的操作,就會導致某些像素區(qū)域被繪制了多次,從而浪費了多余的 CPU 以及 GPU 資源。

如何避免過度繪制呢,如下:

  • 布局上的優(yōu)化。移除 XML 中非必須的背景,移除 Window 默認的背景、按需顯示占位背景圖片

  • 自定義View優(yōu)化。使用 canvas.clipRect()來幫助系統(tǒng)識別那些可見的區(qū)域,只有在這個區(qū)域內才會被繪制。

3,啟動優(yōu)化

通過對啟動速度的監(jiān)控,發(fā)現(xiàn)影響啟動速度的問題所在,優(yōu)化啟動邏輯,提高應用的啟動速度。啟動主要完成三件事:UI 布局、繪制和數(shù)據準備。因此啟動速度優(yōu)化就是需要優(yōu)化這三個過程:

  • UI 布局。應用一般都有閃屏頁,優(yōu)化閃屏頁的 UI 布局,可以通過 Profile GPU Rendering 檢測丟幀情況。

  • 啟動加載邏輯優(yōu)化??梢圆捎梅植技虞d、異步加載、延期加載策略來提高應用啟動速度。

  • 數(shù)據準備。數(shù)據初始化分析,加載數(shù)據可以考慮用線程初始化等策略。

4,合理的刷新機制

在應用開發(fā)過程中,因為數(shù)據的變化,需要刷新頁面來展示新的數(shù)據,但頻繁刷新會增加資源開銷,并且可能導致卡頓發(fā)生,因此,需要一個合理的刷新機制來提高整體的 UI 流暢度。合理的刷新需要注意以下幾點:

  • 盡量減少刷新次數(shù)。

  • 盡量避免后臺有高的 CPU 線程運行。

  • 縮小刷新區(qū)域。

5,其他

在實現(xiàn)動畫效果時,需要根據不同場景選擇合適的動畫框架來實現(xiàn)。有些情況下,可以用硬件加速方式來提供流暢度。

內存優(yōu)化

在 Android 系統(tǒng)中有個垃圾內存回收機制,在虛擬機層自動分配和釋放內存,因此不需要在代碼中分配和釋放某一塊內存,從應用層面上不容易出現(xiàn)內存泄漏和內存溢出等問題,但是需要內存管理。Android 系統(tǒng)在內存管理上有一個 Generational Heap Memory 模型,內存回收的大部分壓力不需要應用層關心, Generational Heap Memory 有自己一套管理機制,當內存達到一個閾值時,系統(tǒng)會根據不同的規(guī)則自動釋放系統(tǒng)認為可以釋放的內存,也正是因為 Android 程序把內存控制的權力交給了 Generational Heap Memory,一旦出現(xiàn)內存泄漏和溢出方面的問題,排查錯誤將會成為一項異常艱難的工作。除此之外,部分 Android 應用開發(fā)人員在開發(fā)過程中并沒有特別關注內存的合理使用,也沒有在內存方面做太多的優(yōu)化,當應用程序同時運行越來越多的任務,加上越來越復雜的業(yè)務需求時,完全依賴 Android 的內存管理機制就會導致一系列性能問題逐漸呈現(xiàn),對應用的穩(wěn)定性和性能帶來不可忽視的影響,因此,解決內存問題和合理優(yōu)化內存是非常有必要的。

Android內存管理機制

Android 應用都是在 Android 的虛擬機上運行,應用 程序的內存分配與垃圾回收都是由虛擬機完成的。在 Android 系統(tǒng),虛擬機有兩種運行模式:Dalvik 和 ART。

1,Java對象生命周期

Android 全方位性能調優(yōu)詳解


一般Java對象在虛擬機上有7個運行階段:

創(chuàng)建階段->應用階段->不可見階段->不可達階段->收集階段->終結階段->對象空間重新分配階段

2,內存分配

在 Android 系統(tǒng)中,內存分配實際上是對堆的分配和釋放。當一個 Android 程序啟動,應用進程都是從一個叫做 Zygote 的進程衍生出來,系統(tǒng)啟動 Zygote 進程后,為了啟動一個新的應用程序進程,系統(tǒng)會衍生 Zygote 進程生成一個新的進程,然后在新的進程中加載并運行應用程序的代碼。其中,大多數(shù)的 RAM pages 被用來分配給Framework 代碼,同時促使 RAM 資源能夠在應用所有進程之間共享。

但是為了整個系統(tǒng)的內存控制需要,Android 系統(tǒng)會為每一個應用程序都設置一個硬性的 Dalvik Heap Size 最大限制閾值,整個閾值在不同設備上會因為 RAM 大小不同而有所差異。如果應用占用內存空間已經接近整個閾值時,再嘗試分配內存的話,就很容易引起內存溢出的錯誤。

3,內存回收機制

我們需要知道的是,在 Java 中內存被分為三個區(qū)域:Young Generation(年輕代)、Old Generation(年老代)、Permanent Generation(持久代)。最近分配的對象會存放在 Young Generation 區(qū)域。對象在某個時機觸發(fā) GC 回收垃圾,而沒有回收的就根據不同規(guī)則,有可能被移動到 Old Generation,最后累積一定時間在移動到 Permanent Generation 區(qū)域。系統(tǒng)會根據內存中不同的內存數(shù)據類型分別執(zhí)行不同的 GC 操作。GC 通過確定對象是否被活動對象引用來確定是否收集對象,進而動態(tài)回收無任何引用的對象占據的內存空間。但需要注意的是頻繁的 GC 會增加應用的卡頓情況,影響應用的流暢性,因此需要盡量減少系統(tǒng) GC 行為,以便提高應用的流暢度,減小卡頓發(fā)生的概率。

內存分析工具

做內存優(yōu)化前,需要了解當前應用的內存使用現(xiàn)狀,通過現(xiàn)狀去分析哪些數(shù)據類型有問題,各種類型的分布情況如何,以及在發(fā)現(xiàn)問題后如何發(fā)現(xiàn)是哪些具體對象導致的,這就需要相關工具來幫助我們。

1,Memory Monitor

Memory Monitor 是一款使用非常簡單的圖形化工具,可以很好地監(jiān)控系統(tǒng)或應用的內存使用情況,主要有以下功能:

  • 顯示可用和已用內存,并且以時間為維度實時反應內存分配和回收情況。

  • 快速判斷應用程序的運行緩慢是否由于過度的內存回收導致。

  • 快速判斷應用是否由于內存不足導致程序崩潰。

2,Heap Viewer

Heap Viewer 的主要功能是查看不同數(shù)據類型在內存中的使用情況,可以看到當前進程中的 Heap Size 的情況,分別有哪些類型的數(shù)據,以及各種類型數(shù)據占比情況。通過分析這些數(shù)據來找到大的內存對象,再進一步分析這些大對象,進而通過優(yōu)化減少內存開銷,也可以通過數(shù)據的變化發(fā)現(xiàn)內存泄漏。

3,Allocation Tracker

Memory Monitor 和 Heap Viewer 都可以很直觀且實時地監(jiān)控內存使用情況,還能發(fā)現(xiàn)內存問題,但發(fā)現(xiàn)內存問題后不能再進一步找到原因,或者發(fā)現(xiàn)一塊異常內存,但不能區(qū)別是否正常,同時在發(fā)現(xiàn)問題后,也不能定位到具體的類和方法。這時就需要使用另一個內存分析工具 Allocation Tracker,進行更詳細的分析, Allocation Tracker 可以分配跟蹤記錄應用程序的內存分配,并列出了它們的調用堆棧,可以查看所有對象內存分配的周期。

4,Memory Analyzer Tool(MAT)

MAT 是一個快速,功能豐富的 Java Heap 分析工具,通過分析 Java 進程的內存快照 HPROF 分析,從眾多的對象中分析,快速計算出在內存中對象占用的大小,查看哪些對象不能被垃圾收集器回收,并可以通過視圖直觀地查看可能造成這種結果的對象。

常見內存泄漏場景

如果在內存泄漏發(fā)生后再去找原因并修復會增加開發(fā)的成本,最好在編寫代碼時就能夠很好地考慮內存問題,寫出更高質量的代碼,這里列出一些常見的內存泄漏場景,在以后的開發(fā)過程中需要避免這類問題。

  • 資源性對象未關閉。比如Cursor、File文件等,往往都用了一些緩沖,在不使用時,應該及時關閉它們。

  • 注冊對象未注銷。比如事件注冊后未注銷,會導致觀察者列表中維持著對象的引用。

  • 類的靜態(tài)變量持有大數(shù)據對象。

  • 非靜態(tài)內部類的靜態(tài)實例。

  • Handler臨時性內存泄漏。如果Handler是非靜態(tài)的,容易導致 Activity 或 Service 不會被回收。

  • 容器中的對象沒清理造成的內存泄漏。

  • WebView。WebView 存在著內存泄漏的問題,在應用中只要使用一次 WebView,內存就不會被釋放掉。

除此之外,內存泄漏可監(jiān)控,常見的就是用LeakCanary 第三方庫,這是一個檢測內存泄漏的開源庫,使用非常簡單,可以在發(fā)生內存泄漏時告警,并且生成 leak tarce 分析泄漏位置,同時可以提供 Dump 文件進行分析。

優(yōu)化內存空間

沒有內存泄漏,并不意味著內存就不需要優(yōu)化,在移動設備上,由于物理設備的存儲空間有限,Android 系統(tǒng)對每個應用進程也都分配了有限的堆內存,因此使用最小內存對象或者資源可以減小內存開銷,同時讓GC 能更高效地回收不再需要使用的對象,讓應用堆內存保持充足的可用內存,使應用更穩(wěn)定高效地運行。常見做法如下:

  • 對象引用。強引用、軟引用、弱引用、虛引用四種引用類型,根據業(yè)務需求合理使用不同,選擇不同的引用類型。

  • 減少不必要的內存開銷。注意自動裝箱,增加內存復用,比如有效利用系統(tǒng)自帶的資源、視圖復用、對象池、Bitmap對象的復用。

  • 使用最優(yōu)的數(shù)據類型。比如針對數(shù)據類容器結構,可以使用ArrayMap數(shù)據結構,避免使用枚舉類型,使用緩存Lrucache等等。

  • 圖片內存優(yōu)化。可以設置位圖規(guī)格,根據采樣因子做壓縮,用一些圖片緩存方式對圖片進行管理等等。

穩(wěn)定性優(yōu)化

Android 應用的穩(wěn)定性定義很寬泛,影響穩(wěn)定性的原因很多,比如內存使用不合理、代碼異常場景考慮不周全、代碼邏輯不合理等,都會對應用的穩(wěn)定性造成影響。其中最常見的兩個場景是:Crash 和 ANR,這兩個錯誤將會使得程序無法使用,比較常用的解決方式如下:

  • 提高代碼質量。比如開發(fā)期間的代碼審核,看些代碼設計邏輯,業(yè)務合理性等。

  • 代碼靜態(tài)掃描工具。常見工具有Android Lint、Findbugs、Checkstyle、PMD等等。

  • Crash監(jiān)控。把一些崩潰的信息,異常信息及時地記錄下來,以便后續(xù)分析解決。

  • Crash上傳機制。在Crash后,盡量先保存日志到本地,然后等下一次網絡正常時再上傳日志信息。

耗電優(yōu)化

在移動設備中,電池的重要性不言而喻,沒有電什么都干不成。對于操作系統(tǒng)和設備開發(fā)商來說,耗電優(yōu)化一致沒有停止,去追求更長的待機時間,而對于一款應用來說,并不是可以忽略電量使用問題,特別是那些被歸為“電池殺手”的應用,最終的結果是被卸載。因此,應用開發(fā)者在實現(xiàn)需求的同時,需要盡量減少電量的消耗。

在 Android5.0 以前,在應用中測試電量消耗比較麻煩,也不準確,5.0 之后專門引入了一個獲取設備上電量消耗信息的 API:Battery Historian。Battery Historian 是一款由 Google 提供的 Android 系統(tǒng)電量分析工具,和Systrace 一樣,是一款圖形化數(shù)據分析工具,直觀地展示出手機的電量消耗過程,通過輸入電量分析文件,顯示消耗情況,最后提供一些可供參考電量優(yōu)化的方法。

除此之外,還有一些常用方案可提供:

  • 計算優(yōu)化,避開浮點運算等。

  • 避免 WaleLock 使用不當。

  • 使用 Job Scheduler。

安裝包大小優(yōu)化

應用安裝包大小對應用使用沒有影響,但應用的安裝包越大,用戶下載的門檻越高,特別是在移動網絡情況下,用戶在下載應用時,對安裝包大小的要求更高,因此,減小安裝包大小可以讓更多用戶愿意下載和體驗產品。

常用應用安裝包的構成,如圖所示:

Android 全方位性能調優(yōu)詳解


從圖中我們可以看到:

  • assets文件夾。存放一些配置文件、資源文件,assets不會自動生成對應的 ID,而是通過 AssetManager 類的接口獲取。

  • res。res 是 resource 的縮寫,這個目錄存放資源文件,會自動生成對應的 ID 并映射到 .R 文件中,訪問直接使用資源 ID。

  • META-INF。保存應用的簽名信息,簽名信息可以驗證 APK 文件的完整性。

  • AndroidManifest.xml。這個文件用來描述 Android 應用的配置信息,一些組件的注冊信息、可使用權限等。

  • classes.dex。Dalvik 字節(jié)碼程序,讓 Dalvik 虛擬機可執(zhí)行,一般情況下,Android 應用在打包時通過 Android SDK 中的 dx 工具將 Java 字節(jié)碼轉換為 Dalvik 字節(jié)碼。

  • resources.arsc。記錄著資源文件和資源 ID 之間的映射關系,用來根據資源 ID 尋找資源。

減少安裝包大小的常用方案

  • 代碼混淆。使用proGuard 代碼混淆器工具,它包括壓縮、優(yōu)化、混淆等功能。

  • 資源優(yōu)化。比如使用 Android Lint 刪除冗余資源,資源文件最少化等。

  • 圖片優(yōu)化。比如利用 AAPT 工具對 PNG 格式的圖片做壓縮處理,降低圖片色彩位數(shù)等。

  • 避免重復功能的庫,使用 WebP圖片格式等。

  • 插件化。比如功能模塊放在服務器上,按需下載,可以減少安裝包大小。

小結

性能優(yōu)化不是更新一兩個版本就可以解決的,是持續(xù)性的需求,持續(xù)集成迭代反饋。在實際的項目中,在項目剛開始的時候,由于人力和項目完成時間限制,性能優(yōu)化的優(yōu)先級比較低,等進入項目投入使用階段,就需要把優(yōu)先級提高,但在項目初期,在設計架構方案時,性能優(yōu)化的點也需要提早考慮進去,這就體現(xiàn)出一個程序員的技術功底了。

什么時候開始有性能優(yōu)化的需求,往往都是從發(fā)現(xiàn)問題開始,然后分析問題原因及背景,進而尋找最優(yōu)解決方案,最終解決問題,這也是日常工作中常會用到的處理方式。


向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI