| Acknowledgments |
|
xvii | |
| About the Author |
|
xix | |
| About the Translators |
|
xxi | |
| Introduction |
|
xxiii | |
| Chapter 1 Plug-Ins from the Past to the Future |
|
1 | (12) |
|
1.1 Android Plug-Ins In China |
|
|
1 | (1) |
|
1.2 History Of Android Plug-In Techniques |
|
|
2 | (6) |
|
|
|
8 | (1) |
|
1.4 Another Choice: React Native |
|
|
9 | (1) |
|
1.5 Do All Components Require Plug-Ins? |
|
|
10 | (1) |
|
1.6 Double-Opening And Virtual Machine |
|
|
10 | (1) |
|
|
|
11 | (1) |
|
|
|
12 | (1) |
| Chapter 2 The Underlying Knowledge of Android |
|
13 | (66) |
|
2.1 Overview Of Underlying Android Knowledge |
|
|
13 | (2) |
|
|
|
15 | (2) |
|
|
|
17 | (5) |
|
2.4 ActivityManagerService |
|
|
22 | (1) |
|
2.5 Activity Working Principles |
|
|
23 | (14) |
|
2.5.1 How to Launch an App |
|
|
23 | (1) |
|
2.5.2 Starting the App Is Not So Simple |
|
|
24 | (17) |
|
2.5.2.1 Click the App Icon in Launcher and Send a Message to the AMS |
|
|
25 | (5) |
|
2.5.2.2 The AMS Handles the Information from the Launcher |
|
|
30 | (1) |
|
2.5.2.3 The Launcher Goes to Sleep and Informs the AMS Again |
|
|
31 | (2) |
|
2.5.2.4 The AMS Creates a New Process |
|
|
33 | (1) |
|
2.5.2.5 Start a New Process and Inform the AMS |
|
|
34 | (1) |
|
2.5.2.6 The AMS Tells the New App Which Activity to Launch |
|
|
35 | (1) |
|
2.5.2.7 The Amazon App Starts an Activity |
|
|
35 | (2) |
|
|
|
37 | (1) |
|
|
|
38 | (3) |
|
|
|
41 | (6) |
|
2.8.1 Start Service in a New Process |
|
|
41 | (3) |
|
2.8.1.1 The App Sends a Message to the AMS to Launch Service |
|
|
42 | (1) |
|
2.8.1.2 The AMS Creates a New Process |
|
|
42 | (1) |
|
2.8.1.3 Start a New Process and Inform the AMS |
|
|
43 | (1) |
|
2.8.1.4 The AMS Sends Information to the New Process |
|
|
43 | (1) |
|
2.8.1.5 New Process to Launch Service |
|
|
43 | (1) |
|
2.8.2 Start a Service in the Same Process |
|
|
44 | (1) |
|
2.8.3 Bind a Service in the Same Process |
|
|
44 | (3) |
|
2.8.3.1 The App Sends a Message to the AMS to Bind a Service |
|
|
45 | (1) |
|
2.8.3.2 The AMS Sends Two Messages to the App Process |
|
|
45 | (1) |
|
2.8.3.3 The App Receives the First Message |
|
|
45 | (1) |
|
2.8.3.4 The App Receives the Second Message and Sends a Binder Object to the AMS |
|
|
46 | (1) |
|
2.8.3.5 AMS Informs the App |
|
|
46 | (1) |
|
|
|
47 | (4) |
|
|
|
48 | (1) |
|
|
|
49 | (2) |
|
|
|
51 | (6) |
|
2.10.1 The Essence of the ContentProvider |
|
|
54 | (1) |
|
|
|
54 | (2) |
|
2.10.3 Communication between ContentProvider and the AMS |
|
|
56 | (1) |
|
2.11 The PMS And App Installation Process |
|
|
57 | (4) |
|
|
|
57 | (1) |
|
2.11.2 App Installation Process |
|
|
58 | (1) |
|
|
|
59 | (1) |
|
2.11.4 ActivityThread and PackageManager |
|
|
60 | (1) |
|
|
|
61 | (2) |
|
|
|
63 | (1) |
|
|
|
63 | (2) |
|
|
|
65 | (12) |
|
2.15.1 A Music Player Based on Two Receivers |
|
|
65 | (6) |
|
2.15.2 A Music Player Based on One Receiver |
|
|
71 | (6) |
|
|
|
77 | (2) |
| Chapter 3 Reflection |
|
79 | (26) |
|
|
|
79 | (9) |
|
3.1.1 Get the Class Using a String |
|
|
80 | (1) |
|
3.1.1.1 Get the Class Using a String |
|
|
80 | (1) |
|
|
|
80 | (1) |
|
|
|
80 | (1) |
|
|
|
80 | (1) |
|
3.1.2 Get the Property and Method of the Class |
|
|
81 | (5) |
|
3.1.2.1 Get the Constructor of the Class |
|
|
81 | (2) |
|
3.1.2.2 Invoke a Private Method of the Class |
|
|
83 | (1) |
|
3.1.2.3 Invoke a Private and Static Method of the Class |
|
|
84 | (1) |
|
3.1.2.4 Get a Private Field of the Class and Modify Its Value |
|
|
84 | (1) |
|
3.1.2.5 Get the Private Static Field of the Class and Modify Its Value |
|
|
85 | (1) |
|
3.1.3 Generics and Singleton<T> |
|
|
86 | (2) |
|
|
|
88 | (5) |
|
3.2.1 Get a Class from a String |
|
|
89 | (1) |
|
3.2.1.1 Get a Class from a String |
|
|
89 | (1) |
|
3.2.1.2 Get a Class by Using on and get |
|
|
89 | (1) |
|
3.2.2 Get the Property and Method of a Class |
|
|
90 | (1) |
|
3.2.2.1 Get a Constructor of a Class |
|
|
90 | (1) |
|
3.2.2.2 Get the Private Method of the Class |
|
|
90 | (1) |
|
3.2.2.3 Get the Private and Static Method of the Class |
|
|
91 | (1) |
|
3.2.2.4 Get the Private Field of the Class |
|
|
91 | (1) |
|
3.2.2.5 Get the Private and Static Field of the Class |
|
|
91 | (1) |
|
3.2.3 Generics and Singleton<T> |
|
|
91 | (2) |
|
3.3 Encapsulated Classes Of The Basic Reflection |
|
|
93 | (4) |
|
|
|
93 | (1) |
|
3.3.2 Invoke Instance Methods |
|
|
94 | (1) |
|
3.3.3 Invoke Static Methods |
|
|
95 | (1) |
|
3.3.4 Get the Field of the Class and Set Its Value |
|
|
95 | (1) |
|
|
|
96 | (1) |
|
3.4 Further Encapsulation Of The Reflection |
|
|
97 | (6) |
|
3.4.1 Reflect a Method with Only One Parameter or without Parameters |
|
|
97 | (3) |
|
3.4.2 Replace String with Class Type |
|
|
100 | (1) |
|
3.4.3 Differences between the Static and Instance Fields |
|
|
101 | (1) |
|
3.4.4 Optimization of the Field Reflection |
|
|
102 | (1) |
|
|
|
103 | (2) |
| Chapter 4 Proxy Pattern |
|
105 | (10) |
|
4.1 What Is A Proxy Pattern? |
|
|
105 | (4) |
|
|
|
106 | (2) |
|
|
|
108 | (1) |
|
4.2 Static-Proxy And Dynamic-Proxy |
|
|
109 | (2) |
|
|
|
111 | (2) |
|
|
|
113 | (1) |
|
|
|
114 | (1) |
| Chapter 5 Hooking startActivity() |
|
115 | (30) |
|
5.1 Invoke startActivity() In Two Ways |
|
|
115 | (1) |
|
5.2 Hooking startActivity() Of The Activity |
|
|
116 | (15) |
|
5.2.1 Solution 1: Hooking the Method startActivityForResult of Activity |
|
|
118 | (1) |
|
5.2.2 Solution 2: Hooking the Field mInstrumentation of Activity |
|
|
118 | (3) |
|
5.2.3 Solution 3: Hooking the Method getDefault() of AMN |
|
|
121 | (4) |
|
5.2.4 Solution 4: Hooking the Field mCallback of H |
|
|
125 | (3) |
|
5.2.5 Solution 5: Hooking Instrumentation Again |
|
|
128 | (3) |
|
5.3 Hooking The Method startActivity Of Context |
|
|
131 | (2) |
|
5.3.1 Solution 6: Hooking the Field mInstrumentation of ActivityThread |
|
|
131 | (2) |
|
5.3.2 Which Solution Is the Best? |
|
|
133 | (1) |
|
5.4 Launch An Activity Not Declared In AndroidManifest.xml |
|
|
133 | (10) |
|
|
|
133 | (2) |
|
5.4.2 First Half of the Hook |
|
|
135 | (4) |
|
5.4.3 Second Half of the Hook: Hooking the Field mCallback of H |
|
|
139 | (2) |
|
5.4.4 Second Half of the Hook: Hooking the mInstrumentation Field of ActivityThread |
|
|
141 | (2) |
|
|
|
143 | (2) |
| Chapter 6 The Basic Concepts of Plug-In Techniques |
|
145 | (14) |
|
|
|
145 | (3) |
|
6.2 Interface-Oriented Programming |
|
|
148 | (3) |
|
|
|
151 | (3) |
|
6.4 Debugging In Plug-Ins |
|
|
154 | (2) |
|
6.5 Application Plug-In Solutions |
|
|
156 | (2) |
|
|
|
158 | (1) |
| Chapter 7 Resources in Plug-In |
|
159 | (22) |
|
7.1 How To Load Resources In Android |
|
|
159 | (2) |
|
|
|
159 | (1) |
|
7.1.2 Resources and AssetManager |
|
|
160 | (1) |
|
7.2 Plug-In Solutions Of Resources |
|
|
161 | (5) |
|
7.3 Solutions For Changing Skins |
|
|
166 | (12) |
|
7.4 Another Plug-In Solution For Changing Skins |
|
|
178 | (1) |
|
|
|
179 | (2) |
| Chapter 8 The Plug-In Solution of Four Components |
|
181 | (68) |
|
8.1 The Simplest Plug-In Solution |
|
|
181 | (7) |
|
8.1.1 Pre-Declare Activity and Service of the Plug-In in the HostApp's AndroidManifest.xml |
|
|
182 | (1) |
|
|
|
183 | (1) |
|
8.1.3 Start a Service of the Plug-In |
|
|
184 | (1) |
|
8.1.4 Resources in Activity |
|
|
185 | (3) |
|
8.2 A Plug-In Solution For Activity |
|
|
188 | (28) |
|
8.2.1 Launch an Activity of a Plug-In Not Declared in the AndroidManifest.xml of the HostApp |
|
|
188 | (5) |
|
8.2.2 Solution 1: Based on Dynamic-Proxy |
|
|
193 | (12) |
|
8.2.2.1 The Process of Launching an Activity |
|
|
193 | (3) |
|
8.2.2.2 Add a Plug-In Activity to the Cache |
|
|
196 | (5) |
|
8.2.2.3 Solution 1 of Loading Class in a Plug-In: Create DexClassLoader for Each Plug-In Apk |
|
|
201 | (1) |
|
8.2.2.4 Hooking More Classes |
|
|
202 | (3) |
|
8.2.3 Solution 2: Merge All the Plug-In Dexes into One Array |
|
|
205 | (3) |
|
8.2.4 Plug-In Solution of Resources |
|
|
208 | (1) |
|
8.2.5 Support LaunchMode in Plug-In |
|
|
208 | (4) |
|
8.2.6 Solution 3: Hook ClassLoader |
|
|
212 | (4) |
|
8.3 The Plug-In Solution For Service |
|
|
216 | (13) |
|
8.3.1 The Relationship Between Service and Activity |
|
|
216 | (2) |
|
|
|
218 | (2) |
|
8.3.3 Plug-In Solution to startService() |
|
|
220 | (6) |
|
8.3.4 Plug-In Solution of bindService |
|
|
226 | (3) |
|
8.4 A Plug-In Solution For BroadcastReceiver |
|
|
229 | (10) |
|
|
|
229 | (2) |
|
8.4.2 A Plug-In Solution for Dynamic Receiver |
|
|
231 | (1) |
|
8.4.3 A Plug-In Solution for Static Receiver |
|
|
231 | (2) |
|
8.4.4 A Final Plug-In Solution for Static Receiver |
|
|
233 | (6) |
|
8.5 A Plug-In Solution For ContentProvider |
|
|
239 | (8) |
|
8.5.1 The Basic Concept of ContentProvider |
|
|
239 | (1) |
|
8.5.2 A Simple Example of ContentProvider |
|
|
239 | (3) |
|
8.5.3 A Plug-In Solution for ContentProvider |
|
|
242 | (3) |
|
8.5.4 The Right Time to Install a ContentProvider Plug-In |
|
|
245 | (1) |
|
8.5.5 The Forwarding Mechanism of ContentProvider |
|
|
246 | (1) |
|
|
|
247 | (2) |
| Chapter 9 A Plug-In Solution Based on Static-Proxy |
|
249 | (58) |
|
9.1 A Plug-In Solution For Activity Based On Static-Proxy |
|
|
249 | (22) |
|
9.1.1 The Idea of Static-Proxy |
|
|
249 | (1) |
|
9.1.2 The Simplest Example of Static-Proxy |
|
|
250 | (5) |
|
9.1.2.1 Jump from the HostApp to the Plug-In |
|
|
251 | (1) |
|
9.1.2.2 Communication between ProxyActivity and Plug-In Activity |
|
|
252 | (3) |
|
9.1.2.3 The Logic of Activity in the Plug-In |
|
|
255 | (1) |
|
9.1.3 Jump in the Plug-In |
|
|
255 | (1) |
|
9.1.4 Eliminate the Keyword "that" |
|
|
256 | (3) |
|
|
|
259 | (2) |
|
9.1.5.1 Preparation for Jumping Out |
|
|
259 | (1) |
|
9.1.5.2 Jump to Another Plug-In |
|
|
260 | (1) |
|
9.1.5.3 Jump to the HostApp |
|
|
260 | (1) |
|
9.1.6 Use Interface-Oriented Programming in Static-Proxy |
|
|
261 | (6) |
|
9.1.7 Support for LaunchMode |
|
|
267 | (4) |
|
9.1.7.1 Overview of LaunchMode |
|
|
267 | (2) |
|
9.1.7.2 Plug-In Solutions for LaunchMode |
|
|
269 | (2) |
|
9.2 The Plug-In Solution For Service And BroadcastReceiver Based On Static-Proxy |
|
|
271 | (34) |
|
9.2.1 Static-Proxy in Service |
|
|
271 | (7) |
|
|
|
276 | (1) |
|
|
|
277 | (1) |
|
|
|
278 | (1) |
|
9.2.2 Support bindService() |
|
|
278 | (2) |
|
|
|
280 | (3) |
|
9.2.4 The Last Solution for Service Plug-Ins: Integration with Dynamic-Proxy and Static-Proxy |
|
|
283 | (18) |
|
9.2.4.1 Parse Service in the Plug-In |
|
|
283 | (2) |
|
9.2.4.2 Create a Service Object Using Reflection |
|
|
285 | (2) |
|
9.2.4.3 ProxyService and ServiceManager |
|
|
287 | (7) |
|
9.2.4.4 bindService() and unbindService() |
|
|
294 | (7) |
|
9.2.5 Static-Proxy in BroadcastReceiver |
|
|
301 | (4) |
|
|
|
305 | (2) |
| Chapter 10 Related Plug-In Techniques |
|
307 | (98) |
|
10.1 Resolve The Conflicts Between Resources Of The Plug-Ins |
|
|
307 | (13) |
|
10.1.1 The Process of App Packaging |
|
|
307 | (1) |
|
|
|
308 | (8) |
|
10.1.2.1 Modify and Generate a New aapt Command |
|
|
308 | (6) |
|
10.1.2.2 Using This New aapt Command in the Project |
|
|
314 | (2) |
|
|
|
316 | (2) |
|
10.1.4 Plug-In Uses Resources in the HostApp |
|
|
318 | (2) |
|
10.2 A Plug-In Framework Based On Fragment |
|
|
320 | (6) |
|
10.2.1 AndroidDynamicLoader Overview |
|
|
320 | (1) |
|
10.2.2 A Simple Plug-In Sample Based on Fragment |
|
|
321 | (1) |
|
10.2.3 Jumping Between Fragments |
|
|
322 | (2) |
|
10.2.4 Jump from the Plug-In |
|
|
324 | (2) |
|
|
|
326 | (15) |
|
10.3.1 From Activity to HTML5 |
|
|
328 | (6) |
|
10.3.2 From HTML5 to Activity |
|
|
334 | (6) |
|
10.3.3 Support for the Backpress Button |
|
|
340 | (1) |
|
10.4 ProGuard For Plug-Ins |
|
|
341 | (11) |
|
10.4.1 Basic Obfuse Rules for Plug-Ins |
|
|
341 | (1) |
|
10.4.2 Obfuse Without a Common Library |
|
|
342 | (3) |
|
10.4.3 Obfusing with a Common Library |
|
|
345 | (7) |
|
|
|
346 | (3) |
|
10.4.3.2 Modify the ProGuard File |
|
|
349 | (1) |
|
10.4.3.3 Remove Redundant Dexes from plugin1.apk |
|
|
350 | (2) |
|
|
|
352 | (4) |
|
10.5.1 The Basic Concept of an Incremental Update |
|
|
352 | (1) |
|
10.5.2 Create an Incremental Package |
|
|
353 | (1) |
|
|
|
353 | (1) |
|
10.5.4 Merge Incremental Package |
|
|
354 | (2) |
|
10.6 A Plug-In Solution For SO Files |
|
|
356 | (17) |
|
10.6.1 Write a Hello-World SO |
|
|
356 | (6) |
|
|
|
356 | (1) |
|
10.6.1.2 Create a Project to Generate SO |
|
|
357 | (5) |
|
|
|
362 | (1) |
|
10.6.3 The Principle of Loading SO |
|
|
363 | (5) |
|
|
|
364 | (1) |
|
10.6.3.2 The Process of Loading SO |
|
|
365 | (1) |
|
10.6.3.3 Two Ways to Load SO |
|
|
365 | (3) |
|
10.6.3.4 The Relationship between ClassLoader and SO |
|
|
368 | (1) |
|
10.6.4 A Plug-In Solution Based on System.load() |
|
|
368 | (4) |
|
10.6.5 An SO Plug-In Solution Based on System.loadLibrary() |
|
|
372 | (1) |
|
10.7 Hooking The Packaging Process |
|
|
373 | (14) |
|
10.7.1 Gradle Plug-In Project |
|
|
373 | (6) |
|
10.7.1.1 Create Gradle Plug-In Project |
|
|
373 | (3) |
|
|
|
376 | (1) |
|
10.7.1.3 The Hook App Packaging Process |
|
|
377 | (2) |
|
10.7.2 Modify resources.arsc |
|
|
379 | (8) |
|
10.7.2.1 How to Find Resources in Android |
|
|
379 | (1) |
|
10.7.2.2 Function of aapt |
|
|
380 | (1) |
|
10.7.2.3 The Principle of Gradle-Small |
|
|
380 | (1) |
|
10.7.2.4 How to Use Gradle-Small |
|
|
381 | (1) |
|
10.7.2.5 The Family of Plug-Ins Defined in Gradle-Small |
|
|
381 | (4) |
|
10.7.2.6 The Family of Editors Defined in Gradle-Small |
|
|
385 | (2) |
|
10.8 Compatibility With Android O and P |
|
|
387 | (17) |
|
10.8.1 Compatibility with Android O |
|
|
388 | (5) |
|
|
|
388 | (2) |
|
10.8.1.2 The Story of Element and DexFile |
|
|
390 | (3) |
|
10.8.2 Compatibility with Android P |
|
|
393 | (16) |
|
10.8.2.1 The Modification of the Class H |
|
|
393 | (8) |
|
10.8.2.2 The Refactoring of the Class Instrumentation |
|
|
401 | (3) |
|
|
|
404 | (1) |
| Chapter 11 Summary of Plug-In Technology |
|
405 | (6) |
|
|
|
405 | (1) |
|
11.2 Class Loading In The Plug-In |
|
|
405 | (1) |
|
11.3 Which Class Or Interface Can Be Hooked? |
|
|
406 | (1) |
|
11.4 A Plug-In Solution For Activity |
|
|
407 | (1) |
|
11.5 A Plug-In Solution For Resources |
|
|
407 | (1) |
|
11.6 Use Fragment In The Plug-In |
|
|
408 | (1) |
|
11.7 Plug-In Solutions For Service, ContentProvider, And BroadcastReceiver |
|
|
409 | (1) |
|
11.7.1 A Plug-In Solution for Service |
|
|
409 | (1) |
|
11.7.2 A Plug-In Solution for BroadcastReceiver |
|
|
409 | (1) |
|
11.7.3 A Plug-In Solution for ContentProvider |
|
|
410 | (1) |
|
|
|
410 | (1) |
| Appendix A: Sample Code List |
|
411 | (4) |
| Index |
|
415 | |