【Android】性能優化之內存、網絡、布局、卡頓、安裝包、啟動速度優化

歡迎來到 Android 開發老生常談的性能優化篇,本文將性能優化劃分為內存、網絡、布局、卡頓、安裝包、啟動速度七塊,從這七塊優化出發,闡述優化的 Application 的方式。

目錄

  • 內存優化
    • 避免內存泄漏
    • 使用內存分析工具
    • 優化數據結構和算法
    • 數據緩存
    • 避免頻繁的 GC
  • 網絡優化
    • 合并接口請求,減少請求次數
    • 使用網絡緩存
    • 使用合適的數據格式
    • 使用合適的網絡庫
    • 后臺同步
    • 預加載
    • 使用持久連接
    • 優化圖片加載
    • 使用前檢測網絡
  • 布局優化
    • 1、減少布局嵌套
    • 2、減少 wrap-content 的使用
    • 3、使用 include、merge、ViewStub,重復布局復用
  • 卡頓優化
    • 造成卡頓的原因
      • 主線程阻塞
      • 內存泄漏
      • 布局過于復雜
      • Bitmap對象過大
      • 頻繁的GC
      • 動畫效果處理不當
    • 如何避免卡頓問題
      • 避免在主線程中執行耗時操作
      • 優化布局
      • 處理內存泄漏
      • 優化Bitmap的使用
      • 減少GC的觸發
  • 安裝包優化
    • 資源優化
      • 1、按需添加第三方庫,避免引入重復庫。
      • 2、 png轉svg,再使用svg轉成vector格式。
      • 3、 刪除多余的so庫。
      • 4、 刪除多余的 `mipmap` 文件夾。
      • 5、 刪除未使用到的資源文件。
      • 6、動態加載.so文件。
      • 7、使用插件化。
    • 代碼混淆
  • 啟動速度優化
    • App Startup 優化初始化速度
    • 懶加載
      • ViewStup 按需加載布局
      • Paging 分頁
      • ViewPager 2 翻頁
    • 預加載
    • 偽加載
      • 設置啟動頁
    • 代碼優化
      • 使用 adb 命令查看啟動 Activity 時間
      • 使用 Profile 查看 Activity 方法耗時,對其進行優化
    • WorkManager 后臺保活
  • 課外小知識
    • 應用啟動狀態
      • 冷啟動
      • 溫啟動
      • 熱啟動

內存優化

在 Android 中,內存優化通常指的是 運行內存優化。運行內存優化 主要關注如何有效地使用和管理應用程序的 RAM (Random Access Memory) 使用,以提高性能,減少延遲,并防止應用程序因為消耗過多內存而被系統殺死。

避免內存泄漏

內存泄漏是指應用程序分配了內存,但未能釋放。這會導致應用程序消耗的內存隨著時間的推移而增加,可能導致應用程序崩潰或系統性能下降。

使用內存分析工具

Android Studio 提供了一些工具,如 Memory Profiler,可以幫助開發者分析和理解應用程序的內存使用情況。

優化數據結構和算法

使用更有效的數據結構和算法可以減少內存使用。

數據緩存

合理使用 數據庫、網絡、圖片緩存數據,可以減少不必要的數據、重復數據的存儲,減少數據創建和銷毀的開銷,此外,還可以提高數據的訪問速度。

避免頻繁的 GC

垃圾回收 (Garbage Collection 簡稱 GC) ,頻繁的垃圾回收會影響應用程序的性能。可以通過減少對象的創建和銷毀,以及使用對象池等技術來減少垃圾回收的頻率。

網絡優化

合并接口請求,減少請求次數

盡可能地減少網絡請求次數,可以通過合并請求、使用批量接口等方式實現。

使用網絡緩存

對于一些不經常變動的數據,可以使用緩存來減少網絡請求。例如,可以使用 HTTP 緩存、數據庫緩存或者內存緩存。

使用合適的數據格式

例如,對于大量的數據,可以使用 Protobuf 而不是 JSON,因為 Protobuf 更加緊湊,可以減少數據的大小,從而減少網絡傳輸的時間。

使用合適的網絡庫

使用 OkHttpRetrofit 等網絡庫,它們內部已經做了很多優化。

后臺同步

對于一些不需要立即返回結果的操作,可以使用后臺同步,例如使用 WorkManager 或者 JobScheduler

預加載

對于一些用戶可能需要的數據,可以提前進行加載。

使用持久連接

使用 HTTP2,它們支持多路復用,可以減少連接的建立和關閉的開銷。

優化圖片加載

對于圖片,可以使用合適的格式和大小,還可以使用圖片加載庫,例如 Glide 或者 Picasso,它們內部已經做了很多優化。

使用前檢測網絡

在進行網絡請求前,先檢測網絡狀態,如果網絡不可用,那么可以立即返回錯誤,而不是等待超時。

布局優化

1、減少布局嵌套

2、減少 wrap-content 的使用

3、使用 include、merge、ViewStub,重復布局復用

卡頓優化

在 Android 系統中,每一秒屏幕刷新速度為 60 幀(FPS),人類眼睛舒適放松時的可視幀率是 24 幀,當某個加載中的界面每秒刷新低于 24 幀時,就會感覺到卡頓。但當屏幕沒有繪制需求時,即屏幕的顯示的界面為靜止時,幀率為 0。

造成卡頓的原因

主線程阻塞

如果在主線程(UI線程)中執行了耗時的操作,如網絡請求、數據庫操作等,會導致UI更新延遲,從而引發卡頓。

內存泄漏

如果應用中存在內存泄漏,可能會導致內存占用過高,從而引發卡頓。

布局過于復雜

如果布局層級過深或者布局過于復雜,可能會導致布局渲染時間過長,從而引發卡頓。

Bitmap對象過大

如果Bitmap對象過大,可能會導致內存占用過高,從而引發卡頓。

頻繁的GC

垃圾回收 (Garbage Collection 簡稱 GC) 過程需要消耗系統資源,如果頻繁觸發,可能會導致應用性能下降,出現卡頓現象。

動畫效果處理不當

如何避免卡頓問題

避免在主線程中執行耗時操作

可以使用線程、協程、AsyncTask等技術將耗時操作移至后臺執行。

優化布局

盡量減少布局的層級,避免過度繪制,使用更高效的 View 或 ViewGroup。

處理內存泄漏

使用 LeakCanary 等工具幫助找到并處理內存泄漏。

優化Bitmap的使用

盡量不要使用過大的 Bitmap,使用合適的壓縮格式和分辨率,及時回收不再使用的Bitmap

減少GC的觸發

盡量減少內存抖動,避免頻繁的對象創建和銷毀。 內存抖動 (Memory Churn) 是指應用程序在短時間內頻繁地創建和銷毀對象,這種行為會導致垃圾回收器 (Garbage Collector) 頻繁地運行,從而消耗大量的CPU資源,可能導致應用程序的性能下降,出現卡頓現象。

以上只是一些可能的原因,具體的原因需要通過性能分析工具如 Android ProfilerBlockCanarySystrace 等進行分析。

往期文章👉【Android】測試方法匯總,助力打造完美應用

安裝包優化

資源優化

1、按需添加第三方庫,避免引入重復庫。

2、 png轉svg,再使用svg轉成vector格式。

3、 刪除多余的so庫。

刪除多余的so庫,執行這一操作的前提是:程序所運行的系統 CPU 架構固定是 Android CPU 架構中的某一個。例如:部分第三方提供的 so 庫是包含了 armeabiarmeabi-v71arm64-v8ax86 等庫文件,如果你的程序只運行在 armeabi CPU 架構上,則可以把其它的 so 庫文件刪除。

4、 刪除多余的 mipmap 文件夾。

一般圖標資源使用 mipmap-xhdpi 足夠用了,更大的屏幕則使用 mipmap-xxhdpimipmap-xxxhdpi 的分辨率,已經使用 mipmap-xhdpi 或其它更大分辨率的程序,應刪除比它小的分辨率文件。

5、 刪除未使用到的資源文件。

可通過 Android Studio 菜單欄的 RefactorRemove Unused Resources 功能一鍵移除未被使用的 drawablemipmaplayout 以及 colors.xmlstrings.xml 文件里面的 colorstring

6、動態加載.so文件。

.so 文件可以在用戶安裝應用到手機后再從服務器上下載到手機的 data 目錄下,加載的時候使用絕對路徑在 static 關鍵字里加載。

static {System.loadLibrary("so文件")
}

參考文章
1、Android 應用資源概述

7、使用插件化。

插件化技術支持動態加載代碼和動態加載資源,把 Application 的一部分分離出來,對于業務龐大的項目非常有用,極大的分解了 Application 的大小。但又因為插件化需要一定的技術保障和服務端的系統支持,有一定的風險,建議酌情選擇。

代碼混淆

代碼混淆(Obfuscation)是將計算機程序的源代碼或機器代碼,轉換成功能上等價,但是難于閱讀和理解的形式的行為。簡單來說,就是簡化函數名、變量、常量名稱,通過減少字符數以達到減小安裝包大小的方式。

啟用混淆只需要打開 Android 項目,在 Application Model 下中找到 build.gradle,在該文件添加如下配置即可開啟混淆:

android {// 打包 release 包時執行release {// 啟用混淆,默認使用 R8 編譯器minifyEnabled true// 資源壓縮shrinkResources true// 定義 自定義混淆規則的文件proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'}}
}

上面混淆的方式僅適用于代碼簡單、封裝少的項目。項目復雜還請自定義混淆規則,詳情請查看往期文章👉【Android】App攻防之代碼混淆

啟動速度優化

App Startup 優化初始化速度

App Startup 是 Android 官方推出的一個應用程序啟動時初始化組件的庫。開發人員可以使用 App Startup 來簡化啟動序列并顯式設置初始化順序。

詳情請看👉 App Startup

懶加載

懶加載是一種延遲加載的策略,它指的是在需要時才進行加載和初始化,而不是在應用程序啟動或頁面加載時就提前加載。這種策略通常用于延遲加載大型資源或組件,以減少啟動時間和內存占用。

ViewStup 按需加載布局

詳情請看👉 ViewStup

Paging 分頁

詳情請看👉 Paging

ViewPager 2 翻頁

詳情請看👉 ViewPager 2

預加載

預加載是在應用程序啟動或特定頁面加載之前提前加載和準備數據、資源或組件。這有助于提高應用程序的性能和響應速度,因為一些必要的內容已經被提前加載到內存中,而不是等到用戶請求時再進行加載。

偽加載

偽加載是一種虛假的加載行為,通常用于模擬加載過程而不實際進行真正的加載。這種策略可以用于創建加載動畫或展示加載狀態,以提升用戶體驗,但實際上并沒有進行真實的加載操作。

設置啟動頁

給 app 添加啟動頁,這應該是最常見的實現偽加載的方式了。當應用啟動頁播放完成跳轉到首頁時,你能很明顯的感覺到,app 比沒有使用啟動頁之前變得更“流暢”了。

設置啟動頁參考文章 👉 Android—啟動頁+閃屏頁

其它啟動速度優化的方法:
1、盡量不要在ApplicationonCreate中寫初始化代碼
2、減少靜態類、靜態方法、靜態函數的使用,盡量做到用時再初始化

代碼優化

使用 adb 命令查看啟動 Activity 時間

在 Android 中,我們可以通過 adb 命令:adb shell am start -W packageName/packageName.ActivityName 獲取到啟動該 Activity 所消耗的時間,如下:

 E:\Projects\StepDemo> adb shell am start -W com.binyouwei.demo/com.binyouwei.demo.MainActivityStarting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.binyouwei.demo/.MainActivity }
Status: ok
Activity: com.binyouwei.demo/.MainActivity
ThisTime: 522
TotalTime: 522
WaitTime: 525
Complete

在上方,我輸入了 adb shell am start -W com.binyouwei.demo/com.binyouwei.demo.MainActivity ,系統給我響應了一大串的字符,其中的含義如下:
ThisTime:指定的 activity 啟動耗時。
TotalTime:應用自身啟動耗時 = ThisTime + 應用 Application 等資源啟動時間
WaitTime:系統啟動應用耗時 = TotalTime + 系統資源啟動時間

使用 Profile 查看 Activity 方法耗時,對其進行優化

使用參考文章👉Android Studio 中 CPU Profiler 系統性能分析工具的使用

WorkManager 后臺保活

使用 WorkManager 實現后臺保活,當應用處于后臺時,應用所占的內存不會被系統完全回收,再次啟動應用相較于第一次啟動會更快。

課外小知識

應用啟動狀態

冷啟動

冷啟動是指應用程序從頭開始啟動的過程,這意味著應用程序的進程被終止,用戶點擊應用圖標重新啟動應用。在冷啟動過程中,應用需要重新創建進程、初始化應用程序和加載 UI 界面。

溫啟動

溫啟動是指應用程序在后臺保持活動狀態并且重新進入前臺時的啟動方式。在溫啟動過程中,應用程序的進程仍然存在,但需要重新初始化和加載 UI 界面。

熱啟動

熱啟動是指應用程序在后臺保持活動狀態并且重新進入前臺時的快速啟動方式。在熱啟動過程中,應用程序的進程仍然存在,并且可以快速恢復到之前的狀態,而不需要重新初始化和加載 UI 界面。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/697697.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/697697.shtml
英文地址,請注明出處:http://en.pswp.cn/news/697697.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Jmeter基礎(1) Mac下載安裝啟動

目錄 Jmeter下載安裝啟動下載啟動 Jmeter下載安裝啟動 注意??:使用jmeter需要有java環境 下載 官網下載地址:https://jmeter.apache.org/ 會看到這里有兩個版本,那么有什么區別么? Binaries是可執行版,直接下載解…

Python算法題集_圖論(課程表)

Python算法題集_課程表 題207:課程表1. 示例說明2. 題目解析- 題意分解- 優化思路- 測量工具 3. 代碼展開1) 標準求解【循環遞歸全算】2) 改進版一【循環遞歸緩存】3) 改進版二【循環遞歸緩存反向計算】4) 改進版三【迭代剝離計數器檢測】 4. 最優算法5. 相關資源 本…

Spring整合Junit4和Junit5

1、整合的好處 好處1&#xff1a;不需要自己創建IOC容器對象了好處2&#xff1a;任何需要的bean都可以在測試類中直接享受自動裝配 2、操作 整合junit4 ①加入依賴 <dependency><groupId>junit</groupId><artifactId>junit</artifactId><…

代碼隨想錄算法訓練營第二十三天補|669. 修剪二叉搜索樹 ● 108.將有序數組轉換為二叉搜索樹 ● 538.把二叉搜索樹轉換為累加樹

平衡樹、二叉樹、靈活應用中序遍歷&#xff08;值大小有序&#xff09; 669. 修剪二叉搜索樹 給你二叉搜索樹的根節點 root &#xff0c;同時給定最小邊界low 和最大邊界 high。通過修剪二叉搜索樹&#xff0c;使得所有節點的值在[low, high]中。修剪樹 不應該 改變保留在樹中…

Window部署SkyWalking

SkyWalking mysql的驅動依賴 選擇下載版本 v9.4 現在后解壓縮目錄結構 一、修改config目錄文件 application.yml 修改1&#xff1a; selector: ${SW_STORAGE:h2} 修改后&#xff1a; selector: ${SW_STORAGE:mysql} 修改2&#xff1a;使用mysql數據庫 mysql: properti…

通俗易懂分析:Vite和Webpack的區別

1、對項目構建的理解 先從瀏覽器出發&#xff0c; 瀏覽器是由瀏覽器內核和JS引擎組成&#xff1b;瀏覽器內核編譯解析html代碼和css代碼&#xff0c;js引擎編譯解析JavaScript代碼&#xff1b;所以從本質上&#xff0c;瀏覽器只能識別運行JavaScript、CSS、HTML代碼。 而我們在…

敏捷開發最佳實踐:領導力維度實踐案例——走動式激勵

在本節實踐案例中&#xff0c;某財險公司信息技術部高級工程師分享了組織級數字化轉型中的優秀敏捷領導力實踐&#xff0c;不僅解決了產品上市周期長、響應市場變化慢的難題&#xff0c;還打破了部門墻、提升了客戶滿意度&#xff0c;該案例將為同類企業在組織層面進行有效敏捷…

Centos7配置靜態IP詳細步驟

使用Centos虛擬機測試時一到切換網段就頭疼&#xff0c;總是會有ping不通網關、同段IP和外網的情況。下面出一個盡可能完整的排查思路和配置靜態IP的過程。以下為配置nat模式后&#xff0c;出現以上情況的網絡不通的排查思路&#xff0c;并配置win10vm8靜態IP和centos7虛機nat模…

vue3路由切換過渡動畫實現

<router-view v-slot"{ Component }"><transition name"fade" mode"out-in" appear><keep-alive><component :is"Component" /></keep-alive></transition> </router-view>/* 路由切換動畫…

SQL字符集

目標:了解字符集的概念&#xff0c;掌握MySQL數據庫存儲數據的字符集邏輯以及設置方式 字符集概念 MySQL字符集關系 解決亂碼問題 字符集設置原理 1、字符集概念 目標:了解字符集概念&#xff0c;掌握字符集存儲和讀取的實現原理 概念 字符集:charset或者character set&am…

(十二)【Jmeter】線程(Threads(Users))之setUp 線程組

簡述 操作路徑如下: 作用:在正式測試開始前執行預加載或預熱操作,為測試做準備。配置:設置預加載或預熱操作的采樣器、循環次數等參數。使用場景:確保在正式測試開始前應用程序已經達到穩定狀態,減少測試結果的偏差。優點:提供預加載或預熱操作,確保測試的準確性。缺…

Centos開機網卡自啟動失敗

問題背景 每次都要手動啟動在這里插入代碼片 解決方案: 關閉 NetworkManager 服務 systemctl disable NetworkManager systemctl stop NetworkManager重啟就會發現網卡已經可以自動啟動了

2024幻獸帕魯游戲服務器租用價格表_一年和1個月報價明細

游戲服務器租用多少錢一年&#xff1f;1個月游戲服務器費用多少&#xff1f;阿里云4核16G10M游戲服務器26元1個月、149元半年&#xff0c;騰訊云4核16G游戲服務器32元、312元一年&#xff0c;華為云26元&#xff0c;京東云主機也是26元起&#xff0c;游戲服務器配置從4核16G、4…

代碼隨想錄算法刷題訓練營day22

代碼隨想錄算法刷題訓練營day22&#xff1a;LeetCode(236)二叉樹的最近公共祖先、LeetCode(235) 二叉搜索樹的最近公共祖先、LeetCode(701)二叉搜索樹中的插入操作、LeetCode(450)刪除二叉搜索樹中的節點 LeetCode(236)二叉樹的最近公共祖先 題目 代碼 /*** Definition for…

【鴻蒙 HarmonyOS 4.0】路由router

一、介紹 頁面路由指在應用程序中實現不同頁面之間的跳轉和數據傳遞。HarmonyOS提供了Router模塊&#xff0c;通過不同的url地址&#xff0c;可以方便地進行頁面路由&#xff0c;輕松地訪問不同的頁面。 二、頁面跳轉 2.1、兩種跳轉模式&#xff1a; router.pushUrl()&…

vue2與vue3中父子組件傳參的區別

本次主要針對vue中父子組件傳參所進行講解 一、vue2和vue3父傳子區別 1.vue2的父傳子 1).在父組件子標簽中自定義一個屬性 <sonPage :子組件接收到的類名"傳輸的數據">子組件</sonPage> 2).在子組件中peops屬性中拿到自定屬性 props: {子組件接收的…

Stable Diffusion算法、結構全流程概述

Stable Diffusion能力強、功能多、插件廣&#xff0c;本文擬概述SD的全流程&#xff0c;方便梳理算法各結構的關系 1、stable diffusion訓練用ddpm, 采樣用ddim DDPM的推理采樣步長和訓練時的步長一樣&#xff0c;導致采樣步數過多&#xff0c;推理時間長。DDIM指出&#xff…

安卓游戲開發之音頻技術優劣分析

一、引言 在安卓游戲開發中&#xff0c;音頻處理技術扮演著至關重要的角色&#xff0c;它不僅能夠增強游戲的沉浸感和玩家體驗&#xff0c;還能通過聲音效果傳達關鍵的游戲信息。以下將對幾種常見的安卓游戲音頻處理技術進行優劣分析&#xff0c;并結合應用場景來闡述其特點。 …

docker鏡像打包和解壓

背景 工作記錄 打包鏡像 docker save -o 壓縮包名稱.tar 鏡像名稱:鏡像版本 例如 docker save -o app-web.tar app-web:2.0解壓鏡像 這里解壓上面打包的app-web的壓縮包 docker load<壓縮包名稱.tar docker load<app-web.tar這樣解壓下來的實際就是app-web:2.0這個鏡…

微服務-微服務API網關Spring-clould-gateway實戰

1. 需求背景 在微服務架構中&#xff0c;通常一個系統會被拆分為多個微服務&#xff0c;面對這么多微服務客戶端應該如何去調用呢&#xff1f; 如果根據每個微服務的地址發起調用&#xff0c;存在如下問題&#xff1a; 1.客戶端多次請求不同的微服務&#xff0c;會增加客戶端…