第 1章 开始启程——你的第 一行+ f' q/ v' h5 x& E! ?( N4 p D
, y. L$ D0 a3 z) o. A6 d; UAndroid代码 1+ r% w- M+ Y9 @
0 x* ^ O- ]% j3 p) k* i1.1 了解全貌,Android王国简介 2
+ Q" s, ^3 t L1 ~1 q" d1 g: W" @$ R( i6 `2 @3 i8 B: ~3 s
1.1.1 Android系统架构 2
% E9 g' ^( G5 p9 z( f+ m) m
8 Q; ]% ~( @' e" g% z7 l1.1.2 Android已发布的版本 3
3 d$ U5 s& \4 o6 O1 w( K. S/ m. C3 ] o; Y* B0 L0 `
1.1.3 Android应用开发特色 4' \' t4 c# E, o8 Y. i
; b' H2 e8 c4 w7 F; F. Y+ y1.2 手把手带你搭建开发环境 56 K6 ]- \! k; E& w
" |/ g5 m" i2 g) [' Y0 Y2 y0 s5 _% q
1.2.1 准备所需要的工具 5
& M% o" V% s3 h# o! S* W+ Q3 m; c; j" I8 W+ X7 ~
1.2.2 搭建开发环境 5+ q, M( F l }7 ]8 S4 P- o
. ~' f# }! S; w4 }8 p: h# @1.3 创建你的第 一个Android项目 9) h/ a4 n+ Z8 {9 L% ]2 e1 W( e
/ m( ~2 z: V/ l1 I2 |
1.3.1 创建HelloWorld项目 9' Y# T+ f3 b) _% f
: m5 [3 g4 i$ b
1.3.2 启动模拟器 11
; Y) J4 Y5 u4 R2 w( T4 e
' U, n: K. ]0 l5 P: c1.3.3 运行HelloWorld 14
# h7 D- ?" o6 b% a. E1 }) d8 y1 H& u$ o0 d! ]1 A6 i
1.3.4 分析你的第 一个Android程序 15' c6 X: G( w+ }; Q9 b4 M( N$ R
. E4 B9 q0 G7 W6 v5 G
1.3.5 详解项目中的资源 20 @, h" e }+ e
3 m8 a. [6 W7 a1.3.6 详解build.gradle文件 22
3 o( K+ C# K" a! Y5 m! |# i4 t, z- C* x
1.4 前行:掌握日志工具的使用 250 R9 ^" V( v+ E4 ^- r
+ t4 Z9 L; a% u8 k: X1.4.1 使用Android的日志工具Log 25
* \$ ]: n* b, v8 O0 f- d+ L' R+ g4 @: V% k2 R& ~/ r. F
1.4.2 为什么使用Log而不使用println() 26
: j/ z& z3 H" j7 ^2 w+ p; e9 l1 U: u: o2 G, z2 x a2 V
1.5 小结与点评 28
# e! M1 \- {, I# c/ \/ S1 @. H$ |3 I* G1 R8 y
第 2章 探究新语言,快速入门Kotlin3 e3 n- G# Q0 t
5 G' q5 Q9 g* `1 L1 Y
编程 30- n) ^' _/ |: w6 m, k
- e# @1 O7 ?; x" B6 d2.1 Kotlin语言简介 31
* `! Y$ E6 q, ]. h* L9 q9 U1 h1 \
# u5 l g/ n& V& }# Q |; `2.2 如何运行Kotlin代码 326 t2 x$ E- E" U) Q- d: z
+ g) Q& b( c4 T
2.3 编程之本:变量和函数 35
+ G) T* A0 y+ R1 Y) F
, s3 D" b3 |2 v2 S% i3 i- A* g2.3.1 变量 35
" p. m9 M. s; [( q+ A; W) l9 V- V4 z9 s1 l' I2 B, u. O. ^
2.3.2 函数 373 N) l6 m; `3 R0 E' w: Q' B5 u
8 e3 k1 M% t3 h7 t3 l, B( U! M
2.4 程序的逻辑控制 41
8 n: U$ G+ p' b2 j
, b# S7 E6 M. {2.4.1 if条件语句 410 i) S, i' {9 a6 `9 \, b
F1 f( \6 q& h: i' P
2.4.2 when条件语句 42
. }9 V+ n) U5 I! G5 v
. o. y4 K2 f h/ H2.4.3 循环语句 45
5 \6 W' e9 m& c2 J2 S# K
X" ~+ ]: |2 c1 g9 N2.5 面向对象编程 48
9 a! }& ?3 t+ B0 Z7 o
B, [5 r) m# O- n- Z, f ~2.5.1 类与对象 499 c* a7 u/ H# R: j0 g, t4 o) s
, G3 z0 K$ e+ ?8 W2.5.2 继承与构造函数 50
8 v6 T1 K* b5 P, E/ J9 _/ E: |) y- L4 Q
2.5.3 接口 55+ r# [8 V5 I' y7 ^ Q
9 `4 q: O4 t/ `2.5.4 数据类与单例类 58% F+ F( [# U7 E
) m; W8 K" e7 O- q# x2 o$ C+ t2.6 Lambda编程 61
1 w, t2 V9 i6 ?( w+ z3 s- G! c) a/ g+ y- c! Z
2.6.1 集合的创建与遍历 617 o8 V1 t& y c9 _7 j
) N1 X# [% ]$ c/ v0 ^
2.6.2 集合的函数式API 65, g1 R" _ m _. t- T- p0 w
( y/ n# X- b$ X& k2.6.3 Java函数式API的使用 69( T, i% k1 h0 v! i
" Z9 ]6 K7 S K2 ~) W/ u2 v( E) B
2.7 空指针检查 71
8 l% `+ s( i" [- H/ a- r: L' A8 O, U) A5 x
2.7.1 可空类型系统 72
# X* s" T4 k4 B* S: a8 k9 z
# @9 b( I0 H; z- ~2.7.2 判空辅助工具 736 D/ D* `( g0 z' x- a6 A5 r
; O9 y) m0 ?) S$ i2.8 Kotlin中的小魔术 77
F4 F: a9 t7 _+ c
" H% \$ L Y4 C8 o8 n! K: A L2.8.1 字符串内嵌表达式 77
. f. }* g4 y u2 |$ g7 ~, o3 e8 k6 A
2.8.2 函数的参数默认值 78, C! q2 O$ m0 ~* N4 j1 r" z
" \0 ]2 j/ M, m1 N u2 b4 F/ \0 L
2.9 小结与点评 81
: s- _ W. P( y" z8 D9 _- v V5 M" U0 m% ^
第3章 先从看得到的入手,探究* f+ z+ r4 o7 Z# U
; \ M/ |% |: V' F: _Activity 82& R& o+ A, e# p0 _* v4 V6 v
% t4 Q7 U8 N' @) u1 c0 e: `4 `' A; h3.1 Activity是什么 82
; }* D: b- h7 }& S7 J* p6 s4 ^ I! D- E A! l
3.2 Activity的基本用法 82- T# N7 y4 J+ C6 T
2 F$ w. I( f9 I3 ]& L, k3.2.1 手动创建Activity 83
/ @% w, ?3 l9 ~' q( y- V9 n
2 I% l8 Q! M' m: `( {3.2.2 创建和加载布局 855 k2 K# A7 L3 _& z3 Y
' O7 O& u# g( z+ I" e1 u* S1 c3.2.3 在AndroidManifest文件中
! I$ d9 y2 o7 Q$ v+ |$ T" ]: r7 V* J; M) ?) R9 p" S- c
注册 88
( H3 `/ C+ \5 G5 J& b
2 _- e$ k+ g+ v" S) d& ]; ^& g3.2.4 在Activity中使用Toast 90
. g+ k% g- h) l( ~. Z* A7 R. Y% M; d/ y4 E
3.2.5 在Activity中使用Menu 92
* }; {6 U2 A; T+ I( T& ~, Q& x2 a% w e- C4 s, v
3.2.6 销毁一个Activity 96
& ~( J5 m9 ~, x& P2 ~6 j- f
) `; d7 j/ a9 V3.3 使用Intent在Activity之间穿梭 96
# V5 U+ S* k4 f2 k5 s1 q& _7 C4 l$ d% S
3.3.1 使用显式Intent 96
{2 O' ]' V7 s1 Z. o2 V- H6 W/ _0 E/ _
3.3.2 使用隐式Intent 99
! ?5 C. C6 L" N& V! H! f- F. I# y/ T6 e E v' O+ j! Q
3.3.3 更多隐式Intent的用法 101* S2 [& F' Q8 K8 H- w1 ?7 d- @
5 I9 |8 w1 m1 Z9 w# D3.3.4 向下一个Activity传递数据 105
+ } Z% e0 f/ o7 v) h/ ^1 r
, I/ D# C, p# }. }' m. h4 U3.3.5 返回数据给上一个Activity 106
- j4 M/ k3 t& m
, i, p5 V5 a. j( n3.4 Activity的生命周期 108: V* m k5 H4 W
: d3 s8 r, R! P8 W8 R" Y9 I3.4.1 返回栈 108
1 N- t+ K' |* o4 X [# R0 D; Z- J! @( Y M0 A3 s- k
3.4.2 Activity状态 109
* |$ m5 ^4 T6 k( e- {: J' i. y
; u$ J7 W5 I' X8 {" Y" Q3.4.3 Activity的生存期 110
/ p% u$ i& }* n4 @# }( v
. j K( [. r) Y: ^3.4.4 体验Activity的生命周期 111
" N8 v* ~% P' J/ O2 z( T8 r9 X. N1 N7 N( w! M& W: r8 g
3.4.5 Activity被回收了怎么办 117
2 f+ t( p/ \/ {0 H( Y4 D0 p4 B$ P _& W; n9 P! h: u
3.5 Activity的启动模式 118
' b% W) S$ {2 l
( e0 T8 K6 \ c |5 m) r3.5.1 standard 119: ` F% I0 A" t( ?1 x4 T
4 \( z) N0 _4 F3.5.2 singleTop 120% H$ Z+ e/ [; ~
0 K4 U: n3 i$ E8 x( N E3.5.3 singleTask 122
2 R( M- J6 z; C: _" x. x, ]. l- K, y% x8 ^# B Y( |1 D; v
3.5.4 singleInstance 123/ ^0 B, |8 |# f1 C( Y
) I* u* s& ^$ _3.6 Activity的实践 126% Q! Z) _ g, C( s( g0 w8 C" K
& a6 R& K6 V) B# k; k/ L0 [3.6.1 知晓当前是在哪一个Activity 126
3 L n% u% k& h
, i# j# h y1 J; Q) E/ r3.6.2 随时随地退出程序 127
* J+ e6 L. A$ U# T/ p8 e4 x1 m1 h ~. e& A
3.6.3 启动Activity的写法 129
4 |8 }/ ~5 b' s+ e- v3 ^$ A( ]# i0 P3 H6 m! G( h
3.7 Kotlin课堂:标准函数和静态方法 130# v! e T6 w2 E
( D! g, h: P( i& A
3.7.1 标准函数with、run和apply 130& u" X, V- C# C/ m
4 f* y+ ^5 r" ]( O Y- X8 G# ?
3.7.2 定义静态方法 133% n; S7 I4 S8 o
$ u9 K9 l/ J0 d3.8 小结与点评 137
! {9 p. C' j% ?0 L N# h. ?9 W' O) d
7 A6 T; l- J6 N1 I9 I第4章 软件也要拼脸蛋,UI开发的
" T: x9 |. \' ^' @9 a1 G2 U- Y( w
& S# z6 B3 y3 ]) N7 e" o& b点点滴滴 1380 I! y9 e. l) Y6 m) ?$ [ w. v
0 i/ }+ s/ _) f0 F# _4.1 该如何编写程序界面 1386 ~" j) N1 I) z \3 L" ~3 c
, `, A5 ~6 T# R0 S- s
4.2 常用控件的使用方法 139
# q8 v/ ^: d1 e5 j" n' } A, t d) w$ f6 ~3 ]( e9 Y [. t
4.2.1 TextView 139
; ~$ z2 _2 p3 D5 w. P8 |/ Q; f. |2 I1 }$ o
4.2.2 Button 142& f. q9 G( R% F- q
/ [& R# @7 e8 m0 k! j0 _4.2.3 EditText 1448 L! B- c( A* v! y, I% j
/ }4 A; W K' k5 _- l$ g
4.2.4 ImageView 149
$ X% @' a" N, @4 Q2 _; L Q
* F" ^6 D( p& B4.2.5 ProgressBar 1511 g( y& j" d! C# ~: W
( p9 U( d$ D# s5 L0 w! j( @$ ?0 j
4.2.6 AlertDialog 154
5 h9 w2 a7 ~ l* o4 }8 _& s9 K4 {# C0 I% A
4.3 详解3种基本布局 156
8 ]. a8 t' ]6 S& ~+ C2 C7 Y/ @; G4 e) ?- ?" U5 S* y# C/ X$ V: @( h
4.3.1 LinearLayout 156
# ]! i h" e. b c7 p
0 ~0 Q& j! h- P4.3.2 RelativeLayout 163
4 q x7 t# x7 P; j- Y4 V5 b
9 u9 A X) V" Q4.3.3 FrameLayout 166
3 b: a" r3 M& _3 X$ q3 H) }( e8 x E9 z5 K5 s$ O
4.4 系统控件不够用?创建自定义控件 169
! B! Y1 P- l; v
# t) t6 u5 `1 D. f+ u4.4.1 引入布局 169
$ p1 Y$ z9 ` K) X$ J+ o/ N: p! D7 Z- W9 Z! \# R% _( d( X
4.4.2 创建自定义控件 172
4 n: [' `! F9 x0 C6 l: N/ o2 J6 ]; h9 y% V8 y
4.5 常用和难用的控件:ListView 174
& k6 \5 |3 Z" F, c7 f
1 L1 c6 u8 |" h4.5.1 ListView的简单用法 174- }, a, l2 y* V/ m
( L6 Q6 }1 m9 Y% z5 e9 g2 b4.5.2 定制ListView的界面 176
+ D/ [0 [3 X) c9 w) Z2 T4 N2 s- [( G/ e6 [# m0 x1 T
4.5.3 提升ListView的运行效率 179
S; ^$ F* I1 t5 N, _
7 }; R" {* p* ~4.5.4 ListView的点击事件 180
6 D& h; R' w5 |2 |$ Z7 D8 u: o4 E
4.6 更强大的滚动控件:RecyclerView 182& E8 Y% U: P9 V2 e5 D, D6 K0 E
1 A8 Z; l- p o' @5 @# ]4.6.1 RecyclerView的基本用法 183
1 X! l* ~6 V7 F* `3 F. G/ S1 K; t% ^+ J4 Q
4.6.2 实现横向滚动和瀑布流布局 186
2 k" |" e {, A8 ]2 m" x: u; |8 Z# n# y1 \8 I- B* b
4.6.3 RecyclerView的点击事件 191
, D: ?* B9 c8 S$ D5 H% h
9 c: W$ T; ^0 Z" O+ J/ l, @2 g+ R4.7 编写界面的实践 193
) R# Y$ d6 \) {$ |* U2 s k4 m# q* ?# D2 i# i- H
4.7.1 制作9-Patch图片 193: y1 [! A& v) n# N6 M) W% o
" _! M( s9 e# g6 U9 f! J0 }/ P
4.7.2 编写精美的聊天界面 1964 k6 W4 B2 s: K/ r
" T3 w! r, W3 O" `- k, n
4.8 Kotlin课堂:延迟初始化和密封类 201
8 S: I$ j8 s. J* c' K/ |" s+ k9 B$ m$ o9 L+ c
4.8.1 对变量延迟初始化 201
. P: q( b) {7 e( O4 @0 T! ~3 F6 r: ]7 R* @+ I/ B
4.8.2 使用密封类优化代码 2046 l' M0 Y# V- l9 n
: J t) i$ S; `9 L5 w: F% K4 J
4.9 小结与点评 206& u2 f3 l" }7 q
, _: i; o# ]$ x5 w6 ^第5章 手机平板要兼顾,探究
, P u; l* h5 R! p: @' J# U
8 m1 q) [2 H& {0 L c: W( Z) BFragment 207/ V' @" K, F& K5 r* j0 ~
* ^3 e, T5 |! R( l
5.1 Fragment是什么 207
& E& f' @% s( o, Z' |0 k, s7 ]/ v. [
5.2 Fragment的使用方式 209% _5 ^. W. v. Z% N* L) M
W8 K# L/ H" A6 B) L- g
5.2.1 Fragment的简单用法 2103 m8 c: W* E9 Y, P
C6 Y5 ^( K' i# T5.2.2 动态添加Fragment 212
; C$ ? t! p |6 Q# t7 K. A) Y
; q5 Y+ B1 c ]) O: D8 A" Q( u5.2.3 在Fragment中实现返回栈 215
% z* ~! r$ Y! g% c3 S4 a I3 a% B0 m' q8 q( c9 `' }3 z
5.2.4 Fragment和Activity之间的
1 A. Z e6 `8 P/ ]
' R; Z, q# E# c# h交互 216
7 |3 Q; g! ^) f* J
% \9 X) D# |8 u: b4 y5.3 Fragment的生命周期 217
! A2 c" d5 ]1 |6 t
( c \4 K8 {: h: |2 |0 |5.3.1 Fragment的状态和回调 217
5 a2 f+ R0 N: }8 k* x' R0 B$ R: @
: Z) b1 y1 G* ^1 N7 E$ v6 v. N* r5.3.2 体验Fragment的生命周期 2191 ]. x3 A' X: k5 N5 S
* j0 v3 j; [, J% {$ `
5.4 动态加载布局的技巧 221- z) w4 m! S; Y7 N5 _" t: H
4 F) m4 q! p" v4 \6 S" a4 s* ~5.4.1 使用限定符 221# B& `4 x% o/ h2 q
* ~/ |4 m7 e0 d3 p
5.4.2 使用小宽度限定符 224
, B7 ^, \) ]( o- E3 S5 b: K* T: E1 ?; H( Z
5.5 Fragment的实践:一个简易6 w! R2 K/ b1 }
3 t; u: s" F* w' T6 J& V
版的新闻应用 2256 g9 E/ f2 k/ p% h
% L$ c \' ]/ ~# H! z/ K" |5 w
5.6 Kotlin课堂:扩展函数和运算符% l5 Z/ T, Y; C$ M
( u, m+ s$ O) A% v+ g% ^6 q重载 2341 b7 T5 `0 t5 g4 G8 V, j& T
* e. x6 l4 Y) i8 T/ y7 K8 m# I( [5.6.1 大有用途的扩展函数 234; A! G1 p9 p9 M+ ?4 K+ @: |) N
; E) i/ o( H8 z# T4 y& F9 P+ |5.6.2 有趣的运算符重载 236& \6 ]* T: z" Z9 c
0 X3 I: V# w) ]/ H' y1 q, A1 n5.7 小结与点评 240
: {; X, I1 W- j) j }9 P& O+ ] N& {9 J3 O
第6章 全局大喇叭,详解广播机制 242
# l# l; Y8 K1 |
- T- w/ T3 x0 {* y, }6.1 广播机制简介 242* T" Y7 N9 |4 r+ Q0 H5 j6 g
# Q4 o, a# W5 a/ w' b' I+ }
6.2 接收系统广播 243' k% z& h( }+ x/ i+ i
" G, i$ Z. H0 _9 v
6.2.1 动态注册监听时间变化 243% @% ^" C0 p6 A: I
' M# T; c8 Y4 v$ H: k# b' Q# x6.2.2 静态注册实现开机启动 245' |& o1 n% t2 Z, R* T k7 Q/ @9 L
0 p+ s2 h0 `. q/ z6.3 发送自定义广播 249
% C" v3 s3 m& g8 k
/ @- J8 D# Y& [3 _! p- w# L# j# z6.3.1 发送标准广播 249$ ^ n4 B# U- H y$ j( X+ Y F
~+ g# y; H3 S% C! }1 z6.3.2 发送有序广播 2528 o5 ~& M8 N4 ^' Y
+ y: m: j+ _1 I4 Q6.4 广播的实践:实现强制下线功能 255
1 Z4 N) g% }: F; ^& H+ G6 F5 y6 B( Q' v2 {) E! ~
6.5 Kotlin课堂:高阶函数详解 261
; T1 s1 [; l% T* Z- z# |5 ^
5 Z. d- S5 I* G+ I7 K$ T5 x6.5.1 定义高阶函数 261
6 j! M: k, t) Z6 J5 L0 y2 z# ] y# }* B4 t
6.5.2 内联函数的作用 265) o g5 \" Z. e2 M; e5 J
8 r; s& D# y- e6 G$ {4 Q g6.5.3 noinline与crossinline 268( Y3 h$ `+ y; o0 T( N) k
3 y$ }. b' F& l' \+ ^6.6 Git时间:初识版本控制工具 2715 X5 [3 {- \+ B: l
% P" u! H6 u7 b' y, \, Z. M: T
6.6.1 安装Git 271
4 [7 r. P; f8 U. w2 f9 F
9 P+ ?4 M' g+ W" [1 T+ ~6.6.2 创建代码仓库 272
6 H- j, C& P2 c6 i" }4 p* O% [% R5 }. r# }- ~
6.6.3 提交本地代码 274
% o! p Z2 g4 ~7 j7 X# F/ t6 ^
9 [2 @5 P7 ~+ v; H- L: q$ m6.7 小结与点评 274% ]# W) d' u3 _1 r
9 z. Q9 N: _+ y( H! O第7章 数据存储全方案,详解
/ Y! p. M& Q$ N* b7 f- G; V7 f# N- R3 L/ h* ]. d2 `9 I$ \1 m
持久化技术 275
' n' E$ b$ m. J8 F
9 N: f7 J0 e3 H+ ^0 A7.1 持久化技术简介 275) P5 d- G+ y( s+ l
5 T/ y2 M4 D3 |/ L( h
7.2 文件存储 276
: i/ r0 A7 G+ J5 s' Q% L
) a Z, }' N! ?4 `# S. c% B7.2.1 将数据存储到文件中 276; U* A% u" M* h' E1 X5 T% H
4 M M# L" i: r( R+ C' Q9 g7.2.2 从文件中读取数据 279
; P4 n! u/ s$ h7 y
d7 O3 r3 `0 o4 M) J3 C6 A7.3 SharedPreferences存储 281
% s1 g9 |$ d' J2 ]7 Z" M, l$ n1 u' h7 u. |
7.3.1 将数据存储到SharedPre-! X: I. k' _7 H
" R: O8 K ?0 ~) W
ferences中 282
0 W0 x( o2 \+ ]
$ ]0 u( C* B K& ?! m) e) q7.3.2 从SharedPreferences中读取: ?* ^" e1 m% ?( ]' |. E3 Y
. a4 |' W- s H& B数据 284
. Y9 Y7 I8 }+ S* F& k+ Z3 }
# Z1 D$ w& }* o. A# ?8 B7 b7.3.3 实现记住密码功能 285
; ]( {6 J4 `$ `/ Y# H& R1 i" m: N" t2 [% ]( R
7.4 SQLite数据库存储 288
5 p) n1 Q: @; ~1 D3 R1 H8 Q. s% ~( S$ c4 m7 A* S
7.4.1 创建数据库 289
# h. h' u* f- y! X B- V
- h+ Y0 D. ]" d7.4.2 升级数据库 295& v! w+ A% L' s
. r5 S+ p9 C) ?1 e7.4.3 添加数据 297
) ^. j: Y# V: b! y) w5 |0 P0 j" J1 X0 g0 S
7.4.4 更新数据 3007 s* {6 Y: i$ `6 Y# X9 P7 I# E
2 f9 Y9 g4 b( I6 D
7.4.5 删除数据 302. Z; U, ?$ b+ O) h$ I* f2 Q4 D7 {4 @% f
; b, o7 _% Y2 H2 n/ X9 |7.4.6 查询数据 304
9 z; i3 x- x) g0 C/ O8 l, x7 m$ t5 ^+ }' u, W' C; T$ d' k" B
7.4.7 使用SQL操作数据库 307" G/ b( a" R& P. N4 @$ o
( h" Q ^5 o& {5 _7 ]5 Q2 j- N
7.5 SQLite数据库的实践 307# F2 l+ H& j# [1 x' D. b, a( T
; [' e3 w) U" A: s$ a% [7.5.1 使用事务 308/ o( h8 p2 P1 u' W: u+ r
. b2 F; s5 j% W" \
7.5.2 升级数据库的写法 309
! `4 q9 L4 g# G( h
. W0 W; n4 X) g- V$ m* F7.6 Kotlin课堂:高阶函数的应用 312 I# j- E9 f `, k
3 X( B2 v! P# K+ S1 \# E# d) r4 H7.6.1 简化SharedPreferences的用法 312
0 N. v% n* U% P/ n& n% {9 x; f# i6 q
7.6.2 简化ContentValues的用法 3141 n2 G7 J! c, O4 }
+ b/ O5 Q0 x. Z3 r( ~7.7 小结与点评 317 W' u+ V+ O9 ?% j" R# F
- O) q8 t- @: n k" P第8章 跨程序共享数据,探究ContentProvider 318' A! @& P7 X+ n& E7 H8 B; o# N9 W
/ y) H- Z6 Q0 L& b! b6 j8.1 ContentProvider简介 318# v* h$ F( V( B! g$ ]
6 T; i) _2 N" q) g- R* [
8.2 运行时权限 319
1 F( B$ l* |# ?$ T8 H% n5 m; E. J7 [9 ~; L) R
8.2.1 Android权限机制详解 319
9 d$ s: m2 X& ^+ X: c. b" L( z; D9 s5 O3 W, B
8.2.2 在程序运行时申请权限 322- K7 \. a$ Y1 ?
9 y, f2 v' I$ p" y9 G
8.3 访问其他程序中的数据 326) R' }$ [( B8 M3 ?& t0 L
' \- G4 G* D. ]; p- I9 o$ y% [
8.3.1 ContentResolver的基本用法 326
6 a& e& V i0 V1 H" e, j# A6 e/ x' A" o# G1 |, `0 _
8.3.2 读取系统联系人 329& F, f( \; s5 _& A; E$ m
! _+ G8 v- [. W3 ]
8.4 创建自己的ContentProvider 332
* r' w1 u0 G% w. k5 U9 y; I8 q5 W& f! Z
8.4.1 创建ContentProvider的步骤 332) W% K. I) D/ H5 x/ E2 |. J
6 Z# u* D* o! z2 b
8.4.2 实现跨程序数据共享 336- u' E6 ]3 M6 a. H. [& Y
7 R2 H- {1 p- i" `8 ?' W. f
8.5 Kotlin课堂:泛型和委托 345* t& t3 W) o# o' X
( O& K* r4 z; F0 @: B, e' {
8.5.1 泛型的基本用法 345
# O) `* t2 D- |! \4 E
u$ W& l: Y$ t7 D8.5.2 类委托和委托属性 3470 k" _, |# a4 V+ N1 Q
, k5 a0 e5 q. d/ K! R c- p8.5.3 实现一个自己的lazy函数 350
$ d+ y6 @& Y! m' \* u3 p
1 z0 P: l% }# s' f- P) x) S2 c8.6 小结与点评 352
! r" p# g6 }( d/ J- z; @9 Q. C$ c$ ^5 W# J
第9章 丰富你的程序,运用手机
7 l7 {0 ~9 y/ J" L ]7 c
: r4 U: W6 U7 U1 T5 H. k- V( u多媒体 353
e2 w9 Z9 o: [% A# M6 @& A5 k$ J2 r6 M( S& a
9.1 将程序运行到手机上 353
4 W$ B5 K( z @. A5 q2 e8 l3 P3 q6 b# N$ l6 d, z5 `
9.2 使用通知 355
7 Z" B% l4 ?$ B, X( P8 B6 h. z/ p9 X- ?8 F: A! n1 ?
9.2.1 创建通知渠道 355
$ p( F9 k) E4 \$ ?9 }' |% O @4 B
& u0 |. e6 w- D6 W9.2.2 通知的基本用法 357+ I; |5 T; r9 S0 z# |
1 e) V# Z9 f6 v; k/ g% A. X9 @' H9.2.3 通知的进阶技巧 362
9 V. m' j, t: j e& [
% q/ C2 Y( [: v" y2 B9.3 调用摄像头和相册 367
. V; G8 I$ N1 ^; Q% S+ {7 _2 j# U9 s
9.3.1 调用摄像头拍照 367& z# I* [: z ~" M
4 v1 B; v* O0 d* ?. ~9 e
9.3.2 从相册中选择图片 371
4 c& {4 l t7 r6 V1 P- \( a! a6 D7 t' q6 `
9.4 播放多媒体文件 374
7 R% u! v2 E9 [; U, Z I- P1 y" b7 i- @0 f" ~
9.4.1 播放音频 374+ D7 H/ s3 x# A8 k) N
1 f% P2 m7 l: }# L) v) \' s
9.4.2 播放视频 377# B2 P0 {* A$ v4 X' b, x
" m! k# F1 x! T/ K5 c8 w9.5 Kotlin课堂:使用infix函数构建" c' S- J+ c+ |; [3 \6 \3 t/ p& T
8 {& [0 t- T6 M% X$ e更可读的语法 381
( N& @, C) ~' r, p; l4 E" u$ f+ X! w* n- q
9.6 Git时间:版本控制工具进阶 3830 Y5 b4 t/ J. k
' w+ v* c5 g+ [; t8 a( W8 p
9.6.1 忽略文件 384
5 r/ S- Q/ Z" ~$ o e: J" A
: D8 W! Z% T# Z8 l) g1 K9.6.2 查看修改内容 385
; ?! l$ ^# k& ^' I9 B" W' r8 x; p% X( M6 {% ^& e0 i9 {6 s$ K
9.6.3 撤销未提交的修改 3874 J) L; f3 M5 h% Q) j4 k
6 A# ?# S+ R7 I: |- j- h9.6.4 查看提交记录 388
2 ^: s5 O* L4 r N5 @' Y6 G$ o5 ^) `4 j) |: M4 t
9.7 小结与点评 389
# z$ }/ C3 p. G0 m; V0 {8 e5 s8 j( e% _$ S1 h( ?
第 10章 后台默默的劳动者,探究 e6 \! M& I1 G9 v8 }2 C% H
' P- l* S; [, ]+ T3 ^; ~6 e) [
Service 390
2 B& @, J- g" R }1 l& G
6 M) y9 i m' q0 y. H5 V10.1 Service是什么 390
0 X6 D0 X) a" I
/ G: A+ U! G# C3 k5 [5 Z9 C- r' c10.2 Android多线程编程 3916 x! F2 X {- _1 a0 z
$ w9 G1 y4 n8 Q' I3 P10.2.1 线程的基本用法 391
: [ D T- s9 _5 x, `! w5 ?+ r2 {. C, O
10.2.2 在子线程中更新UI 392
$ g1 F1 \' w6 d. H9 j: i4 Z# k# E* \
10.2.3 解析异步消息处理机制 395
2 ^. D1 Q% G1 f; j% [" R* F5 l& h: F" o5 m
10.2.4 使用AsyncTask 396
+ A& u" ?& H5 J3 R& a" }7 {$ x4 i( |8 M( C/ o- w
10.3 Service的基本用法 399
* V# c& P9 X6 u% }0 b
" r+ Z! O4 `( n- Y# L0 b10.3.1 定义一个Service 399& Z! u0 }5 x: ^* s
/ S" E- ?7 G) v* j10.3.2 启动和停止Service 401
& G9 ~; J, z, R- S
' A* V' p8 ^: K0 ~1 }10.3.3 Activity和Service进行
; w" E- j- H# h' |/ h3 }0 u2 D; s8 E7 D# [7 j e+ {6 b/ k% L
通信 404" K0 M+ J, q- p$ Q X' z
) H! N1 P* J4 F; i% y" W7 |5 Y
10.4 Service的生命周期 408
3 B' a' q: C. \- {, E% |, z( L/ Q X2 K% O, H' u6 r* i
10.5 Service的更多技巧 408
& G( x0 ~1 l* w- P2 u b, U+ q" A4 G- A# F" _ f# P. r
10.5.1 使用前台Service 4099 J, h i3 L g, w
; R) K- M" G$ @" y% K% M' _10.5.2 使用IntentService 411
9 N+ |+ g9 J, I5 ?. `5 U4 s! D; e% \4 l6 }' d1 ^
10.6 Kotlin课堂:泛型的高级特性 415
9 O5 `5 U" c! ]+ a2 N) O* f) L2 r* N: L
10.6.1 对泛型进行实化 415
( L8 l% D2 V/ Y' e |0 h- E# i
: y+ n& @- e+ O9 I Q) I$ v10.6.2 泛型实化的应用 417
( d- l' s2 g: n0 f, S" J) S5 a8 m& Q) L3 E1 b# t
10.6.3 泛型的协变 418- r$ ?8 I, Y4 Q0 l4 s# d* E
: [( |! `8 W2 h8 A' Y
10.6.3 泛型的逆变 422
; F7 n+ ?, m( V. u7 g
$ C$ h4 }$ k( \4 j9 p# ^10.7 小结与点评 4258 f, m9 |5 v3 |: e
3 m, ^1 p+ J4 K, B: d" q# K第 11章 看看精彩的世界,使用网络
- t& W# Q# I' ?: B* A/ ~' P H Z Q4 V) g# M8 R
技术 427
! c9 ?- F0 U1 p/ L. N
& t; ?( }5 A& D11.1 WebView的用法 427& A* o1 i6 J4 ]- U
+ u+ n& l- N3 I1 F& X11.2 使用HTTP访问网络 429
" H G: i% ?8 r8 {3 h
L0 Z: E2 U$ `3 E8 M; d! b+ U11.2.1 使用HttpURLConnection 430* y$ W o. k- }9 y z& o$ _4 |1 u6 M/ g
! c3 g2 G; r# P$ a11.2.2 使用OkHttp 433
6 A9 ?' n6 w( D2 X3 {9 D; I. m! ^3 Q: Q( s E J g6 k. t, T
11.3 解析XML格式数据 4368 ]& G5 Z% `; @! |0 z! K6 r
; G( o+ v# x0 o |( q4 ^( Y
11.3.1 Pull解析方式 438. n5 c5 r P% K1 H5 U i: ~5 ?7 |
2 k3 Z7 F* Y6 F$ R U0 s8 S% p" V! u11.3.2 SAX解析方式 441* v6 X) x( {9 d9 a
; I d# X, q" ~3 e0 w, V& E. o11.4 解析JSON格式数据 444
1 F1 h& P6 c+ S" l8 i t6 [3 `1 Z( J; `' r1 N! x2 s
11.4.1 使用JSONObject 445
' J( n( ~; h' S, Y7 M: l8 h( T0 p" j8 O2 ^# ?, t( D% `
11.4.2 使用GSON 446$ D, C) E% q8 \5 Y* R+ S
; o. y2 k+ k$ `11.5 网络请求回调的实现方式 448
, e" {9 m& q4 l+ ]
5 Z# K- o: c, k. T4 M11.6 好用的网络库:Retrofit 451
) y/ m9 p1 K, r6 @0 O; N9 H% J
/ X3 B$ U+ A' C5 A11.6.1 Retrofit的基本用法 452
) C% \6 ?# {( U: ~$ z2 l Q
8 T% l! X2 `$ L3 S5 H; ~& L% W11.6.2 处理复杂的接口地址类型 456$ W( m9 H6 B8 H( i3 @1 e
6 u* M7 Z4 Q% z* }( w11.6.3 Retrofit构建器的写法 459
- a4 z2 W/ W* j# T2 W% W
/ C9 W1 P2 r# R( x" b& g: j, ~8 N11.7 Kotlin课堂:使用协程编写高效的
9 ]7 p/ c" c% L1 |
; m0 E. O# c! S7 c+ W' E并发程序 461
7 e! n5 A. J* m" O6 F/ ^) x3 s+ q
5 b5 ^( h' R. L& W11.7.1 协程的基本用法 461
1 \' ]! g, E, H9 Q& f9 Q
H( l6 ^$ }. X* f9 d11.7.2 更多的作用域构建器 467! V/ o& d( p, R- E
3 S; y. l8 Q0 P" f7 r2 P* ` I
11.7.3 使用协程简化回调的写法 471% u' c& m! c1 i0 _' e0 q
8 O* [1 E2 k4 k7 h
11.8 小结与点评 474
2 m' j" M4 F& _# M0 Q9 \+ Q& ]8 B: m8 ?" v+ B: H+ d
第 12章 的UI体验,Material
/ j3 G9 E7 B( ]7 z' [- f2 Y+ E% Y+ P! _* v: Q+ G
Design实战 4754 m1 A4 \: `: l8 F# r6 O' Y4 B
- H" [1 c- m8 ?1 B' b, w' ~6 x0 r12.1 什么是Material Design 475
. ^8 {5 j7 V C" x9 y: y
1 y1 N5 H+ p1 ?& Q12.2 Toolbar 476
! \; i8 ?5 s& D2 \) K! {8 @% Y x4 B$ k4 \, U% N
12.3 滑动菜单 483
; q4 P. C1 _& |! x3 u9 K# |" Z& W% {" I: T
12.3.1 DrawerLayout 483
$ x, `! c7 t4 B( f
5 P0 S9 c9 \+ }* e12.3.2 NavigationView 486
9 Z! w) u. y+ N! g# ]* |
1 E! d) G! L$ W+ e; \12.4 悬浮按钮和可交互提示 491( p6 u$ u! Z P. Y) i3 L7 J
+ T! J+ x# Y1 W" i f) l H; G( n
12.4.1 FloatingActionButton 491
8 T+ H2 L# a/ r \" x" v8 W, J
: F- v8 F7 f4 Z12.4.2 Snackbar 494
9 v K8 e6 y: g' Z0 O
! K" e# ]( w- k% _) f12.4.3 CoordinatorLayout 496
, c- [: o7 z7 e: E* N1 |# S: x; F- G! H! a+ \8 b8 U
12.5 卡片式布局 498
: X; d/ F( z: s1 M
% f3 e( I$ B9 M) A/ s- j R12.5.1 MaterialCardView 498
# c( K6 z+ Y% S% G
8 F- ^7 m0 y2 U9 `9 A. f9 Q; n12.5.2 AppBarLayout 504
$ z' k+ r; L7 b2 x
0 ]( q$ J& s) M6 k5 _# Y3 {8 _% s! @12.6 下拉刷新 507
, Y/ H$ ?3 V" J8 K; D5 E2 a8 i/ ^1 \! H" G! U# k! x' ^7 A9 r
12.7 可折叠式标题栏 510
5 ?# |. C1 P4 Y$ v; A
$ d" e6 @6 ^$ O( l i12.7.1 CollapsingToolbarLayout 510, V7 Q a" l+ C. c( P3 D
O S5 u+ O2 p3 j% h4 I! ]
12.7.2 充分利用系统状态栏空间 519
' j# i3 R6 U/ S- [4 t' h7 W1 Z D
2 y6 ?0 j2 F# Z4 h12.8 Kotlin课堂:编写好用的工具方法 522( l% K2 R" y" _, v% m
8 F, i% X0 K5 Y' }: q
12.8.1 求N个数的小值 522
' R# I+ f0 ]$ g! P2 c) S# ~4 T8 b
12.8.2 简化Toast的用法 524
5 N l5 z9 o3 O0 s/ [6 C2 R4 m2 P) e4 Y1 \
12.8.3 简化Snackbar的用法 5269 g/ T! H' c$ I! Y2 P: v C6 F' D
9 F$ S' `9 N1 {0 o1 z) X4 w, H: t3 ~12.9 Git时间:版本控制工具的高级5 i3 ~1 q" f: K3 c: s
0 o% ?8 n" u7 l1 T( k1 Z, H用法 528
: N9 j4 `) P& B! k+ r e8 g1 o5 Y4 V9 _
12.9.1 分支的用法 5289 ]% q' U( X0 t& N
! r- {# v) N# C0 j
12.9.2 与远程版本库协作 530
" n5 m# q0 U, T/ \5 d, r
! t# ~6 x: O0 j12.10 小结与点评 532$ f, @4 v" n5 s; m
1 G; M# `, `( V* Z% y第 13章 高级程序开发组件,探究+ W: o% B9 K/ J1 h& b
8 J4 F9 L6 x% B9 [% ~1 T
Jetpack 533" J2 P- c$ c6 _. U" n& S" `
4 h4 f) U" K2 j. N13.1 Jetpack简介 533) b( t, Z" v0 I
7 T9 {+ v/ I# I6 Q6 S13.2 ViewModel 534$ |* ?" Z, ]: l$ B: H" X
/ M, q+ }3 o: P
13.2.1 ViewModel的基本用法 536
4 B% g) a4 W6 T' d# N* {1 i1 t/ e* j0 l! a. Q# E0 ~& c
13.2.2 向ViewModel传递参数 539
$ A. |( m+ o5 X/ z. o& ~
" u; |( P$ c+ Y( u# v" z. M* m3 R13.3 Lifecycles 541
* @* P W% f$ k' B; b2 Y5 U; k$ p8 s$ v1 }& N! A
13.4 LiveData 545
8 U9 P1 i2 K5 m8 C, a/ b2 H7 [& ~% Z* r1 W: W1 K, D
13.4.1 LiveData的基本用法 545
% t5 R1 Z& O8 {& I5 V& J H# V. N
5 r/ y: m9 w }! @, q13.4.2 map和switchMap 549) d3 H" N3 j; j0 ^: F* S/ \" b, g
& c# u- R P9 g" O9 N
13.5 Room 5546 @9 B2 B; _- T+ ?' u
' p7 L5 ?, W' t4 F) [9 K- I i
13.5.1 使用Room进行増删改查 555, X8 j8 w& {: @
- S9 a0 J1 P! h: P' r
13.5.2 Room的数据库升级 5629 w3 S2 y7 H- H) X2 U) W( o5 \% @
* j+ ^8 L Y4 h! |5 g: E$ C
13.6 WorkManager 565& _1 v% Z3 ^5 d5 @5 K; {' \
5 D( l. O. Z% J13.6.1 WorkManager的基本用法 566& c. s* {. a6 W) q3 I5 u# z( ]
* v- }7 f8 i$ M2 _+ V. i+ y
13.6.2 使用WorkManager处理, J! P" n8 t! d& H2 t
! ~2 {0 Y) j0 t( Z! o
复杂的任务 568( D5 O2 ?5 ?6 K7 V! b; b! i
9 Q3 j* x; q, ^8 `" u. X/ I, [
13.7 Kotlin课堂:使用DSL构建专有的
5 _( r8 B3 e5 T# n& A, E$ h9 b. W" t7 _! k
语法结构 571
+ b8 l9 e; H3 q' m4 u+ q3 \$ y g+ b& v- B% Q
13.8 小结与点评 577$ {- J8 ]. L( S! @
' X5 x9 t) k, f) L2 y+ ^第 14章 继续进阶,你还应该掌握的
/ D- R; h7 [: `& Y
0 o; l. [7 W' \" y% w9 z6 d高级技巧 579
9 h |$ c9 c0 |/ t7 b& T5 x' K! }
14.1 全局获取Context的技巧 579# ]. n- ]0 w( w
9 e& V; |1 N+ M- l. d+ T# R& q
14.2 使用Intent传递对象 582
( V) ^) G# q" O
2 r& W' @: [' C1 h14.2.1 Serializable方式 582
0 o7 O0 J* I+ [5 l/ `3 W5 J9 T+ T H# J! P/ l9 `
14.2.2 Parcelable方式 583+ C4 g8 y! Z/ O- t0 {, `! V
' f1 n, b; W @7 B
14.3 定制自己的日志工具 584" r6 T: R9 f/ L
" O6 A. f8 g8 e8 X2 G4 q14.4 调试Android程序 586
" s8 f% O' m3 H* }& N R* a" l; X7 \- k9 N1 C7 c& i- C6 b( n# `' T
14.5 深色主题 589: g3 V1 @0 L* C% W# |6 O
. {& R! \$ b8 N9 f
14.6 Kotlin课堂:Java与Kotlin代码
3 f: @# N5 C3 \1 a! g6 f3 T I
5 O! q6 h6 S/ N, [ [% j之间的转换 596
4 u/ Q/ Q6 u/ I6 r% a9 v
0 Z3 q4 `$ {/ l- P- E14.7 总结 600! B/ Z1 a) G _0 y# _
+ C! Y. J- v z! ~. t: M: E
第 15章 进入实战,开发一个天气' _; [1 b, M) V' m; ^* T. q4 d
9 S9 ?* ?$ {3 W3 f* ~预报App 601
1 z/ N# D. h, Q
2 C, v/ w4 [# ^/ U y, ?15.1 功能需求及技术可行性分析 601- }+ q3 L# V" \9 e) m" }+ t
6 V$ H. ?6 `5 K) N- B8 g R& s) q15.2 Git时间:将代码托管到GitHub上 605
- N) X5 q# a( o c. n: v$ Z+ S: V2 t
15.3 搭建MVVM项目架构 612
6 s) O* g; T! X5 G G- d9 a$ W: _+ `6 A2 g/ W
15.4 搜索全球城市数据 615
+ ^+ z% O4 g& I/ k' D% s% B: g& T7 y' C' r* a3 ?
15.4.1 实现逻辑层代码 615
" @2 I7 a. w5 u' Z7 V
" Q) w2 f2 D9 n& u6 Q15.4.2 实现UI层代码 620
8 L6 }! O) a# E) S L$ |0 J
7 G( D% ]9 @9 N2 A% C15.5 显示天气信息 626# V2 ~! g6 }' G1 f' H. B
, {/ Y7 ?0 O1 J1 y2 N2 y
15.5.1 实现逻辑层代码 626
. t: [3 `% ]1 _9 ?. r6 z' |! s1 A8 n' @3 n+ s$ Q0 U5 f. G/ F
15.5.2 实现UI层代码 631
. j* O4 T7 a3 R' Y! A' u; ?: V! a* ^
15.5.3 记录选中的城市 645
9 x3 V8 X8 o- D
+ L X4 \. y6 `! F4 R# V15.6 手动刷新天气和切换城市 6472 [- K/ e: j; [7 q! l
! ]' K9 k' W4 x4 O
15.6.1 手动刷新天气 648/ t3 W4 z. V0 E" Q$ Z
5 }. D: c9 ?7 b# R ?5 s) A0 ]" c
15.6.2 切换城市 6502 b1 m& y7 |. H" S, G# Q5 M7 @ f
1 s( {) w& C0 A
15.7 制作App的图标 654# c1 I. {% u/ ^$ I- o( d' \% V" Y
' ], l) m' d1 u; X* }
15.8 生成正式签名的APK文件 659' @- {) r5 j9 Y; C9 I5 U) G4 E
/ ? G2 `2 U, F& N0 z2 h3 W& P
15.8.1 使用Android Studio生成 660
% C2 g% t2 t3 d
; e7 |. B4 K: a5 W6 r4 |: J5 H* M15.8.2 使用Gradle生成 663; k4 \* A5 a: D, l2 V
3 G# _8 J# n( u
15.9 你还可以做的事情 666/ e: P* {$ V( {
0 Y( G( y7 k& ?6 b, e2 e
第 16章 编写并发布一个开源库,PermissionX 6691 l4 Q& O- q* X# z7 {, @" J! h
8 F! s4 U: g- B
16.1 开发前的准备工作 669 java8.com
* Q# O n* ^) X9 n' W2 x8 m1 R# T" D, @/ S4 o
16.2 实现PermissionX开源库 673; u( T/ {5 k1 |& i0 F6 Y
% }6 \5 ^" q" ]16.3 对开源库进行测试 678
9 |& v- Z3 c9 c! o; N
, G7 \( H6 g1 m/ h; j3 l1 V$ f8 u" f16.4 将开源库发布到jcenter仓库 681
) R; C% j1 n1 B" b& X0 |% k' u$ |' S# W
16.5 体验我们的成果 688' M, d1 w: Z6 g# f4 r
/ ^3 ?) L" l+ @5 T) x6 A' X# ~2 o16.6 结束语 691
' ^, R' [7 p4 }3 n# d# d9 y