[TOC]
## 啟動時長統計
### TraceView和SysTrace工具
### 手工打點
ActionS: 進程不存在的情況下,點擊icon啟動執行到SplashActivity#onDrawComplete的耗時
ActionR: 進程不存在的情況下,點擊icon啟動執行到SplashActivity#onDrawComplete后,到消息同步完畢的耗時
### 無痕跡打點
ASM編譯插樁
## 啟動優化手段
### 顯示優化
#### 1.將啟動頁主題背景設置成閃屏頁圖片
這么做的目的主要是為了消除啟動時的黑白屏,給用戶一種秒響應的感覺,但是并不會真正減少用戶啟動時間,僅屬于視覺優化。
#### 2.主頁面布局優化
1)通過減少冗余或者嵌套布局來降低視圖層次結構
2)用 ViewStub 替代在啟動過程中不需要顯示的 UI 控件
## 黑科技優化
### redex 重排列 class 文件
通過文件重排列的目的,就是將啟動階段需要用到的文件在 APK 文件中排布在一起,盡可能的利用 Linux 文件系統的 pagecache 機制,用最少的磁盤 IO 次數,讀取盡可能多的啟動階段需要的文件,減少 IO 開銷,從而達到提升啟動性能的目的。
### 在類加載的過程中通過 Hook 去掉類驗證的過程
### 低端機,MultipDex
#### ClassLoader 加載類原理:
> ClassLoader.loadClass -> DexPathList.loadClass -> 遍歷dexElements數組 ->DexFile.loadClassBinaryName
通俗點說就是:ClassLoader加載類的時候是通過遍歷dex數組,從dex文件里面去加載一個類,加載成功就返回,加載失敗則拋出Class Not Found 異常。
#### MultiDex原理:
> 在明白ClassLoader加載類原理之后,我們可以通過反射dexElements數組,將新增的dex添加到數組后面,這樣就保證ClassLoader加載類的時候可以從新增的dex中加載到目標類,經過分析后最終MultipDex原理圖如下:
> 
#### MultiDex優化
install過程為什么耗時,因為涉及到解壓apk取出dex、壓縮dex、將dex文件通過反射轉換成DexFile對象、反射替換數組。
1. 在Application 的attachBaseContext 方法里,啟動另一個進程的LoadDexActivity去異步執行MultiDex邏輯,顯示Loading。
2. 然后主進程Application進入while循環,不斷檢測MultiDex操作是否完成
3. MultiDex執行完之后主進程Application繼續走,ContentProvider初始化和Application onCreate方法,也就是執行主進程正常的邏輯。
## 業務優化
### 減少啟動過程中的 GC 優化/IO讀取
### 第三方庫懶加載
很多第三方開源庫都說在Application中進行初始化,十幾個開源庫都放在Application中,肯定對冷啟動會有影響,所以可以考慮按需初始化,例如Glide,可以放在自己封裝的圖片加載類中,調用到再初始化,其它庫也是同理,讓Application變得更輕。
### 線程優化
線程是程序運行的基本單位,線程的頻繁創建是耗性能的,所以大家應該都會用線程池。單個cpu情況下,即使是開多個線程,同時也只有一個線程可以工作,所以線程池的大小要根據cpu個數來確定。
## 異步加載
異步加載。將耗時任務放到子線程加載,等到所有加載任務加載完成之后,再進入首頁。
多線程異步加載方案確實是 ok 的。但如果遇到前后依賴的關系呢。比如任務2 依賴于任務 1,這時候要怎么解決呢。
有向無環圖。它可以完美解決先后依賴關系。
### 有向無環圖
**有向無環圖**(Directed Acyclic Graph, DAG)是有向圖的一種,字面意思的理解就是圖中沒有環。常常被用來表示事件之間的驅動依賴關系,管理任務之間的調度。

**頂點**:圖中的一個點,比如頂點 1,頂點 2。
**邊**:連接兩個頂點的線段叫做邊,edge。
**入度**:代表當前有多少邊指向它。
在上圖中,頂掉 1 的入度是 0,因為沒有任何邊指向它。頂掉 2 的入度是 1, 因為 頂掉 1 指向 頂掉 2. 同理可得出 5 的入度是 2,因為頂掉 4 和頂點 3 指向它。
**拓撲排序**:拓撲排序是對一個有向圖構造拓撲序列的過程。它具有如下特點。
* 每個頂點出現且只出現一次。
* 若存在一條從頂點 A 到頂點 B 的路徑,那么在序列中頂點 A 出現在頂點 B 的前面
由于有這個特點,因此常常用有向無環圖的數據結構用來解決依賴關系。
上圖中,拓撲排序之后,任務2肯定排在任務1之后,因為任務2依賴 任務1, 任務3肯定在任務2之后,因為任務3依賴任務2。
拓撲排序一般有兩種算法,第一種是入度表法,第二種是 DFS 方法。下面,讓我們一起來看一下怎么實現它。
### 入度表法
入度表法是根據頂點的入度來判斷是否有依賴關系的。若頂點的入度不為 0,則表示它有前置依賴。它也常常被稱作**BFS 算法**。
#### 算法思想
* 建立入度表,入度為 0 的節點先入隊。
* 當隊列不為空,進行循環判斷。
* 節點出隊,添加到結果 list 當中。
* 將該節點的鄰居入度減 1。
* 若鄰居節點入度為 0,加入隊列。
* 若結果 list 與所有節點數量相等,則證明不存在環。否則,存在環。
- Android
- 四大組件
- Activity
- Fragment
- Service
- 序列化
- Handler
- Hander介紹
- MessageQueue詳細
- 啟動流程
- 系統啟動流程
- 應用啟動流程
- Activity啟動流程
- View
- view繪制
- view事件傳遞
- choreographer
- LayoutInflater
- UI渲染概念
- Binder
- Binder原理
- Binder最大數據
- Binder小結
- Android組件
- ListView原理
- RecyclerView原理
- SharePreferences
- AsyncTask
- Sqlite
- SQLCipher加密
- 遷移與修復
- Sqlite內核
- Sqlite優化v2
- sqlite索引
- sqlite之wal
- sqlite之鎖機制
- 網絡
- 基礎
- TCP
- HTTP
- HTTP1.1
- HTTP2.0
- HTTPS
- HTTP3.0
- HTTP進化圖
- HTTP小結
- 實踐
- 網絡優化
- Json
- ProtoBuffer
- 斷點續傳
- 性能
- 卡頓
- 卡頓監控
- ANR
- ANR監控
- 內存
- 內存問題與優化
- 圖片內存優化
- 線下內存監控
- 線上內存監控
- 啟動優化
- 死鎖監控
- 崩潰監控
- 包體積優化
- UI渲染優化
- UI常規優化
- I/O監控
- 電量監控
- 第三方框架
- 網絡框架
- Volley
- Okhttp
- 網絡框架n問
- OkHttp原理N問
- 設計模式
- EventBus
- Rxjava
- 圖片
- ImageWoker
- Gilde的優化
- APT
- 依賴注入
- APT
- ARouter
- ButterKnife
- MMKV
- Jetpack
- 協程
- MVI
- Startup
- DataBinder
- 黑科技
- hook
- 運行期Java-hook技術
- 編譯期hook
- ASM
- Transform增量編譯
- 運行期Native-hook技術
- 熱修復
- 插件化
- AAB
- Shadow
- 虛擬機
- 其他
- UI自動化
- JavaParser
- Android Line
- 編譯
- 疑難雜癥
- Android11滑動異常
- 方案
- 工業化
- 模塊化
- 隱私合規
- 動態化
- 項目管理
- 業務啟動優化
- 業務架構設計
- 性能優化case
- 性能優化-排查思路
- 性能優化-現有方案
- 登錄
- 搜索
- C++
- NDK入門
- 跨平臺
- H5
- Flutter
- Flutter 性能優化
- 數據跨平臺