本书的主要内容有:了解Kotlin基础知识和Kotlin集合框架。探索Android基础:操作系统和应用容器及其组件。了解线程安全以及如何处理并发。编写低开销顺序异步工作。使用协程检查结构化并发性,并了解通道如何支持协程通信。了解如何使用流完成异步数据处理。使用Android性能分析工具了解性能问题。使用性能优化减少资源消耗。
为Android移动操作系统开发应用似乎很令人生畏,尤其是如果还需要学习一种新的编程语言:Kotlin,这是目前Android的官方开发语言。利用这本实用的书,Android开发人员将学习如何从Java过渡到Kotlin,包括Kotlin如何为获得异步计算控制提供真正的优势。
本书作者探讨了原生Android开发中常见任务的实现,并展示了Kotlin如何帮助你解决并发问题。这本书主要关注结构化并发(一种新的异步编程范式),将带你了解Kotlin最z强大的构造之一:协程。
前言JetBrains 创建Kotlin 有两个原因:没有一种语言可以填补Android 开发中使用(遗留)Java 库的所有空白,另外一种新的语言将允许Android 开发引领趋势,而不只是追随潮流。2015 年2 月,Kotlin 10 正式发布。Kotlin 简洁、安全、实用,并且强调与Java代码的互操作性。当今使用Java 的任何地方都可以使用Kotlin:服务器端开发、Android 应用、桌面或移动客户端、物联网设备编程等。Kotlin 在Android 开发人员中迅速流行起来,Google 决定采用Kotlin 作为Android 开发的官方语言,这使得人们对这个语言的兴趣暴涨。根据Android 开发者网站(https://developerandroidcom/kotlin),目前有超过60% 的专业Android 开发人员使用Kotlin。Android 的学习曲线相当陡峭:不可否认,它很难学习,更难掌握。对很多人来说,Android 开发人员成长的一部分,就是随着时间的推移,要不断处理Android操作系统与应用之间意想不到的交互。本书通过研究Android 中的这些问题,旨在向读者深入详尽地介绍这些情况。我们不仅会讨论Kotlin 和Java,还将讨论使用Android 时出现的并发问题,以及Kotlin 如何解决这些问题。有时我们会将Kotlin 与Java 进行比较,因为我们认为这样做能更好地理解(特别是大部分读者都可能有Java 背景)。我们可以利用实用示例演示如何弥补二者的差距,并展示大多数Kotlin 操作的底层概念都与Java 的相应概念很类似。我们将按主题组织这些任务,对涉及的大量信息进行结构化分解,以便软件工程师掌握,并展示如何使应用健壮并且可维护。另外,熟悉Java 的用户(包括Android 开发人员)会发现,我们同时在Java 和Kotlin 中介绍各个常见任务时,它们的学习曲线会大大变平。在适当的情况下,我们会讨论其中一个语言或两个语言的区别和缺陷,不过我们希望提供简单易懂的任务示例,使读者能够掌握和适应现代范式,并立即本能地意识到更新代码的重要性。尽管Kotlin 与Java 可完全互操作,但其他Java 应用开发(服务器端编程、桌面客户端、中间件等)还没有赶上Android 的程度。这很大程度上是由于Android的维护者(Google)强烈鼓励其用户做出改变。用户逐步迁移到Kotlin,但更多的用户仍然使用Java 来完成关键任务。我们希望这本书能成为Android 开发人员的生命线,让他们能够放心地利用Kotlin 提供的优势和简单性。本书面向的读者这本书面向超过600 万Android 工程师中的每一个人。我们相信几乎每个Android 工程师都能从这本书中受益。可能有一小部分人能流利地使用Kotlin,即使如此,他们也能从我们介绍的信息中有所收获。但事实上,我们面向的是绝大多数还没有过渡到Kotlin 的人。这本书也适合那些在以Java 为中心的Android开发中已经接触过Kotlin,但还没有完全熟悉Kotlin 的人:场景1读者精通Java,听说过这种新的Kotlin 语言,并想尝试一下。所以他们读了一些在线教程,开始使用,效果很好。很快他们就意识到这不仅仅是一种新的语法。习惯用法不一样了(例如,函数式编程,协程),现在可以采用一种全新的开发方式。不过他们缺乏指导。对他们来说,这本书将非常适合。场景2读者是一个Java 开发小团队的一员。他们对是否应该在项目中包含Kotlin 进行了讨论。尽管据说Kotlin 与Java 100% 可互操作,但一些同事认为引入另一种语言会增加项目的复杂性。还有一些人认为,由于需要掌握两种语言,这可能会限制能够参与该项目的同事人数。如果能证明利大于弊,这些读者可以用这本书来说服他们的同事。场景3有经验的Android 开发人员可能使用过Kotlin 或用Kotlin 写过一个功能,但需要完成具体工作时,还是会使用Java。我们发现现在就是这种情况,这本书会让我们的生活更轻松。这也是我们周围最常见的状态,很多Android 开发人员接触过Kotlin,认为他们足够了解这个语言,能够在必要时编写Kotlin代码,但他们要么没有意识到要么根本不相信数据类、不可变属性和结构化并发的重要性。我们认为这本书能让一个好奇的人成为一个尽心尽力的布道者。为什么写这本书有大量的书介绍Android 如何工作,Kotlin 如何工作,或者并发如何工作。Kotlin因其易用性和更简洁的语法在Android 开发中广受欢迎,但Kotlin 为Android 提供的远不止这些:它提供了解决Android 并发问题的新方法。我们写这本书是为了深入地探讨这些主题之间特定的关系。不论单独来看还是合在一起,Android和Kotlin 都在快速变化。想要跟上所有这些变化可能很困难。我们把这本书看作是一个有意义的检查点:它介绍了Android 的起源,当前的位置,以及随着Kotlin 语言的成熟,将如何继续与Kotlin 一起发展。本书内容组织有时我们会加入代码片段的截图,而不是常规的atlas 代码格式。这对于协程和流特别有用,因为在截图中可以清楚地看到挂起点,还可以获得IDE 的类型提示。第1 章Kotlin 基础和第2 章Kotlin 集合框架介绍了Kotlin 中实现Android编程的重大转变。虽然这几章中的信息足以为你奠定一个很好的Kotlin 基础,不过后面的章节将更深入地探讨更复杂/ 更高级的特性。熟悉Java 或类似语法结构的用户会发现这种转换非常自然。第3 章Android 基础和第4 章Android 并发将提供与内存和线程相关的Android 系统基础知识。与其他操作系统一样,并发很难实现。第5 章线程安全到第11 章用Android 性能分析工具检查性能问题将研究围绕内存和线程的常见问题,同时指出Android 框架如何随着时间的推移逐步演化,从而赋予开发人员更多的控制。同时,这些章节还展示了Kotlin 的扩展和语言特性如何帮助开发人员更快地编写更好的应用。第12 章利用性能优化减少资源消耗将探讨使用强大的Android 开发工具来检查底层性能和与内存相关的分析,从而能发现你从未真正了解的问题。这本书将为工程师提供原生Android 开发中常见任务的专业开发和管理实现。很多任务包括一个现实问题,然后是用Java 和Kotlin 实现的相应解决方案。需要进一步的解释时,在解决方案后面会做一个简单的比较,并强调Kotlin 语言的简洁与自然。排版约定本书使用了下述排版约定:斜体(Italic)表示新术语、URL、电子邮件地址、文件名和扩展名。等宽字体(Constant Width)表示程序片段,以及正文中出现的变量、函数名、数据库、数据类型、环境变量、语句和关键字等。加粗等宽字体(constant width bold)表示应该由用户输入的命令或其他文本。等宽斜体(constant width italic)表示应该由用户输入的值或根据上下文确定的值替换的文本。使用代码示例这本书的补充材料( 代码示例、练习等) 可以从https://githubcom/ProgrammingAndroidWithKotlin 下载。如果使用代码示例时有技术问题或遇到其他问题,请通过以下email 联系我们:bookquestions@oreillycom。这本书的目的就是要帮助你完成工作。一般来讲,你可以在你的程序和文档中使用这些代码,不需要联系我们来得到许可,除非你直接复制了大部分的代码。例如,如果你在编写一个程序,使用了本书中的多段代码,这并不需要得到许可。但是出售或发行OReilly 书示例代码则需要得到许可。回答问题时如果引用了这本书的文字和示例代码,这不需要得到许可。但是如果你的产品的文档借用了本书中的大量示例代码,则需要得到许可。我们希望但不严格要求标明引用出处。引用信息通常包括书名、作者、出版商和ISBN。例如Programming Androidwith Kotlin by Pierre-Olivier Laurence, Amanda Hinchman-Dominguez, G BlakeMeike, and Mike Dunn (OReilly) Copyright 2022 Pierre-Olivier Laurence andAmanda Hinchman-Dominguez, 978-1-492-06300-1。如果你认为你在使用代码示例时超出了合理使用范围或者上述许可范围,可以随时联系我们:permissions@oreillycom。OReilly 在线学习平台(OReilly Online Learning)近40 年来,OReilly Media 致力于提供技术和商业培训、知识和卓越见解,来帮助众多公司取得成功。公司独有的专家和改革创新者网络通过OReilly 书籍、文章以及在线学习平台,分享他们的专业知识和实践经验。OReilly 在线学习平台按照您的需要提供实时培训课程、深入学习渠道、交互式编程环境以及来自OReilly 和其他200 多家出版商的大量书籍与视频资料。更多信息,请访问网站:https://wwworeillycom/。联系我们任何有关本书的意见或疑问,请按照以下地址联系出版社。美国:OReilly Media, Inc1005 Gravenstein Highway NorthSebastopol, CA 95472中国:北京市西城区西直门南大街2 号成铭大厦C 座807 室(100035)奥莱利技术咨询(北京)有限公司针对这本书,我们还建有一个网页,列出了有关勘误、示例和其他信息。可以通过以下地址访问这个页面:https://oreilly/pak。如果对这本书有什么意见,或者询问技术上的问题,请发送电子邮件至errata@oreillycomcn。有关我们的图书和课程,更多新闻和信息请访问我们的网站:http://wwworeillycom。我们的Facebook:http://facebookcom/oreilly。我们的Twitter:http://twittercom/oreillymedia。我们的YouTube:http://youtubecom/oreillymedia。致谢感谢我们的技术审校Adnan Sozuan 和Andrew Gibel,经他们之手,这本书得到了极大的增强和改进。还要感谢OReilly 的人员,他们帮助我们团结在一起,给予了我们所需的全部支持,终于将这本书变成现实,尤其是Jeff Bleiel 和Zan McQuade。感谢Roman Elizarov 和Jake Wharton 抽出时间与我们讨论Kotlin 并发的发展方向和Android 的底层问题。感谢朋友、家人和同事们的支持。感谢Kotlin 社区,以及花时间阅读早期草稿并提供反馈的所有人。最后,这本书谨献给Mike Dunn:合著者、同事、朋友和父亲。我们非常想念他,希望这本书能让他感到骄傲。
Pierre-Olivier Laurence是法国巴黎附近Safran Aircraft Engines公司的首席软件工程师。Amanda Hinchman-Dominguez是Kotlin方面的Google Developer Expert,也是Groupon的Android工程师,活跃在全球Kotlin社区。G Blake Meike是Couchbase的高级软件工程师,著有多本书,包括《Programming Android》。Mike Dunn是Oreilly Media的首席移动工程师,也是Oreilly 《Native mobile Development》一书的作者。
目录
前言 1
第1 章 Kotlin 基础 9
11 Kotlin 类型系统 10
111 基本类型 10
112 Null 安全性 11
113 Unit 类型 14
114 函数类型 15
115 泛型 17
12 变量和函数 17
121 变量 18
122 Lambda 18
123 扩展函数 19
13 类 21
131 类初始化 22
132 属性 23
133 lateinit 属性 25
134 懒属性 27
135 委托 29
136 伴随对象 29
137 数据类 30
138 枚举类 32
139 密封类 34
14 可见性修饰符 35
15 小结 37
第2 章 Kotlin 集合框架 39
21 集合基础40
211 Java 互操作性 40
212 可变性 41
213 重载操作符 42
214 创建容器 43
22 函数式编程 45
221 函数式与过程式编程:简单示例 45
222 函数式Android 47
23 Kotlin 转换函数 47
231 Boolean 函数 47
232 Filter 函数 48
233 Map 49
234 flatMap 51
235 分组 53
236 迭代器与序列 54
24 示例 56
241 问题 56
242 实现 57
25 小结 64
第3 章 Android 基础 65
31 Android 堆栈 65
311 硬件 66
312 内核 67
313 系统服务 67
314 Android 运行时环境 67
315 应用 68
32 Android 应用环境 68
321 意图和意图过滤器 69
322 上下文 71
33 Android 应用组件:构建模块 75
331 活动及相关特性 75
332 服务 80
333 内容提供者 85
334 广播接收者 86
34 Android 应用架构 88
341 MVC:基础 88
342 部件 89
343 局部模型 90
35 Android 模式 90
351 模型?C 视图?C 意图 90
352 模型?C 视图?C 演示器91
353 模型?C 视图?C 视图模型 91
36 小结 93
第4 章 Android 并发 95
41 线程安全性 96
411 原子性 97
412 可见性 97
42 Android 线程模型 99
43 丢帧 100
44 内存泄漏102
45 管理线程的工具 105
451 Looper/Handler 105
452 Executor 和ExecutorService 108
46 管理任务的工具 110
461 JobScheduler 111
462 WorkManager 114
47 小结 115
第5 章 线程安全 117
51 线程问题示例 118
52 不变性条件 120
521 互斥锁 120
522 线程安全集合 121
53 线程封闭124
54 线程竞争124
55 阻塞调用与非阻塞调用 125
56 工作队列126
57 背压 128
58 小结 130
第6 章 使用回调处理并发 131
61 购买特性示例 132
62 创建应用134
621 视图模型 134
622 视图 136
623 实现逻辑 140
624 讨论 141
63 线程模型的限制 143
64 小结 144
第7 章 协程概念 147
71 到底什么是协程 147
711 你的第一个协程 148
712 async 协程创建器 151
72 关于结构化并发 153
73 结构化并发中的父?C 子关系 155
74 CoroutineScope 和CoroutineContext 157
75 挂起函数164
76 挂起函数原理 165
77 使用协程和挂起函数:实用示例 169
78 不要误解suspend 修饰符 172
79 小结 173
第8 章 协程实现结构化并发 175
81 挂起函数175
811 场景设置 176
812 使用javautilconcurrentExecutorService 的传统方法 178
813 回顾HandlerThread181
814 使用挂起函数和协程185
815 挂起函数与线程小结189
82 取消 190
821 协程生命周期 190
822 取消协程 192
823 取消委托给第三方库的任务 195
824 与取消合作的协程 199
825 delay 是可取消的 201
826 处理取消 202
827 取消原因 203
83 监督 206
84 supervisorScope 构建器 208
85 并行分解209
86 自动取消210
87 异常处理210
871 未处理和公布的异常 211
872 公布异常 213
873 未处理异常 215
88 小结 218
89 结语 219
第9 章 通道 221
91 通道概述222
911 会合通道 224
912 无限通道 228
913 合并通道 229
914 缓冲通道 230
915 通道生产者 231
92 通信顺序进程 232
921 模型和架构 232
922 第一个实现 234
923 select 表达式 239
924 综合 241
925 扇出和扇入 243
926 性能测试 244
927 背压 245
928 与Actor 模型的相似性 246
929 进程中顺序执行 247
9210 结语 248
93 CSP 中的死锁 248
94 要点总结251
95 通道的限制 252
96 热通道 253
97 小结 254
第10 章 流 257
101 流简介 258
1011 一个更现实的例子 259
1012 操作符 261
1013 终端操作符262
102 冷流使用示例 262
1021 用例1:与基于回调的API 交互 262
1022 用例2:并发转换值流 268
1023 出错时会发生什么 270
1024 结语 270
1025 用例3:创建定制操作符 271
1026 用法 273
103 错误处理 274
1031 try/catch 块 275
1032 关注点分离很重要 277
1033 违反异常透明性 278
1034 catch 操作符 279
1035 封装发射异常 282
104 用SharedFlow 实现热流 285
1041 创建SharedFlow 286
1042 注册订阅者287
1043 向SharedFlow 发射值 287
1044 使用SharedFlow 传递数据 288
1045 使用SharedFlow 作为事件总线 294
1046 StateFlow:专用SharedFlow 295
1047 StateFlow 使用示例 296
105 小结 298
第11 章 用Android 性能分析工具检查性能问题 299
111 Android Profiler 301
1111 Network Profiler 305
1112 CPU Profiler 311
1113 Energy Profiler 322
1114 Memory Profiler 325
112 用LeakCanary 检测内存泄漏 330
113 小结 334
第12 章 利用性能优化减少资源消耗 337
121 用ConstraintLayout 得到更扁平的视图层次结构 338
122 利用可绘制对象减少编程绘制 342
123 最小化网络调用中的资产负载 347
124 位图池和缓存 348
125 减少不必要的工作 349
126 使用静态函数 352
127 使用R8 和ProGuard 实现缩小和混淆 352
128 小结 354