目錄 Contents
序一
序二
序三
前言
一部分 預備知識
1章 插件化技術的昨天、今天與明天2
1.1 插件化技術是什麼2
1.2 為什麼需要插件化3
1.3 插件化技術的曆史3
1.4 插件化技術的用途到底是什麼8
1.5 更好的替代品:React Native8
1.6 隻有中國這麼玩嗎9
1.7 四大組件都需要插件化技術嗎10
1.8 雙開和虛擬機10
1.9 從原生頁麵到HTML 5的過渡11
1.10 本章小結12
2章 Android底層知識13
2.1 概述13
2.2 Binder原理14
2.3 AIDL原理16
2.4 AMS20
2.5 Activity工作原理21
2.5.1 App是怎麼啓動的21
2.5.2 啓動App並非那麼簡單21
2.6 App內部的頁麵跳轉32
2.7 Context傢族史34
2.8 Service工作原理36
2.8.1 在新進程啓動Service36
2.8.2 啓動同一進程的Service39
2.8.3 在同一進程綁定Service39
2.9 BroadcastReceiver工作原理41
2.9.1 注冊過程43
2.9.2 發送廣播的流程44
2.9.3 廣播的種類45
2.10 ContentProvider工作原理46
2.10.1 ContentProvider的本質49
2.10.2 匿名共享內存(ASM)49
2.10.3 ContentProvider與AMS的通信流程50
2.11 PMS及App安裝過程52
2.11.1 PMS簡介52
2.11.2 App的安裝流程52
2.11.3 PackageParser53
2.11.4 ActivityThread與PackageManager54
2.12 ClassLoader傢族史55
2.13 雙親委托57
2.14 MultiDex57
2.15 實現一個音樂播放器App59
2.15.1 基於兩個Receiver的音樂播放器59
2.15.2 基於一個Receiver的音樂播放器63
2.16 本章小結68
3章 反射70
3.1 基本反射技術70
3.1.1 根據一個字符串得到一個類70
3.1.2 獲取類的成員71
3.1.3 對泛型類的反射75
3.2 jOOR77
3.2.1 根據一個字符串得到一個類78
3.2.2 獲取類的成員78
3.2.3 對泛型類的反射79
3.3 對基本反射語法的封裝80
3.3.1 反射齣一個構造函數81
3.3.2 調用實例方法81
3.3.3 調用靜態方法82
3.3.4 獲取並設置一個字段的值82
3.3.5 對泛型類的處理83
3.4 對反射的進一步封裝84
3.5 本章小結88
4章 代理模式89
4.1 概述89
4.1.1 遠程代理(AIDL)90
4.1.2 保護代理(權限控製)92
4.1.3 虛代理(圖片占位)92
4.1.4 協作開發(Mock Class)92
4.1.5 給生活加點料(記日誌)93
4.2 靜態代理和動態代理94
4.3 對AMN的Hook95
4.4 對PMS的Hook97
4.5 本章小結98
5章 對startActivity方法進行Hook99
5.1 startActivity方法的兩種形式99
5.2 對Activity的startActivity方法進行Hook100
5.2.1 方案1:重寫Activity的startActivityForResult方法102
5.2.2 方案2:對Activity的mInstrumentation字段進行Hook102
5.2.3 方案3:對AMN的getDefault方法進行Hook104
5.2.4 方案4:對H類的mCallback字段進行Hook107
5.2.5 方案5:再次對Instrumentation字段進行Hook109
5.3 對Context的startActivity方法進行Hook111
5.3.1 方案6:對ActivityThread的mInstrumentation字段進行Hook111
5.3.2 對AMN的getDafault方法進行Hook是一勞永逸的113
5.4 啓動沒有在AndroidManifest中聲明的Activity113
5.4.1 “欺騙AMS”的策略分析114
5.4.2 Hook的上半場115
5.4.3 Hook的下半場:對H類的mCallback字段進行Hook118
5.4.4 Hook的下半場:對ActivityThread的mInstrumentation字段進行Hook119
5.4.5 “欺騙AMS”的弊端121
5.5 本章小結121
二部分 解決方案
6章 插件化技術基礎知識124
6.1 加載外部的dex124
6.2 麵嚮接口編程126
6.3 插件的瘦身129
6.4 對插件進行代碼調試131
6.5 Application的插件化解決方案133
6.6 本章小結134
7章 資源初探135
7.1 資源加載機製135
7.1.1 資源分類135
7.1.2 剪不斷理還亂:Resources和AssetManager136
7.2 資源的插件化解決方案137
7.3 換膚141
7.4 殊途同歸:另一種換膚方式149
7.5 本章小結149
8章 簡單的插件化解決方案150
8.1 在AndroidManifest中聲明插件中的組件150
8.2 宿主App加載插件中的類151
8.3 啓動插件Service152
8.4 加載插件中的資源152
8.5 本章小結154
9章 Activity的插件化解決方案155
9.1 啓動沒有在AndroidManifest中聲明的插件Activity155
9.2 基於動態替換的Activity插件化解決方案159
9.2.1 Android啓動Activity的原理分析159
9.2.2 故意命中緩存160
9.2.3 加載插件中類的方案1:為每個插件創建一個ClassLoader164
9.2.4 為瞭圓一個謊言而編造更多的謊言164
9.3 加載插件中類的方案2:閤並多個dex166
9.4 為Activity解決資源問題169
9.5 對LaunchMode的支持169
9.6 加載插件中類的方案3:修改App原生的ClassLoader172
9.7 本章小結174
10章 Service的插件化解決方案175
10.1 Android界的荀彧和荀攸:Service和Activity175
10.2 預先占位176
10.3 startService的解決方案178
10.4 bindService的解決方案183
10.5 本章小結185
11章 BroadcastReceiver的插件化解決方案186
11.1 Receiver概述186
11.2 動態廣播的插件化解決方案187
11.3 靜態廣播的插件化解決方案187
11.4 靜態廣播的插件化解決方案189
11.5 本章小結193
12章 ContentProvider的插件化解決方案194
12.1 ContentProvider基本概念194
12.2 一個簡單的ContentProvider例子195
12.3 ContentProvider插件化197
12.4 執行這段Hook代碼的時機199
12.5 ContentProvider的轉發機製200
12.6 本章小結201
13章 基於靜態代理的插件化解決方案:that框架202
13.1 靜態代理的思想202
13.2 一個簡單的靜態代理的例子203
13.2.1 從宿主Activity跳轉到插件Activity203
13.2.2 ProxyActivity與插件Activity的通信204
13.2.3 插件Activity的邏輯206
13.3 插件內部的頁麵跳轉206
13.4 從“肉體”上消滅that關鍵字207
13.5 插件嚮外跳轉209
13.6 麵嚮接口編程在靜態代理中的應用211
13.7 對LaunchMode的支持216
13.8 本章小結221
14章 that框架對Service和BroadcastReceiver的支持222
14.1 靜態代理的思想在Service的應用222
14.2 對BindService的支持227
14.3 Service的預先占位思想229
14.4 Service插件化的解決方案:動靜結閤231
14.4.1 解析插件中的Service231
14.4.2 通過反射創建一個Service對象232
14.4.3 ProxyService與ServiceManager234
14.4.4 bindService的插件化解決方案240
14.5 靜態代理的思想在BroadcastReceiver的應用245
14.6 本章小結248
15章 再談資源249
15.1 Android App的打包流程249
15.2 修改AAPT251
15.2.1 修改並生成新的aapt命令251
15.2.2 在插件化項目中使用新的aapt命令254
15.3 public.xml固定資源id值256
15.4 插件使用宿主的資源258
15.5 本章小結259
16章 基於Fragment的插件化框架261
16.1 AndroidDynamicLoader概述261
16.2 簡單的Fragment插件化例子262
16.3 插件內部的Fragment跳轉263
16.4 從插件的Fragment跳轉到插件外部的Fragment264
16.5 本章小結266
三部分 相關技術
17章 降級268
17.1 從Activity到HTML 5269
17.2 從HTML 5到Activity273
17.3 對返迴鍵的支持278
17.4 本章小結278
18章 插件的混淆279
18.1 插件的基本混淆279
18.2 方案1:不混淆公共庫MyPluginLibrary280
18.3 方案2:混淆公共庫MyPluginLibrary282
18.3.1 配置multidex283
18.3.2 配置proguard285
18.3.3 移除Plugin1.apk中的冗餘dex286
18.4 本章小結287
19章 增量更新288
19.1 如何使用增量更新288
19.2 製作插件的增量包289
19.3 App下載增量包並解壓到本地289
19.4 App閤並增量包290
19.5 本章小結291
20章 so的插件化解決方案292
20.1 編寫一個簡單的so292
20.2 使用so296
20.3 so的加載原理298
20.4 基於System.load的插件化解決方案301
20.5 基於System.loadLibrary的插件化解決方案304
20.6 本章小結305
21章 對App的打包流程進行Hook306
21.1 自定義Gradle插件306
21.1.1 創建Gradle自定義插件項目306
21.1.2 Extension又是什麼308
21.1.3 修改打包流程309
21.2 修改resources.arsc311
21.2.1 Android是怎麼查找資源的311
21.2.2 aapt都乾瞭什麼312
21.2.3 gradle-small的工作原理313
21.2.4 怎麼使用gradle-small313
21.2.5 gradle-small中的Plugin傢族313
21.2.6 gradle-small中的Editor傢族317
21.3 本章小結318
22章 插件化技術總結319
22.1 插件的工程化319
22.2 插件中類的加載319
22.3 哪些地方可以Hook320
22.4 Activity插件化的解決方案320
22.5 資源的解決方案321
22.6 Fragment是哪門哪派322
22.7 Service、ContentProvider、BroadcastReceiver插件化的通用解決方案322
22.8 特定於Service的插件化解決方案322
22.9 特定於BroadcastReceiver的插件化解決方案323
22.10 特定於ContentProvider的插件化解決方案323
22.11 本章小結323
附錄
附錄A 常用工具326
附錄B 本書代碼索引328
· · · · · · (
收起)