| Preface |
|
ix | |
|
|
|
1 | (28) |
|
|
|
2 | (6) |
|
|
|
2 | (1) |
|
|
|
3 | (2) |
|
|
|
5 | (1) |
|
|
|
6 | (2) |
|
|
|
8 | (1) |
|
|
|
8 | (4) |
|
|
|
8 | (1) |
|
|
|
9 | (1) |
|
|
|
10 | (2) |
|
|
|
12 | (12) |
|
|
|
12 | (2) |
|
|
|
14 | (1) |
|
|
|
15 | (2) |
|
|
|
17 | (1) |
|
|
|
18 | (1) |
|
|
|
19 | (1) |
|
|
|
20 | (1) |
|
|
|
21 | (2) |
|
|
|
23 | (1) |
|
|
|
24 | (2) |
|
|
|
26 | (3) |
|
2 The Kotlin Collections Framework |
|
|
29 | (24) |
|
|
|
29 | (5) |
|
|
|
30 | (1) |
|
|
|
30 | (2) |
|
|
|
32 | (1) |
|
|
|
33 | (1) |
|
|
|
34 | (3) |
|
Functional Versus Procedural: A Simple Example |
|
|
35 | (1) |
|
|
|
36 | (1) |
|
Kotlin Transformation Functions |
|
|
37 | (7) |
|
|
|
37 | (1) |
|
|
|
38 | (1) |
|
|
|
38 | (2) |
|
|
|
40 | (2) |
|
|
|
42 | (1) |
|
Iterators Versus Sequences |
|
|
43 | (1) |
|
|
|
44 | (7) |
|
|
|
44 | (1) |
|
|
|
45 | (6) |
|
|
|
51 | (2) |
|
|
|
53 | (28) |
|
|
|
53 | (2) |
|
|
|
54 | (1) |
|
|
|
54 | (1) |
|
|
|
55 | (1) |
|
Android Runtime Environment |
|
|
55 | (1) |
|
|
|
55 | (1) |
|
The Android Application Environment |
|
|
55 | (7) |
|
Intents and Intent Filters |
|
|
57 | (2) |
|
|
|
59 | (3) |
|
Android Application Components: The Building Blocks |
|
|
62 | (11) |
|
The Activity and Its Friends |
|
|
62 | (5) |
|
|
|
67 | (4) |
|
|
|
71 | (1) |
|
|
|
72 | (1) |
|
Android Application Architectures |
|
|
73 | (3) |
|
|
|
74 | (1) |
|
|
|
75 | (1) |
|
|
|
75 | (1) |
|
|
|
76 | (2) |
|
|
|
76 | (1) |
|
|
|
76 | (1) |
|
|
|
77 | (1) |
|
|
|
78 | (3) |
|
|
|
81 | (20) |
|
|
|
82 | (2) |
|
|
|
82 | (1) |
|
|
|
83 | (1) |
|
The Android Threading Model |
|
|
84 | (1) |
|
|
|
85 | (2) |
|
|
|
87 | (3) |
|
Tools for Managing Threads |
|
|
90 | (5) |
|
|
|
91 | (2) |
|
Executors and ExecutorServices |
|
|
93 | (2) |
|
|
|
95 | (4) |
|
|
|
96 | (2) |
|
|
|
98 | (1) |
|
|
|
99 | (2) |
|
|
|
101 | (14) |
|
An Example of a Thread Issue |
|
|
101 | (2) |
|
|
|
103 | (4) |
|
|
|
104 | (1) |
|
|
|
104 | (3) |
|
|
|
107 | (1) |
|
|
|
108 | (1) |
|
Blocking Call Versus Nonblocking Call |
|
|
109 | (1) |
|
|
|
110 | (1) |
|
|
|
111 | (2) |
|
|
|
113 | (2) |
|
6 Handling Concurrency Using Callbacks |
|
|
115 | (14) |
|
Example-of-Purchase Feature |
|
|
116 | (2) |
|
|
|
118 | (8) |
|
|
|
118 | (1) |
|
|
|
119 | (4) |
|
|
|
123 | (1) |
|
|
|
124 | (2) |
|
Limitations of the Threading Model |
|
|
126 | (1) |
|
|
|
127 | (2) |
|
|
|
129 | (28) |
|
What Exactly Is a Coroutine? |
|
|
129 | (5) |
|
|
|
130 | (3) |
|
The async Coroutine Builder |
|
|
133 | (1) |
|
A Quick Detour About Structured Concurrency |
|
|
134 | (3) |
|
The Parent-Child Relationship in Structured Concurrency |
|
|
137 | (1) |
|
CoroutineScope and CoroutineContext |
|
|
138 | (7) |
|
|
|
145 | (1) |
|
Suspending Functions Under the Hood |
|
|
146 | (4) |
|
Using Coroutines and Suspending Functions: A Practical Example |
|
|
150 | (3) |
|
Don't Be Mistaken About the suspend Modifier |
|
|
153 | (1) |
|
|
|
154 | (3) |
|
8 Structured Concurrency with Coroutines |
|
|
157 | (44) |
|
|
|
157 | (14) |
|
|
|
158 | (2) |
|
Traditional Approach Using java.util.concurrent.ExecutorService |
|
|
160 | (3) |
|
A Reminder About HandlerThread |
|
|
163 | (4) |
|
Using Suspending Functions and Coroutines |
|
|
167 | (4) |
|
Summary of Suspending Functions Versus Traditional Threading |
|
|
171 | (1) |
|
|
|
171 | (16) |
|
|
|
172 | (2) |
|
|
|
174 | (2) |
|
Cancelling a Task Delegated to a Third-Party Library |
|
|
176 | (4) |
|
Coroutines That Are Cooperative with Cancellation |
|
|
180 | (2) |
|
|
|
182 | (1) |
|
|
|
183 | (1) |
|
|
|
184 | (3) |
|
|
|
187 | (2) |
|
|
|
189 | (1) |
|
|
|
189 | (2) |
|
|
|
191 | (1) |
|
|
|
191 | (8) |
|
Unhandled Versus Exposed Exceptions |
|
|
191 | (2) |
|
|
|
193 | (3) |
|
|
|
196 | (3) |
|
|
|
199 | (1) |
|
|
|
200 | (1) |
|
|
|
201 | (34) |
|
|
|
202 | (10) |
|
|
|
204 | (4) |
|
|
|
208 | (1) |
|
|
|
209 | (1) |
|
|
|
210 | (1) |
|
|
|
211 | (1) |
|
Communicating Sequential Processes |
|
|
212 | (15) |
|
|
|
213 | (1) |
|
|
|
214 | (5) |
|
|
|
219 | (2) |
|
|
|
221 | (1) |
|
|
|
222 | (1) |
|
|
|
223 | (1) |
|
|
|
224 | (1) |
|
Similarities with the Actor Model |
|
|
225 | (1) |
|
Execution Is Sequential Inside a Process |
|
|
226 | (1) |
|
|
|
226 | (1) |
|
|
|
227 | (2) |
|
|
|
229 | (1) |
|
|
|
230 | (2) |
|
|
|
232 | (1) |
|
|
|
233 | (2) |
|
|
|
235 | (40) |
|
|
|
236 | (4) |
|
|
|
237 | (2) |
|
|
|
239 | (1) |
|
|
|
239 | (1) |
|
Examples of Cold Flow Usage |
|
|
240 | (11) |
|
Use Case #1 Interface with a Callback-Based API |
|
|
240 | (5) |
|
Use Case #2 Concurrently Transform a Stream of Values |
|
|
245 | (2) |
|
What Happens in Case of Error? |
|
|
247 | (1) |
|
|
|
248 | (1) |
|
Use Case #3 Create a Custom Operator |
|
|
248 | (3) |
|
|
|
251 | (1) |
|
|
|
251 | (11) |
|
|
|
252 | (2) |
|
Separation of Concern Is Important |
|
|
254 | (1) |
|
Exception Transparency Violation |
|
|
255 | (1) |
|
|
|
256 | (3) |
|
Materialize Your Exceptions |
|
|
259 | (3) |
|
Hot Flows with SharedFlow |
|
|
262 | (12) |
|
|
|
263 | (1) |
|
|
|
263 | (1) |
|
Send Values to the SharedFlow |
|
|
264 | (1) |
|
Using SharedFlow to Stream Data |
|
|
264 | (6) |
|
Using SharedFlow as an Event Bus |
|
|
270 | (1) |
|
StateFlow: A Specialized SharedFlow |
|
|
271 | (1) |
|
An Example of StateFlow Usage |
|
|
272 | (2) |
|
|
|
274 | (1) |
|
11 Performance Considerations with Android Profiling Tools |
|
|
275 | (36) |
|
|
|
277 | (27) |
|
|
|
280 | (6) |
|
|
|
286 | (11) |
|
|
|
297 | (2) |
|
|
|
299 | (5) |
|
Detecting Memory Leaks with LeakCanary |
|
|
304 | (4) |
|
|
|
308 | (3) |
|
12 Trimming Down Resource Consumption with Performance Optimizations |
|
|
311 | (18) |
|
Achieving Flatter View Hierarchy with ConstraintLayout |
|
|
312 | (4) |
|
Reducing Programmatic Draws with Drawables |
|
|
316 | (5) |
|
Minimizing Asset Payload in Network Calls |
|
|
321 | (1) |
|
Bitmap Pooling and Caching |
|
|
321 | (2) |
|
Reducing Unnecessary Work |
|
|
323 | (2) |
|
|
|
325 | (1) |
|
Minification and Obfuscation with R8 and ProGuard |
|
|
326 | (1) |
|
|
|
327 | (2) |
| Index |
|
329 | |