-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathatom.xml
More file actions
520 lines (317 loc) · 472 KB
/
atom.xml
File metadata and controls
520 lines (317 loc) · 472 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Jockio's Blog</title>
<link href="/atom.xml" rel="self"/>
<link href="http://jockio.github.io/"/>
<updated>2018-03-25T10:27:26.968Z</updated>
<id>http://jockio.github.io/</id>
<author>
<name>Jockio</name>
</author>
<generator uri="http://hexo.io/">Hexo</generator>
<entry>
<title>IntelliJ IDEA Mac快捷键</title>
<link href="http://jockio.github.io/2018/03/25/idea-keymap-on-mac/"/>
<id>http://jockio.github.io/2018/03/25/idea-keymap-on-mac/</id>
<published>2018-03-25T09:56:25.000Z</published>
<updated>2018-03-25T10:27:26.968Z</updated>
<content type="html"><![CDATA[<h3 id="智能提示"><a href="#智能提示" class="headerlink" title="智能提示"></a>智能提示</h3><blockquote><p>⌘ -> command<br>⇧ -> shift<br>⌥ -> option<br>⬆ -> 上箭头<br>⬇ -> 下箭头<br>⌃ -> Control</p></blockquote><a id="more"></a><h3 id="编辑"><a href="#编辑" class="headerlink" title="编辑"></a>编辑</h3><table><thead><tr><th>快捷键</th><th>说明</th></tr></thead><tbody><tr><td>⌘ + F</td><td>在当前窗口查找</td></tr><tr><td>⌘ + ⇧ + F</td><td>在全工程查找</td></tr><tr><td>⌘ + ⇧ + ⌥ + N</td><td>查找类中的方法或变量</td></tr><tr><td>F3 / ⇧ + F3</td><td>移动到搜索结果的下/上一匹配处</td></tr><tr><td>⌘ + R</td><td>在当前窗口替换</td></tr><tr><td>⌘ + ⇧ + R</td><td>在全工程替换</td></tr><tr><td>⌘ + ⇧ + V</td><td>可以将最近使用的剪贴板内容选择插入到文本</td></tr><tr><td>⌥ + ⇧ + Up/Down</td><td>向上/下移一行</td></tr><tr><td>⌘ + ⇧ + Up/Down</td><td>向上/下移动语句</td></tr><tr><td>⌘ + /</td><td>注释 - //</td></tr><tr><td>⌘ + ⇧ + /</td><td>注释 - /**/</td></tr><tr><td>⇧ + Enter</td><td>向下插入新行</td></tr><tr><td>⌘ + Enter</td><td>上插一行</td></tr><tr><td>⌘ + ⇧ + F7</td><td>高亮显示所有该文本,按 Esc 高亮消失</td></tr><tr><td>⌘ + W</td><td>可以选择单词继而语句继而行继而函数</td></tr><tr><td>⌘ + ⇧ + W</td><td>取消选择光标所在词</td></tr><tr><td>⌥ + Left/Right</td><td>移动光标到前/后单词</td></tr><tr><td>⌥ + Backspace</td><td>按单词删除</td></tr><tr><td>⌘ + [/]</td><td>移动到前/后代码块</td></tr><tr><td>⌘ + ⇧ + Left/Right/[/]</td><td>选中跳跃范围内的代码</td></tr><tr><td>⌘ + Y/X</td><td>删除行</td></tr><tr><td>⌘ + D</td><td>复制行</td></tr><tr><td>⌘ + ⇧ + U</td><td>大小写转化</td></tr><tr><td>⌘ + ⌥ + V</td><td>可以引入变量。例如:new String(); 自动导入变量定义</td></tr><tr><td>⌘ + ⌥ + T</td><td>可以把代码包在一个块内,例如:try/catch</td></tr><tr><td>⌘ + ⌥ + L</td><td>格式化代码</td></tr><tr><td>⌘ + ⌥ + I</td><td>将选中的代码进行自动缩进编排,这个功能在编辑 JSP 文件时也可以工作</td></tr><tr><td>⌘ + ⌥ + O</td><td>优化导入的类和包</td></tr><tr><td>⌘ + +/-</td><td>当前方法展开、折叠</td></tr><tr><td>⌘ + ⇧ + +/-</td><td>全部展开、折叠</td></tr></tbody></table><h3 id="重构"><a href="#重构" class="headerlink" title="重构"></a>重构</h3><table><thead><tr><th>快捷键</th><th>说明</th></tr></thead><tbody><tr><td>⌘ + ⇧ + ⌥ + T</td><td>重构功能大汇总快捷键</td></tr><tr><td>⇧ + F6</td><td>重命名</td></tr><tr><td>⌘ + ⌥ + V</td><td>提取变量</td></tr><tr><td>⌘ + O</td><td>重写父类方法</td></tr></tbody></table><h3 id="代码生成"><a href="#代码生成" class="headerlink" title="代码生成"></a>代码生成</h3><table><thead><tr><th>快捷键</th><th>说明</th></tr></thead><tbody><tr><td>fori</td><td>生成循环</td></tr><tr><td>sout</td><td>System.out.println();</td></tr><tr><td>⌘ + J</td><td>可以查看所有代码模板</td></tr><tr><td>⌘ + ⌥ + J</td><td>用动态模板环绕</td></tr><tr><td>⌘ + ⇧ + Enter</td><td>自动补全末尾的字符(括号,分号),例如敲完if/for时也可以自动补上{}花括号。</td></tr><tr><td>⌥ + Enter</td><td>导入包,快速修复</td></tr></tbody></table><h3 id="后缀自动补全功能-Postfix-Completion"><a href="#后缀自动补全功能-Postfix-Completion" class="headerlink" title="后缀自动补全功能(Postfix Completion)"></a>后缀自动补全功能(Postfix Completion)</h3><blockquote><ul><li>要输入 for(User user : users) 只需输入 user.for + Tab。</li><li>要输入 Date birthday = user.getBirthday(); 只需输入 user.getBirthday().var + Tab 即可。 |</li></ul></blockquote><h3 id="文件"><a href="#文件" class="headerlink" title="文件"></a>文件</h3><table><thead><tr><th>快捷键</th><th>说明</th></tr></thead><tbody><tr><td>⌘ + Delete</td><td>删除文件</td></tr><tr><td>⌃ + ⌥ + N</td><td>新建一切文件</td></tr><tr><td>F5</td><td>复制类</td></tr><tr><td>F6</td><td>移动类</td></tr></tbody></table><h3 id="工具栏"><a href="#工具栏" class="headerlink" title="工具栏"></a>工具栏</h3><table><thead><tr><th>快捷键</th><th>说明</th></tr></thead><tbody><tr><td>⌃ + H</td><td>打开类层次窗口,查看类的继承关系</td></tr><tr><td>⌘ + 1</td><td>快速打开或隐藏工程面板</td></tr><tr><td>⇧ + Esc</td><td>不仅可以把焦点移到编辑器上,而且还可以隐藏当前(或最后活动的)工具窗口</td></tr></tbody></table><h3 id="查找定位"><a href="#查找定位" class="headerlink" title="查找定位"></a>查找定位</h3><table><thead><tr><th>快捷键</th><th>说明</th></tr></thead><tbody><tr><td>⌘ + F7</td><td>可以查询当前元素在当前文件中的引用,然后按 F3 可以选择</td></tr><tr><td>⌥ + F7</td><td>查找整个工程中使用地某一个类、方法或者变量的位置</td></tr><tr><td>⇧ + ⇧</td><td>Search Everywhere 功能,可在一个弹出框中搜索任何东西,包括类、资源、配置项、方法等等</td></tr><tr><td>⌘ + N</td><td>快速打开某个类</td></tr><tr><td>⌘ + ⇧ + N</td><td>快速打开文件或资源</td></tr><tr><td>⌘ + B / ⌘ + Click</td><td>快速打开光标处的类或方法(跳转到定义处)</td></tr><tr><td>⌘ + ⌥ + B</td><td>跳转到方法实现处</td></tr><tr><td>F2 / ⇧ + F2</td><td>移动到有错误的代码</td></tr><tr><td>⌘ + U</td><td>转到父类</td></tr><tr><td>⌘ + G</td><td>定位行</td></tr><tr><td>⌘ + ⌥ + left/right</td><td>返回至上次浏览的位置</td></tr><tr><td>⌘ + E</td><td>最近的文件</td></tr><tr><td>⌘ + ⇧ + E</td><td>最近更改的文件</td></tr><tr><td>⌥ + ⇧ + C</td><td>最近的更改</td></tr><tr><td>⌥ + F1</td><td>查找代码所在位置</td></tr><tr><td>⌘ + ⌥ + F7</td><td>显示用法</td></tr><tr><td>⌘ + I</td><td>实现方法</td></tr><tr><td>⌘ + ⌥ + N</td><td>内联</td></tr></tbody></table><h3 id="方法相关"><a href="#方法相关" class="headerlink" title="方法相关"></a>方法相关</h3><table><thead><tr><th>快捷键</th><th>说明</th></tr></thead><tbody><tr><td>⌘ + P</td><td>可以显示参数信息</td></tr><tr><td>⌘ + F12</td><td>查看当前文件的结构</td></tr></tbody></table><h3 id="调试部分、编译"><a href="#调试部分、编译" class="headerlink" title="调试部分、编译"></a>调试部分、编译</h3><table><thead><tr><th>快捷键</th><th>说明</th></tr></thead><tbody><tr><td>⌘ + F2</td><td>停止</td></tr><tr><td>⌥ + ⇧ + F9</td><td>选择 Debug</td></tr><tr><td>⌥ + ⇧ + F10</td><td>选择 Run</td></tr><tr><td>⌘ + ⇧ + F9</td><td>编译</td></tr><tr><td>⌘ + ⇧ + F10</td><td>运行</td></tr><tr><td>⌘ + ⇧ + F8</td><td>查看断点</td></tr><tr><td>F7</td><td>步入 Step into</td></tr><tr><td>F8</td><td>步过 Step over</td></tr><tr><td>F9</td><td>恢复程序 Continue</td></tr><tr><td>⇧ + F7</td><td>智能步入</td></tr><tr><td>⇧ + F8</td><td>步出</td></tr><tr><td>⌥ + ⇧ + F8</td><td>强制步过</td></tr><tr><td>⌥ + ⇧ + F7</td><td>强制步入</td></tr><tr><td>⌥ + F9</td><td>运行至光标处</td></tr><tr><td>⌥ + F10</td><td>定位到断点</td></tr><tr><td>⌘ + ⌥ + F9</td><td>强制运行至光标处</td></tr><tr><td>⌘ + F8</td><td>切换行断点</td></tr><tr><td>⌘ + F9</td><td>生成项目</td></tr><tr><td>⌘ + ⇧ + C</td><td>复制路径</td></tr><tr><td>⌘ + ⌥ + ⇧ + C</td><td>复制引用,必须选择类名</td></tr><tr><td>⌘ + ⌥ + Y</td><td>同步</td></tr><tr><td>⌘ + ~</td><td>快速切换方案(界面外观、代码风格、快捷键映射等菜单)</td></tr><tr><td>⇧ + F12</td><td>还原默认布局</td></tr><tr><td>⌘ + ⇧ + F12</td><td>隐藏/恢复所有窗口</td></tr><tr><td>⌘ + F4</td><td>关闭</td></tr><tr><td>⌘ + ⇧ + F4</td><td>关闭活动选项卡</td></tr><tr><td>⌘ + Tab</td><td>转到下一个拆分器</td></tr><tr><td>⌘ + ⇧ + Tab</td><td>转到上一个拆分器</td></tr></tbody></table><h3 id="切换窗口"><a href="#切换窗口" class="headerlink" title="切换窗口"></a>切换窗口</h3><table><thead><tr><th>快捷键</th><th>说明</th></tr></thead><tbody><tr><td>⌘ + 1</td><td>项目结构</td></tr><tr><td>⌘ + 2</td><td>收藏</td></tr><tr><td>⌘ + 3</td><td>搜索结果</td></tr><tr><td>⌘ + 4</td><td>运行</td></tr><tr><td>⌘ + 5</td><td>调试</td></tr><tr><td>⌘ + 6</td><td>TODO</td></tr><tr><td>⌘ + 7</td><td>结构</td></tr><tr><td>⌃ + Tab</td><td>切换 tab</td></tr></tbody></table><h3 id="其他"><a href="#其他" class="headerlink" title="其他"></a>其他</h3><table><thead><tr><th>快捷键</th><th>说明</th></tr></thead><tbody><tr><td>⌘ + ⇧ + A</td><td>可以查找所有命令,并且每个命令后面还有其快捷键</td></tr><tr><td></td><td>在任意菜单或显示窗口,都可以直接输入你要找的单词,idea 就会自动为你过滤。</td></tr></tbody></table><h3 id="测试"><a href="#测试" class="headerlink" title="测试"></a>测试</h3><table><thead><tr><th>快捷键</th><th>说明</th></tr></thead><tbody><tr><td>⌘ + ⌥ + T</td><td>创建单元测试用例</td></tr></tbody></table>]]></content>
<summary type="html">
<h3 id="智能提示"><a href="#智能提示" class="headerlink" title="智能提示"></a>智能提示</h3><blockquote>
<p>⌘ -&gt; command<br>⇧ -&gt; shift<br>⌥ -&gt; option<br>⬆ -&gt; 上箭头<br>⬇ -&gt; 下箭头<br>⌃ -&gt; Control</p>
</blockquote>
</summary>
<category term="Mac" scheme="http://jockio.github.io/tags/Mac/"/>
</entry>
<entry>
<title>许久未见,你,还好吗?</title>
<link href="http://jockio.github.io/2018/03/24/%E8%AE%B8%E4%B9%85%E6%9C%AA%E8%A7%81%EF%BC%8C%E4%BD%A0%EF%BC%8C%E8%BF%98%E5%A5%BD%E5%90%97%EF%BC%9F/"/>
<id>http://jockio.github.io/2018/03/24/许久未见,你,还好吗?/</id>
<published>2018-03-24T04:37:42.000Z</published>
<updated>2018-03-24T04:39:08.195Z</updated>
<content type="html"><![CDATA[<p>好久不见,你,还好吗?</p>]]></content>
<summary type="html">
<p>好久不见,你,还好吗?</p>
</summary>
<category term="life" scheme="http://jockio.github.io/categories/life/"/>
<category term="life" scheme="http://jockio.github.io/tags/life/"/>
</entry>
<entry>
<title>从源码角度分析 Handler Looper MessageQueue</title>
<link href="http://jockio.github.io/2016/08/16/source-code-of-handler-and-looper/"/>
<id>http://jockio.github.io/2016/08/16/source-code-of-handler-and-looper/</id>
<published>2016-08-16T11:18:02.000Z</published>
<updated>2016-08-16T11:38:58.000Z</updated>
<content type="html"><![CDATA[<h3 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h3><p>首先我们要知道,创建Handler之前,要先创建与之配套的Looper。<br><strong>在主线程中</strong>,系统已经初始化了一个 Looper 对象,因此程序直接创建 Handler 对象即可,然后就可以通过 Handler 来发送、处理消息了。<br><strong>在子线程中</strong>,必须自己创建一个 Looper 对象,并启动它。<br>创建 Looper 对象调用它的 prepare 方法即可(prepare 方法保证每个线程最多只有一个 Looper 对象),然后调用 Looper 的静态 loop 方法来启动它。loop 方法使用一个死循环不断地从MessageQueue 中取消息,并将取出的消息分发给该消息对应的 Handler 处理。至于它们具体做了哪些事,我们会在后面详细讲述。<br><a id="more"></a></p><h3 id="Looper的创建"><a href="#Looper的创建" class="headerlink" title="Looper的创建"></a>Looper的创建</h3><p>我们先看一下Looper的构造函数</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">private</span> <span class="title">Looper</span><span class="params">(<span class="keyword">boolean</span> quitAllowed)</span> </span>{</span><br><span class="line"> mQueue = <span class="keyword">new</span> MessageQueue(quitAllowed);</span><br><span class="line"> mThread = Thread.currentThread();</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>首先我们注意到该构造方法是被private修饰的,也就是说我们无法通过<code>new</code>的方式来创建Looper。其次,我们可以从Looper的构造方法中看出,在创建Looper的时候,创建了与之配套的MessageQueue,然后获取了创建当前Looper线程的引用。<br>而要想创建Looper,只需调用<code>Looper.prepare();</code>。该方法保证了一个线程只能创建一个与之相关联的Looper,并且将创建出的Looper与当前线程绑定起来。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">prepare</span><span class="params">()</span> </span>{</span><br><span class="line"> prepare(<span class="keyword">true</span>);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">prepare</span><span class="params">(<span class="keyword">boolean</span> quitAllowed)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (sThreadLocal.get() != <span class="keyword">null</span>) {</span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> RuntimeException(<span class="string">"Only one Looper may be created per thread"</span>);</span><br><span class="line"> }</span><br><span class="line"> sThreadLocal.set(<span class="keyword">new</span> Looper(quitAllowed));</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="Handler的创建"><a href="#Handler的创建" class="headerlink" title="Handler的创建"></a>Handler的创建</h3><p>Looper对象成功创建之后,我们再来看看Handler。当我们调用Handler的无参构造函数创建Handler时,它内部调用了另一个重载的构造方法<code>this(null, false)</code>。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="title">Handler</span><span class="params">(Callback callback, <span class="keyword">boolean</span> async)</span> </span>{</span><br><span class="line"> ...<span class="comment">//something we just ignore</span></span><br><span class="line"></span><br><span class="line"> mLooper = Looper.myLooper();</span><br><span class="line"> <span class="keyword">if</span> (mLooper == <span class="keyword">null</span>) {</span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> RuntimeException(</span><br><span class="line"> <span class="string">"Can't create handler inside thread that has not called Looper.prepare()"</span>);</span><br><span class="line"> }</span><br><span class="line"> mQueue = mLooper.mQueue;</span><br><span class="line"> mCallback = callback;</span><br><span class="line"> mAsynchronous = async;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>从构造方法中,我们可以看出,handler获取了与当前线程相关联的Looper及MessageQueue的引用。</p><h3 id="Handler-发送消息"><a href="#Handler-发送消息" class="headerlink" title="Handler 发送消息"></a>Handler 发送消息</h3><p>创建完Handler之后,我们先从<code>handler.sendMessage()</code>说起:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MainActivity</span> <span class="keyword">extends</span> <span class="title">Activity</span></span>{</span><br><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">onCreate</span><span class="params">(Bundle onSavedInstanceState)</span></span>{</span><br><span class="line"><span class="keyword">super</span>.onCreate(onSavedInstanceState);</span><br><span class="line">setContentView(R.layout.main);</span><br><span class="line"> </span><br><span class="line">MyRunnable mRunnable = <span class="keyword">new</span> MyRunnable();</span><br><span class="line">Thread mThread = <span class="keyword">new</span> Thread(mRunnable);</span><br><span class="line">mThread.start();</span><br><span class="line">}</span><br><span class="line"> </span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> Handler = <span class="keyword">new</span> Handler(){</span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">handleMessage</span><span class="params">(Message msg)</span></span>{</span><br><span class="line"><span class="comment">//do some magic</span></span><br><span class="line">}</span><br><span class="line">};</span><br><span class="line"> </span><br><span class="line"><span class="keyword">static</span> <span class="class"><span class="keyword">class</span> <span class="title">MyRunnable</span> <span class="keyword">implements</span> <span class="title">Runnable</span></span>{</span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">run</span><span class="params">()</span></span>{</span><br><span class="line">Message msg = Message.obtain();</span><br><span class="line"><span class="comment">//do some magic</span></span><br><span class="line">handler.sendMessage(msg);</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>而不管我们调用<code>sendEmptyMessage()</code>或者是<code>sendMessage()</code>,最终都会走到这里:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">sendMessageAtTime</span><span class="params">(Message msg, <span class="keyword">long</span> uptimeMillis)</span> </span>{</span><br><span class="line"> MessageQueue queue = mQueue;</span><br><span class="line"> <span class="keyword">if</span> (queue == <span class="keyword">null</span>) {</span><br><span class="line"> RuntimeException e = <span class="keyword">new</span> RuntimeException(</span><br><span class="line"> <span class="keyword">this</span> + <span class="string">" sendMessageAtTime() called with no mQueue"</span>);</span><br><span class="line"> Log.w(<span class="string">"Looper"</span>, e.getMessage(), e);</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> enqueueMessage(queue, msg, uptimeMillis);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>关键是最后return时,调用了<code>enqueueMessage()</code>,我们一起看一下该方法的具体实现:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">boolean</span> <span class="title">enqueueMessage</span><span class="params">(MessageQueue queue, Message msg, <span class="keyword">long</span> uptimeMillis)</span> </span>{</span><br><span class="line"> msg.target = <span class="keyword">this</span>;</span><br><span class="line"> <span class="keyword">if</span> (mAsynchronous) {</span><br><span class="line"> msg.setAsynchronous(<span class="keyword">true</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> queue.enqueueMessage(msg, uptimeMillis);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>从<code>enqueueMessage</code>的方法实现可以看出,要发送的消息获取到了当前Handler的引用,也就是<code>msg.target</code> 。然后这条信息被加入到了与当前线程相关联的MessageQueue中。到此,发送消息的逻辑已经结束。<br>那么Handler处理消息的方法又是在什么时候回调的呢?要弄明白这一点,我们要对<code>Looper.loop()</code>进行分析。</p><h3 id="Looper-loop"><a href="#Looper-loop" class="headerlink" title="Looper.loop();"></a>Looper.loop();</h3><p>前面我们也已经提过,要创建一个Handler其实是需要三个步骤的:</p><ol><li>调用<code>Looper.prepare();</code></li><li>创建Handler</li><li>调用<code>Looper.loop();</code><br><br>前面两步我们已经讲解过了,那你肯定会好奇,<code>loop()</code>中到底做了什么呢?我们一起来看一下。</li></ol><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">loop</span><span class="params">()</span> </span>{</span><br><span class="line"><span class="comment">//获取与当前线程相关联的Looper对象</span></span><br><span class="line"> <span class="keyword">final</span> Looper me = myLooper();</span><br><span class="line"> <span class="keyword">if</span> (me == <span class="keyword">null</span>) {</span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> RuntimeException(<span class="string">"No Looper; Looper.prepare() wasn't called on this thread."</span>);</span><br><span class="line"> }</span><br><span class="line"><span class="comment">//获取与Looper对象相匹配的MessageQueue</span></span><br><span class="line"> <span class="keyword">final</span> MessageQueue queue = me.mQueue;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// Make sure the identity of this thread is that of the local process,</span></span><br><span class="line"> <span class="comment">// and keep track of what that identity token actually is.</span></span><br><span class="line"> Binder.clearCallingIdentity();</span><br><span class="line"> <span class="keyword">final</span> <span class="keyword">long</span> ident = Binder.clearCallingIdentity();</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span> (;;) {</span><br><span class="line"> Message msg = queue.next(); <span class="comment">// might block</span></span><br><span class="line"> <span class="keyword">if</span> (msg == <span class="keyword">null</span>) {</span><br><span class="line"> <span class="comment">// No message indicates that the message queue is quitting.</span></span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> ...<span class="comment">//something we just ignore</span></span><br><span class="line"></span><br><span class="line"> msg.target.dispatchMessage(msg);</span><br><span class="line"></span><br><span class="line"> ...<span class="comment">//something we just ignore</span></span><br><span class="line"></span><br><span class="line"> <span class="comment">// Mark the message as in use while it remains in the recycled object pool. Clear out all other details.</span></span><br><span class="line"> msg.recycleUnchecked();</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>从源码可以看出,<code>loop()</code>其实调用了一个死循环,不断的从与Looper配套的MessageQueue中取消息,然后调用<code>msg.target.dispatchMessage(msg);</code>进行消息的分发。<br>前面Handler发送消息的时候,我们已经分析过,每个要发送的Message都获取到了发送它的Handler的引用,也就是<code>msg.target</code>。因此这里<code>msg.target.dispatchMessage(msg);</code>其实也就是调用了handler的<code>dispatchMessage</code>进行消息的分发。</p><h3 id="Handler的handleMessage-何时被回调?"><a href="#Handler的handleMessage-何时被回调?" class="headerlink" title="Handler的handleMessage()何时被回调?"></a>Handler的handleMessage()何时被回调?</h3><p>我们一起来看一下handler的<code>dispatchMessage()</code>:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">dispatchMessage</span><span class="params">(Message msg)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (msg.callback != <span class="keyword">null</span>) {</span><br><span class="line"> handleCallback(msg);</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">if</span> (mCallback != <span class="keyword">null</span>) {</span><br><span class="line"> <span class="keyword">if</span> (mCallback.handleMessage(msg)) {</span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> handleMessage(msg);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>很明显,就是在这里,Handler的<code>handleMessage</code>被回调了。<br>综上,我们可以说,是在<code>Looper.loop()</code>中,当循环不断的从MessageQueue中获取消息时,间接调用了Handler的<code>handleMessage()</code>方法。</p>]]></content>
<summary type="html">
<h3 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h3><p>首先我们要知道,创建Handler之前,要先创建与之配套的Looper。<br><strong>在主线程中</strong>,系统已经初始化了一个 Looper 对象,因此程序直接创建 Handler 对象即可,然后就可以通过 Handler 来发送、处理消息了。<br><strong>在子线程中</strong>,必须自己创建一个 Looper 对象,并启动它。<br>创建 Looper 对象调用它的 prepare 方法即可(prepare 方法保证每个线程最多只有一个 Looper 对象),然后调用 Looper 的静态 loop 方法来启动它。loop 方法使用一个死循环不断地从MessageQueue 中取消息,并将取出的消息分发给该消息对应的 Handler 处理。至于它们具体做了哪些事,我们会在后面详细讲述。<br>
</summary>
<category term="android" scheme="http://jockio.github.io/categories/android/"/>
<category term="tech" scheme="http://jockio.github.io/categories/android/tech/"/>
<category term="android" scheme="http://jockio.github.io/tags/android/"/>
</entry>
<entry>
<title>Android Studio 之 JNI 开发详解</title>
<link href="http://jockio.github.io/2016/08/02/JNI-Develop-in-Android-Studio/"/>
<id>http://jockio.github.io/2016/08/02/JNI-Develop-in-Android-Studio/</id>
<published>2016-08-02T03:19:25.000Z</published>
<updated>2016-09-02T03:21:42.000Z</updated>
<content type="html"><![CDATA[<h3 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h3><ol><li>什么是NDK?<br>NDK全称是Native Development Kit,NDK提供了一系列的工具,帮助开发者快速开发C(或C++)的动态库,并能自动将so和java应用一起打包成apk。NDK集成了交叉编译器(交叉编译器需要UNIX或LINUX系统环境),并提供了相应的mk文件隔离CPU、平台、ABI等差异,开发人员只需要简单修改mk文件(指出“哪些文件需要编译”、“编译特性要求”等),就可以创建出so。</li><li>为什么使用NDK?<br>1.)代码的保护。由于apk的java层代码很容易被反编译,而C/C++库反汇难度较大。<br>2.)可以方便地使用现存的开源库。大部分现存的开源库都是用C/C++代码编写的。<br>3.)提高程序的执行效率。将要求高性能的应用逻辑使用C开发,从而提高应用程序的执行效率。<br>4.)便于移植。用C/C++写得库可以方便在其他的嵌入式平台上再次使用。</li><li>什么是JNI?<br>JNI全称为:Java Native Interface。JNI 是本地编程接口,它使得在 Java 虚拟机内部运行的 Java 代码能够与用其它语言(如 C、C++)编写的代码进行交互。</li><li>为什么使用JNI?<br>JNI的目的是使java方法能够调用c实现的一些函数。</li><li>安卓中的so文件是什么?<br>Android中用到的so文件是一个c++的函数库。在android的JNI中,要先将相应的C语言打包成so库,然后导入到lib文件夹中供java调用。Android中用到的so文件是一个c++的函数库。在android的JNI中,要先将相应的C语言打包成so库,然后导入到lib文件夹中供java调用。Android中用到的so文件是一个c++的函数库。在android的JNI中,要先将相应的C语言打包成so库,然后导入到lib文件夹中供java调用。Android中用到的so文件是一个c++的函数库。在android的JNI中,要先将相应的C语言打包成so库,然后导入到lib文件夹中供java调用。</li></ol><a id="more"></a><p><strong>本例开发环境如下:</strong><br>操作系统:Mac<br>开发环境:Android Studio 2.2 Beta3 + NDK r12 + Gradle 2.14.1</p><h3 id="NDK安装"><a href="#NDK安装" class="headerlink" title="NDK安装"></a>NDK安装</h3><ol><li>从Android Studio安装(需翻墙)<br>1.)打开AndroidStudio,选择顶部工具条,<code>Tools->Android->SDK Manager</code><br><img src="http://upload-images.jianshu.io/upload_images/1399662-397cd60b1cf281a8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt=""><br>2.)在弹出来的对话框中选择SDK Tools选项卡<br><img src="http://upload-images.jianshu.io/upload_images/1399662-5c4d545c3a93ed29.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt=""><br>3.)勾选上图中NDK,点击 Apply,开始安装<br>4.)安装完成后,重启Android Studio</li><li>从<a href="http://www.androiddevtools.cn/" target="_blank" rel="noopener">AndroidDevTools</a>安装<br>1.)打开AndroidDevTools网页,选择导航栏中<code>Android SDK Tools->NDK</code>,选择相应平台的NDK开始下载。<br><img src="http://upload-images.jianshu.io/upload_images/1399662-dffc81c50788fabd.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt=""><br>2.)下载完成后,将NDK解压到某个文件夹下,打开Android Studio,选择<code>File->Project Structure</code><br><img src="http://upload-images.jianshu.io/upload_images/1399662-1866b88a3af285a3.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt=""><br>在弹出来的对话框中,配置NDK路径,如下所示:<br><img src="http://upload-images.jianshu.io/upload_images/1399662-37746ffd6e248da8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt=""></li></ol><h3 id="JNI开发"><a href="#JNI开发" class="headerlink" title="JNI开发"></a>JNI开发</h3><p>下面我们就一步一步来完成一个示例,从C语言编写的程序中获取字符串,然后在TextView上显示出来。</p><ol><li><p>新建一个Android Project,命名为 MyApplication<br><img src="http://upload-images.jianshu.io/upload_images/1399662-2430e33c2cd871aa.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt=""><br><strong>注意:</strong>项目路径中不能有空格!<br><img src="http://upload-images.jianshu.io/upload_images/1399662-d32557d019dea6f9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt=""></p></li><li><p>项目新建完成后,默认为Android视图,这里为了更清楚的展示,我们切换到Project视图。<br><img src="http://upload-images.jianshu.io/upload_images/1399662-f3ce407fe67a32f4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt=""><br>项目结构如下:<br><img src="http://upload-images.jianshu.io/upload_images/1399662-3505b94b5e502e3c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt=""></p></li><li><p>在项目gradle.properties文件中加上以下代码,表示我们要使用NDK进行开发。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">android.useDeprecatedNdk=<span class="keyword">true</span></span><br></pre></td></tr></table></figure></li><li><p>在项目local.properties中加入ndk和sdk的路径:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">sdk.dir=/Users/用户名/android-sdk-macosx</span><br><span class="line">ndk.dir=/Users/用户名/android-sdk-macosx/ndk-bundle</span><br></pre></td></tr></table></figure></li><li><p>在app文件夹下的build.gradle中的defaultConfig里加入如下代码</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">ndk{ </span><br><span class="line"> moduleName <span class="string">"hello"</span> <span class="comment">//生成的so文件名字,调用C程序的代码中会用到该名字 </span></span><br><span class="line"> abiFilters <span class="string">"armeabi"</span>, <span class="string">"armeabi-v7a"</span>, <span class="string">"x86"</span> <span class="comment">//输出指定三种平台下的so库</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure></li></ol><p>如下所示:<br><img src="http://upload-images.jianshu.io/upload_images/1399662-94e616a2661a3e47.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt=""></p><ol><li><p>打开布局文件activity_main.xml,我们来添加一个TextView显示从C程序中返回的字符串</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><?xml version="1.0" encoding="utf-8"?></span><br><span class="line"><span class="tag"><<span class="name">RelativeLayout</span> <span class="attr">xmlns:android</span>=<span class="string">"http://schemas.android.com/apk/res/android"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">xmlns:tools</span>=<span class="string">"http://schemas.android.com/tools"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:id</span>=<span class="string">"@+id/activity_main"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"match_parent"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:paddingBottom</span>=<span class="string">"@dimen/activity_vertical_margin"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:paddingLeft</span>=<span class="string">"@dimen/activity_horizontal_margin"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:paddingRight</span>=<span class="string">"@dimen/activity_horizontal_margin"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:paddingTop</span>=<span class="string">"@dimen/activity_vertical_margin"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">tools:context</span>=<span class="string">"me.jockio.myapplication.MainActivity"</span>></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">TextView</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:id</span>=<span class="string">"@+id/textView"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"wrap_content"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"wrap_content"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:textSize</span>=<span class="string">"20sp"</span> /></span></span><br><span class="line"><span class="tag"></<span class="name">RelativeLayout</span>></span></span><br></pre></td></tr></table></figure></li><li><p>打开MainActivity.java,添加如下代码:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MainActivity</span> <span class="keyword">extends</span> <span class="title">AppCompatActivity</span> </span>{</span><br><span class="line"></span><br><span class="line"> <span class="comment">//固定写法,表示我们要加载的资源文件为libhello.so</span></span><br><span class="line"> <span class="keyword">static</span> {</span><br><span class="line"> System.loadLibrary(<span class="string">"hello"</span>);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">onCreate</span><span class="params">(Bundle savedInstanceState)</span> </span>{</span><br><span class="line"> <span class="keyword">super</span>.onCreate(savedInstanceState);</span><br><span class="line"> setContentView(R.layout.activity_main);</span><br><span class="line"></span><br><span class="line"> TextView textView = (TextView) findViewById(R.id.textView);</span><br><span class="line"> textView.setText(getStringFromNative());</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">//声明一个本地方法,用native关键字修饰</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">native</span> String <span class="title">getStringFromNative</span><span class="params">()</span></span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li><li><p>生成.h头文件<br>打开Android Studio底部的Terminal,默认命令行窗口路径已经在当前项目,输入以下命令:</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">cd app/src/main/java</span><br><span class="line">javah -jni 包名+类名</span><br></pre></td></tr></table></figure></li></ol><p><img src="http://upload-images.jianshu.io/upload_images/1399662-b875bdefebca9cff.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt=""><br>执行完上面两条命令后,会自动生成.h文件<br><img src="http://upload-images.jianshu.io/upload_images/1399662-98d23ff126a5cd37.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt=""><br>生成.h文件内容如下:<br><img src="http://upload-images.jianshu.io/upload_images/1399662-efbf5c3803d58a6a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt=""><br>这里关键部分就是:<br><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="function">JNIEXPORT jstring JNICALL <span class="title">Java_me_jockio_myapplication_MainActivity_getStringFromNative</span> <span class="params">(JNIEnv *, jobject)</span></span>;</span><br></pre></td></tr></table></figure></p><ol><li><p>新建jni文件夹,并拷贝上面生成的.h文件到jni目录<br>选择File->New->Folder->JNI Folder<br><img src="http://upload-images.jianshu.io/upload_images/1399662-fb6cef6cefd005de.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt=""><br>在弹出的对话框中勾选<code>Change Folder Location</code>,并在下面输入文件夹名,如下图所示:<br><img src="http://upload-images.jianshu.io/upload_images/1399662-b5633d257cbd0202.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt=""></p></li><li><p>在jni目录下,右键新建C文件,文件名任意,输入如下内容:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//引入上面生成的头文件,并实现头文件中声明的方法</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">"me_jockio_myapplication_MainActivity.h"</span></span></span><br><span class="line">JNIEXPORT jstring JNICALL Java_me_jockio_myapplication_MainActivity_getStringFromNative</span><br><span class="line"> (JNIEnv *env, jobject obj){</span><br><span class="line"> <span class="keyword">char</span> *str=<span class="string">"String from native C"</span>;</span><br><span class="line"> <span class="keyword">return</span> (*env)->NewStringUTF(env, str);</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li></ol><p>注意观察函数方法名为:<code>Java_包名_类名_方法名</code>,了解到这些后我们以后就可以不生成.h文件,而是直接去写.c文件了。</p><ol><li><p>选择 Build->Make Project,看<code>app/build/intermediates/ndk/debug/lib</code>目录下是否生成.so文件,如果没有生成,选择 Build->Clean Project,等clean完成后,再Build->Rebuild Project,一般经过上面两步以后都能够解决问题。<br><img src="http://upload-images.jianshu.io/upload_images/1399662-f63991749fde2e0f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt=""><br><img src="http://upload-images.jianshu.io/upload_images/1399662-6fa5f8e8764f3da3.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt=""></p></li><li><p>打开模拟器,运行Android程序。这里可以看到已经从libhello.so文件中读取到字符串,并显示在了TextView中。<br><img src="http://upload-images.jianshu.io/upload_images/1399662-f8791e5b1f199687.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt=""></p></li></ol><h3 id="参考文章"><a href="#参考文章" class="headerlink" title="参考文章"></a>参考文章</h3><ul><li><a href="http://laocaixw.github.io/2016/07/26/%E5%9C%A8Android%20Studio%E4%B8%8A%E7%9A%84NDK%E5%BC%80%E5%8F%91/" target="_blank" rel="noopener">在Android Studio上的NDK开发</a></li><li><a href="http://yanbober.github.io/2015/02/14/android_studio_jni_1/" target="_blank" rel="noopener">NDK-JNI实战教程</a></li><li><a href="http://blog.csdn.net/lixiaovip/article/details/49102079" target="_blank" rel="noopener"> <a href="http://blog.csdn.net/lixiaovip/article/details/49102079" target="_blank" rel="noopener">Android Studio第一个jni程序</a></a></li></ul>]]></content>
<summary type="html">
<h3 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h3><ol>
<li>什么是NDK?<br>NDK全称是Native Development Kit,NDK提供了一系列的工具,帮助开发者快速开发C(或C++)的动态库,并能自动将so和java应用一起打包成apk。NDK集成了交叉编译器(交叉编译器需要UNIX或LINUX系统环境),并提供了相应的mk文件隔离CPU、平台、ABI等差异,开发人员只需要简单修改mk文件(指出“哪些文件需要编译”、“编译特性要求”等),就可以创建出so。</li>
<li>为什么使用NDK?<br>1.)代码的保护。由于apk的java层代码很容易被反编译,而C/C++库反汇难度较大。<br>2.)可以方便地使用现存的开源库。大部分现存的开源库都是用C/C++代码编写的。<br>3.)提高程序的执行效率。将要求高性能的应用逻辑使用C开发,从而提高应用程序的执行效率。<br>4.)便于移植。用C/C++写得库可以方便在其他的嵌入式平台上再次使用。</li>
<li>什么是JNI?<br>JNI全称为:Java Native Interface。JNI 是本地编程接口,它使得在 Java 虚拟机内部运行的 Java 代码能够与用其它语言(如 C、C++)编写的代码进行交互。</li>
<li>为什么使用JNI?<br>JNI的目的是使java方法能够调用c实现的一些函数。</li>
<li>安卓中的so文件是什么?<br>Android中用到的so文件是一个c++的函数库。在android的JNI中,要先将相应的C语言打包成so库,然后导入到lib文件夹中供java调用。Android中用到的so文件是一个c++的函数库。在android的JNI中,要先将相应的C语言打包成so库,然后导入到lib文件夹中供java调用。Android中用到的so文件是一个c++的函数库。在android的JNI中,要先将相应的C语言打包成so库,然后导入到lib文件夹中供java调用。Android中用到的so文件是一个c++的函数库。在android的JNI中,要先将相应的C语言打包成so库,然后导入到lib文件夹中供java调用。</li>
</ol>
</summary>
<category term="android" scheme="http://jockio.github.io/categories/android/"/>
<category term="android" scheme="http://jockio.github.io/tags/android/"/>
</entry>
<entry>
<title>屏幕适配之百分比布局</title>
<link href="http://jockio.github.io/2016/07/22/percent-layout-on-android/"/>
<id>http://jockio.github.io/2016/07/22/percent-layout-on-android/</id>
<published>2016-07-22T12:10:28.000Z</published>
<updated>2016-07-27T11:52:57.000Z</updated>
<content type="html"><![CDATA[<h3 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h3><p>刚刚复习多屏幕适配的时候,想到之所以要对手机屏幕进行适配,是因为Android手机的屏幕碎片化太过于严重。但转念一想,电脑屏幕的碎片化相对于手机只会有过之无不及吧,网上查找了下,发现前端之所以没有强调屏幕适配,是因为它们引入了百分比。</p><p>然后谷歌搜了下,才发现去年(2015年)谷歌就已经在Android中引入了百分比来适配不同的屏幕,原来我已经out了……</p><a id="more"></a><h3 id="百分比布局介绍"><a href="#百分比布局介绍" class="headerlink" title="百分比布局介绍"></a>百分比布局介绍</h3><p>谷歌目前只提供了 PercentRelativeLayout 以及 PercentFrameLayout 的两种布局,它们支持的属性有:</p><p><code>layout_widthPercent</code>、<code>layout_heightPercent</code></p><p><code>layout_marginPercent</code>、<code>layout_marginLeftPercent</code></p><p><code>layout_marginTopPercent</code>、<code>layout_marginRightPercent</code></p><p> <code>layout_marginBottomPercent</code>、<code>layout_marginStartPercent</code></p><p><code>layout_marginEndPercent</code></p><p>在此基础上鸿洋大神提供了 PercentLinearLayout (<a href="http://blog.csdn.net/lmj623565791/article/details/46695347" target="_blank" rel="noopener">见博客</a>),并已经引入到<a href="https://github.com/JulienGenoud/android-percent-support-lib-sample" target="_blank" rel="noopener">Github</a>中。</p><p><img src="http://7xwmpc.com1.z0.glb.clouddn.com/percent.png" alt="百分比布局"></p><h4 id="使用步骤"><a href="#使用步骤" class="headerlink" title="使用步骤"></a>使用步骤</h4><p>1.在gradle文件中添加依赖</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">dependencies {</span><br><span class="line"> compile <span class="string">'com.android.support:percent:22.2.0'</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>2.鸿洋大神实现的PercentLinearLayout</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> android.content.Context;</span><br><span class="line"><span class="keyword">import</span> android.content.res.TypedArray;</span><br><span class="line"><span class="keyword">import</span> android.support.percent.PercentLayoutHelper;</span><br><span class="line"><span class="keyword">import</span> android.util.AttributeSet;</span><br><span class="line"><span class="keyword">import</span> android.view.ViewGroup;</span><br><span class="line"><span class="keyword">import</span> android.widget.LinearLayout;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">PercentLinearLayout</span> <span class="keyword">extends</span> <span class="title">LinearLayout</span></span></span><br><span class="line"><span class="class"></span>{</span><br><span class="line"></span><br><span class="line"> <span class="keyword">private</span> PercentLayoutHelper mPercentLayoutHelper;</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">PercentLinearLayout</span><span class="params">(Context context, AttributeSet attrs)</span></span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> <span class="keyword">super</span>(context, attrs);</span><br><span class="line"></span><br><span class="line"> mPercentLayoutHelper = <span class="keyword">new</span> PercentLayoutHelper(<span class="keyword">this</span>);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">onMeasure</span><span class="params">(<span class="keyword">int</span> widthMeasureSpec, <span class="keyword">int</span> heightMeasureSpec)</span></span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> mPercentLayoutHelper.adjustChildren(widthMeasureSpec, heightMeasureSpec);</span><br><span class="line"> <span class="keyword">super</span>.onMeasure(widthMeasureSpec, heightMeasureSpec);</span><br><span class="line"> <span class="keyword">if</span> (mPercentLayoutHelper.handleMeasuredStateTooSmall())</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">super</span>.onMeasure(widthMeasureSpec, heightMeasureSpec);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">onLayout</span><span class="params">(<span class="keyword">boolean</span> changed, <span class="keyword">int</span> l, <span class="keyword">int</span> t, <span class="keyword">int</span> r, <span class="keyword">int</span> b)</span></span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> <span class="keyword">super</span>.onLayout(changed, l, t, r, b);</span><br><span class="line"> mPercentLayoutHelper.restoreOriginalParams();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> LayoutParams <span class="title">generateLayoutParams</span><span class="params">(AttributeSet attrs)</span></span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">new</span> LayoutParams(getContext(), attrs);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">static</span> <span class="class"><span class="keyword">class</span> <span class="title">LayoutParams</span> <span class="keyword">extends</span> <span class="title">LinearLayout</span>.<span class="title">LayoutParams</span></span></span><br><span class="line"><span class="class"> <span class="keyword">implements</span> <span class="title">PercentLayoutHelper</span>.<span class="title">PercentLayoutParams</span> </span>{</span><br><span class="line"> <span class="keyword">private</span> PercentLayoutHelper.PercentLayoutInfo mPercentLayoutInfo;</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">LayoutParams</span><span class="params">(Context c, AttributeSet attrs)</span></span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> <span class="keyword">super</span>(c, attrs);</span><br><span class="line"> mPercentLayoutInfo = PercentLayoutHelper.getPercentLayoutInfo(c, attrs);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="keyword">public</span> PercentLayoutHelper.<span class="function">PercentLayoutInfo <span class="title">getPercentLayoutInfo</span><span class="params">()</span></span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> <span class="keyword">return</span> mPercentLayoutInfo;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">setBaseAttributes</span><span class="params">(TypedArray a, <span class="keyword">int</span> widthAttr, <span class="keyword">int</span> heightAttr)</span></span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> PercentLayoutHelper.fetchWidthAndHeight(<span class="keyword">this</span>, a, widthAttr, heightAttr);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">LayoutParams</span><span class="params">(<span class="keyword">int</span> width, <span class="keyword">int</span> height)</span> </span>{</span><br><span class="line"> <span class="keyword">super</span>(width, height);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">LayoutParams</span><span class="params">(ViewGroup.LayoutParams source)</span> </span>{</span><br><span class="line"> <span class="keyword">super</span>(source);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">LayoutParams</span><span class="params">(MarginLayoutParams source)</span> </span>{</span><br><span class="line"> <span class="keyword">super</span>(source);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h4 id="百分比线性布局"><a href="#百分比线性布局" class="headerlink" title="百分比线性布局"></a>百分比线性布局</h4><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><?xml version="1.0" encoding="utf-8"?></span><br><span class="line"><span class="tag"><<span class="name">com.myapplication.view.PercentLinearLayout</span></span></span><br><span class="line"><span class="tag"> <span class="attr">xmlns:android</span>=<span class="string">"http://schemas.android.com/apk/res/android"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">xmlns:app</span>=<span class="string">"http://schemas.android.com/apk/res-auto"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"match_parent"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:orientation</span>=<span class="string">"vertical"</span>></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">TextView</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"0dp"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"0dp"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">app:layout_widthPercent</span>=<span class="string">"50%"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">app:layout_heightPercent</span>=<span class="string">"10%"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:background</span>=<span class="string">"#d1f756"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:gravity</span>=<span class="string">"center"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:text</span>=<span class="string">"width:50% height:10%"</span>/></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">TextView</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"0dp"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"0dp"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">app:layout_widthPercent</span>=<span class="string">"80%"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">app:layout_heightPercent</span>=<span class="string">"10%"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">app:layout_marginTopPercent</span>=<span class="string">"1%"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:background</span>=<span class="string">"#56f7b1"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:gravity</span>=<span class="string">"center"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:text</span>=<span class="string">"width:80% height:10%"</span>/></span></span><br><span class="line"> </span><br><span class="line"><span class="tag"></<span class="name">com.myapplication.view.PercentLinearLayout</span>></span></span><br></pre></td></tr></table></figure><p> <img src="http://7xwmpc.com1.z0.glb.clouddn.com/linear.PNG" alt="linear"></p><h4 id="百分比相对布局"><a href="#百分比相对布局" class="headerlink" title="百分比相对布局"></a>百分比相对布局</h4><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">android.support.percent.PercentRelativeLayout</span></span></span><br><span class="line"><span class="tag"> <span class="attr">xmlns:android</span>=<span class="string">"http://schemas.android.com/apk/res/android"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">xmlns:app</span>=<span class="string">"http://schemas.android.com/apk/res-auto"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"match_parent"</span>></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">View</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:id</span>=<span class="string">"@+id/top_left"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"0dp"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"0dp"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_alignParentTop</span>=<span class="string">"true"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:background</span>=<span class="string">"#ff44aacc"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">app:layout_heightPercent</span>=<span class="string">"20%"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">app:layout_widthPercent</span>=<span class="string">"70%"</span> /></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">View</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:id</span>=<span class="string">"@+id/top_right"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"0dp"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"0dp"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_alignParentTop</span>=<span class="string">"true"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_toRightOf</span>=<span class="string">"@+id/top_left"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:background</span>=<span class="string">"#ffe40000"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">app:layout_heightPercent</span>=<span class="string">"20%"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">app:layout_widthPercent</span>=<span class="string">"30%"</span> /></span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">View</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:id</span>=<span class="string">"@+id/bottom"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"0dp"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_below</span>=<span class="string">"@+id/top_left"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:background</span>=<span class="string">"#ff00ff22"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">app:layout_heightPercent</span>=<span class="string">"80%"</span> /></span></span><br><span class="line"><span class="tag"></<span class="name">android.support.percent.PercentRelativeLayout</span>></span></span><br></pre></td></tr></table></figure><h4 id="百分比帧布局"><a href="#百分比帧布局" class="headerlink" title="百分比帧布局"></a>百分比帧布局</h4><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">android.support.percent.PercentFrameLayout</span></span></span><br><span class="line"><span class="tag"> <span class="attr">xmlns:android</span>=<span class="string">"http://schemas.android.com/apk/res/android"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">xmlns:app</span>=<span class="string">"http://schemas.android.com/apk/res-auto"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"match_parent"</span>></span></span><br><span class="line"> <span class="comment"><!-- ... XML CODE --></span></span><br><span class="line"><span class="tag"></<span class="name">android.support.percent.PercentFrameLayout</span>></span></span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h3 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h3><p>刚刚复习多屏幕适配的时候,想到之所以要对手机屏幕进行适配,是因为Android手机的屏幕碎片化太过于严重。但转念一想,电脑屏幕的碎片化相对于手机只会有过之无不及吧,网上查找了下,发现前端之所以没有强调屏幕适配,是因为它们引入了百分比。</p>
<p>然后谷歌搜了下,才发现去年(2015年)谷歌就已经在Android中引入了百分比来适配不同的屏幕,原来我已经out了……</p>
</summary>
<category term="android" scheme="http://jockio.github.io/categories/android/"/>
<category term="android" scheme="http://jockio.github.io/tags/android/"/>
</entry>
<entry>
<title>一种无需为ListView设置ViewHolder的写法</title>
<link href="http://jockio.github.io/2016/07/21/an-elegent-method-of-optmize-listview/"/>
<id>http://jockio.github.io/2016/07/21/an-elegent-method-of-optmize-listview/</id>
<published>2016-07-21T11:35:44.000Z</published>
<updated>2016-07-21T11:40:26.000Z</updated>
<content type="html"><![CDATA[<p>【译】原文: <a href="https://www.bignerdranch.com/blog/customizing-android-listview-rows-subclassing/" target="_blank" rel="noopener">https://www.bignerdranch.com/blog/customizing-android-listview-rows-subclassing/</a></p><p>每个Android开发者都会碰到自定义ListView中item布局,并填充数据的情况,而你首先想到的应该就是ViewHolder模式吧。但是ViewHolder模式使用起来太过于死板,实际上我们可以做得更好。在本文中,我们会探索另外一种可供选择的方式:使用RelativeLayout的子类来封装完成定制化的工作。</p><h3 id="目标"><a href="#目标" class="headerlink" title="目标"></a>目标</h3><p>为了说明目的,我们首先创建了一个典型自定义的ListView,它的每一行包括一个ImageView和两个排列在它旁边的TextView,每个item的父布局为RelativeLayout,如下图所示。你可以在<a href="https://github.com/bignerdranch/android-listview-custom-view" target="_blank" rel="noopener">Github</a>上查看它的代码。</p><a id="more"></a><p><img src="https://www.bignerdranch.com/img/blog/2014/04/custom-listview-framed-1.png" alt="Custom ListView"></p><p>当为ListView中的item创建自定义view的时候,我们有下面的需求:</p><ul><li>使用自定义布局管理子控件的排列方式</li><li>当滚动时,重复利用已创建的view</li><li>高效识别子视图,并为其填充数据</li></ul><h3 id="ViewHolder模式所带来的问题"><a href="#ViewHolder模式所带来的问题" class="headerlink" title="ViewHolder模式所带来的问题"></a>ViewHolder模式所带来的问题</h3><p>我们在网上看到的一种实现都大同小异,这就是ViewHolder模式。简而言之,它需要下面的步骤:</p><ul><li>为ListView中item创建一个布局</li><li>创建ViewHolder类,存储item中子控件</li><li>对于ListView中的每个item,创建一个ViewHolder的实例,并通过findViewById()与ViewHolder中成员绑定</li><li>使用setTag(),将item与ViewHolder绑定</li><li>对重复使用的item重用ViewHolder对象</li></ul><p>因为下面的原因,我并不喜欢这个模式:</p><ul><li>它把太多的职责放在了Adapter的getView()方法中</li><li>ViewHolder类过于公式化</li><li>每个视图需要根据tag强转为合适的ViewHolder类型</li><li>ViewHolder类需要知道list中item内部细节,违反了封装的特点</li></ul><p>因此,我决定提供一种可供选择的方式——子类化,而不是一直抱怨。</p><h3 id="使用子类实现自定义"><a href="#使用子类实现自定义" class="headerlink" title="使用子类实现自定义"></a>使用子类实现自定义</h3><p>我会使用RelativeLayout的子类命名为ItemView作为我们是定义布局的根视图,而不是创建一个一般的视图——ViewHolder类与Adapter类的实现,它们了解太多内部实现的细节。Item是呈现数据的模型对象,它里面有三个属性:图片的url,标题以及描述。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Item</span> </span>{</span><br><span class="line"> <span class="keyword">private</span> String mImageUrl;</span><br><span class="line"> <span class="keyword">private</span> String mTitle;</span><br><span class="line"> <span class="keyword">private</span> String mDescription;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// constructor, getters and setters elided</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>ItemView有责任将Item中数据展示在屏幕上。作为ItemView的使用者(在Adapter的子类中),我想我的职责越简单越好,我真的只需要做好下面两件事:</p><ul><li>为ListView的每一个item创建或者重用ItemView</li><li>将当前行的数据Item与ItemView关联起来</li></ul><p>我们可以在ItemAdapter类中查看相关的API:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ItemAdapter</span> <span class="keyword">extends</span> <span class="title">ArrayAdapter</span><<span class="title">Item</span>> </span>{</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="title">ItemAdapter</span><span class="params">(Context c, List<Item> items)</span> </span>{</span><br><span class="line"> <span class="keyword">super</span>(c, <span class="number">0</span>, items);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> View <span class="title">getView</span><span class="params">(<span class="keyword">int</span> position, View convertView, ViewGroup parent)</span></span>{</span><br><span class="line"> ItemView itemView = (ItemView)convertView;</span><br><span class="line"> <span class="keyword">if</span> (<span class="keyword">null</span> == itemView)</span><br><span class="line"> itemView = ItemView.inflate(parent);</span><br><span class="line"> itemView.setItem(getItem(position));</span><br><span class="line"> <span class="keyword">return</span> itemView;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>这里有两行代码很有意思,首先,如果我们没有可重用的view,那么就调用<code>ItemView.inflate(ViewGroup)</code>这个静态方法获取ItemView的实例。其次,我们使用<code>setItem(Item)</code>方法为当前ItemView提供要展示的数据。所有这些细节都封装在ItemVIew内部。</p><p>ItemView通过成员变量存储对子视图的引用,把自己作为自己的ViewHolder。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ItemView</span> <span class="keyword">extends</span> <span class="title">RelativeLayout</span> </span>{</span><br><span class="line"> <span class="keyword">private</span> TextView mTitleTextView;</span><br><span class="line"> <span class="keyword">private</span> TextView mDescriptionTextView;</span><br><span class="line"> <span class="keyword">private</span> ImageView mImageView;</span><br><span class="line"></span><br><span class="line"> ...</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p><code>inflate(ViewGroup)</code>这个静态方法使创建并正确配置ItemView变得非常简单,同时使用XML文件完成自定义布局的配置。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> ItemView <span class="title">inflate</span><span class="params">(ViewGroup parent)</span> </span>{</span><br><span class="line"> ItemView itemView = (ItemView)LayoutInflater.from(parent.getContext())</span><br><span class="line"> .inflate(R.layout.item_view, parent, <span class="keyword">false</span>);</span><br><span class="line"> <span class="keyword">return</span> itemView;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>它使用参数中的<code>parent</code>来获取<code>context</code>,然后将布局文件映射为视图并返回。布局文件如下所示:</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">com.bignerdranch.android.listitemviewdemo.ItemView</span></span></span><br><span class="line"><span class="tag"> <span class="attr">xmlns:android</span>=<span class="string">"http://schemas.android.com/apk/res/android"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"wrap_content"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:padding</span>=<span class="string">"5dp"</span> /></span></span><br></pre></td></tr></table></figure><p>该布局文件只包含一个ItemView,在ItemView中声明了边距。要特别注意的是,它并没有子节点,那么我们需要的ImageView以及两个TexeView在哪呢?实际上,在ItemView的构造方法中,我们完成了对子视图的创建。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="title">ItemView</span><span class="params">(Context context, AttributeSet attrs, <span class="keyword">int</span> defStyle)</span> </span>{</span><br><span class="line"> <span class="keyword">super</span>(context, attrs, defStyle);</span><br><span class="line"> LayoutInflater.from(context).inflate(R.layout.item_view_children, <span class="keyword">this</span>, <span class="keyword">true</span>);</span><br><span class="line"> setupChildren();</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>该构造方法最终会在inflate包含ItemView视图的时候调用,它首先会调用父类的构造方法,然后infalte ItemView中的子视图。子视图的布局文件如下:</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><?xml version="1.0" encoding="utf-8"?></span><br><span class="line"><span class="tag"><<span class="name">merge</span></span></span><br><span class="line"><span class="tag"><span class="attr">xmlns:android</span>=<span class="string">"http://schemas.android.com/apk/res/android"</span></span></span><br><span class="line"><span class="tag"><span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></span></span><br><span class="line"><span class="tag"><span class="attr">android:layout_height</span>=<span class="string">"wrap_content"</span> ></span></span><br><span class="line"><span class="tag"><<span class="name">ImageView</span></span></span><br><span class="line"><span class="tag"><span class="attr">android:id</span>=<span class="string">"@+id/item_imageView"</span></span></span><br><span class="line"><span class="tag"><span class="attr">android:background</span>=<span class="string">"@android:color/darker_gray"</span></span></span><br><span class="line"><span class="tag"><span class="attr">android:layout_width</span>=<span class="string">"60dp"</span></span></span><br><span class="line"><span class="tag"><span class="attr">android:layout_height</span>=<span class="string">"60dp"</span></span></span><br><span class="line"><span class="tag"><span class="attr">android:layout_margin</span>=<span class="string">"5dp"</span></span></span><br><span class="line"><span class="tag"><span class="attr">android:contentDescription</span>=<span class="string">"@string/item_imageView_contentDescription"</span></span></span><br><span class="line"><span class="tag">/></span></span><br><span class="line"><span class="tag"><<span class="name">TextView</span></span></span><br><span class="line"><span class="tag"><span class="attr">android:id</span>=<span class="string">"@+id/item_titleTextView"</span></span></span><br><span class="line"><span class="tag"><span class="attr">android:layout_width</span>=<span class="string">"wrap_content"</span></span></span><br><span class="line"><span class="tag"><span class="attr">android:layout_height</span>=<span class="string">"wrap_content"</span></span></span><br><span class="line"><span class="tag"><span class="attr">android:layout_toRightOf</span>=<span class="string">"@id/item_imageView"</span></span></span><br><span class="line"><span class="tag"><span class="attr">android:text</span>=<span class="string">"title text"</span></span></span><br><span class="line"><span class="tag">/></span></span><br><span class="line"><span class="tag"><<span class="name">TextView</span></span></span><br><span class="line"><span class="tag"><span class="attr">android:id</span>=<span class="string">"@+id/item_descriptionTextView"</span></span></span><br><span class="line"><span class="tag"><span class="attr">android:layout_width</span>=<span class="string">"wrap_content"</span></span></span><br><span class="line"><span class="tag"><span class="attr">android:layout_height</span>=<span class="string">"wrap_content"</span></span></span><br><span class="line"><span class="tag"><span class="attr">android:layout_toRightOf</span>=<span class="string">"@id/item_imageView"</span></span></span><br><span class="line"><span class="tag"><span class="attr">android:layout_below</span>=<span class="string">"@id/item_titleTextView"</span></span></span><br><span class="line"><span class="tag"><span class="attr">android:layout_marginTop</span>=<span class="string">"5dp"</span></span></span><br><span class="line"><span class="tag"><span class="attr">android:text</span>=<span class="string">"description text"</span></span></span><br><span class="line"><span class="tag">/></span></span><br><span class="line"><span class="tag"></<span class="name">merge</span>></span></span><br></pre></td></tr></table></figure><p>根节点为<code>merge</code>标签,它表明在inflation的过程中,<code>merge</code>标签下的所有子控件都会被添加到<code>parent</code>参数中,并传递到构造方法中的<code>inflate(...)</code>方法。之后我们调用<code>setupChildren()</code>方法,通过<code>findViewById(int)</code>完成查找控件的工作,这样就可以把控件与成员变量关联起来了。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">setupChildren</span><span class="params">()</span> </span>{</span><br><span class="line"> mTitleTextView = (TextView) findViewById(R.id.item_titleTextView);</span><br><span class="line"> mDescriptionTextView = (TextView) findViewById(R.id.item_descriptionTextView);</span><br><span class="line"> mImageView = (ImageView) findViewById(R.id.item_imageView);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>到此,ItemView就已经实现了传统的VIewHolder的功能,能通过自己的成员变量将子视图的引用缓存起来。</p><p>为了让大家信服,我同时提供了<code>setItem(Item)</code>方法让调用者把Item与每个子视图绑定起来。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setItem</span><span class="params">(Item item)</span> </span>{</span><br><span class="line"> mTitleTextView.setText(item.getTitle());</span><br><span class="line"> mDescriptionTextView.setText(item.getDescription());</span><br><span class="line"> <span class="comment">// <span class="doctag">TODO:</span> set up image URL</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>这就是我们实现了一种新的模式。尽管我们需要创建多创建一个布局文件,并且为了inflation多实现了一个方法,但是优点是显而易见的:</p><ul><li><code>Adapter</code>类的实现被大大的简化了</li><li>能够很容易的通过xml文件或者代码创建<code>ItemView</code></li><li>任何扩展都能够在ItemView以及布局文件内部来完成</li><li>不再需要创建多余的ViewHolder类</li></ul><h3 id="Subclassing-works"><a href="#Subclassing-works" class="headerlink" title="Subclassing works"></a>Subclassing works</h3><p>下一次想到ViewHolder模式的时候,尝试用一下本文提到的新的模式。该模式良好的封装很容易让你充分自定义ItemView而不再需要考虑那些令人烦扰的细节。在视图重用的过程中,我敢说它跟ViewHolder模式一样好。</p>]]></content>
<summary type="html">
<p>【译】原文: <a href="https://www.bignerdranch.com/blog/customizing-android-listview-rows-subclassing/" target="_blank" rel="noopener">https://www.bignerdranch.com/blog/customizing-android-listview-rows-subclassing/</a></p>
<p>每个Android开发者都会碰到自定义ListView中item布局,并填充数据的情况,而你首先想到的应该就是ViewHolder模式吧。但是ViewHolder模式使用起来太过于死板,实际上我们可以做得更好。在本文中,我们会探索另外一种可供选择的方式:使用RelativeLayout的子类来封装完成定制化的工作。</p>
<h3 id="目标"><a href="#目标" class="headerlink" title="目标"></a>目标</h3><p>为了说明目的,我们首先创建了一个典型自定义的ListView,它的每一行包括一个ImageView和两个排列在它旁边的TextView,每个item的父布局为RelativeLayout,如下图所示。你可以在<a href="https://github.com/bignerdranch/android-listview-custom-view" target="_blank" rel="noopener">Github</a>上查看它的代码。</p>
</summary>
<category term="android" scheme="http://jockio.github.io/categories/android/"/>
<category term="译" scheme="http://jockio.github.io/categories/android/%E8%AF%91/"/>
<category term="android" scheme="http://jockio.github.io/tags/android/"/>
<category term="译" scheme="http://jockio.github.io/tags/%E8%AF%91/"/>
</entry>
<entry>
<title>the Summary of June in 2016</title>
<link href="http://jockio.github.io/2016/07/13/the-summary-of-June-in-2016/"/>
<id>http://jockio.github.io/2016/07/13/the-summary-of-June-in-2016/</id>
<published>2016-07-13T12:38:03.000Z</published>
<updated>2016-07-13T13:58:23.000Z</updated>
<content type="html"><![CDATA[<p>实习已经一个月了,终于下定决定来做个总结,哈哈,自己也觉得太不容易了……虽然也已经过去了一个月,上班也没有太多的事情,都是偶尔改一个bug,大部分时间都在自己学自己的了。下面就对这一个月学习到的东西做个总结吧。</p><h3 id="接触项目"><a href="#接触项目" class="headerlink" title="接触项目"></a>接触项目</h3><p>第一次接触工作中的项目,而且是一个比较大的项目,从SVN上checkout的时候,打开一看,整个人都不好了。项目文件分了几十个包,每个包里又有上百个类,而大部分类的代码都在2000行以上……可能这是多人协作的常态了,也只能慢慢适应了。</p><a id="more"></a><h4 id="项目背景"><a href="#项目背景" class="headerlink" title="项目背景"></a>项目背景</h4><p>由于公司是外企,项目组做的APP又是面向日本用户的,还是与日方协作开发的,因此不管是APP、文档,还是代码中的注释,文字通通都是日文,这无疑给理解项目逻辑带来了严重的挑战。尽管国内有百度翻译,但是真的用在专业术语的翻译上,那都是个屁!</p><p>可能你会说,不是有那么多界面的么,根据布局文件查找相应的Activity不就好了?其实开始我也是这样想的,但真的打开项目的时候,整个人真的都是懵逼的——布局文件只有寥寥几个,而Activity却有上百个,项目中布局复用真的是太严重了,当然了,这对项目来说是好事。</p><h4 id="项目上手"><a href="#项目上手" class="headerlink" title="项目上手"></a>项目上手</h4><p>好在项目的debug信息比较详细,每一个类的方法在开始调用的时候都会打印出该方法所属的类的类名与该方法的方法名,在方法即将结束的时候也会打印该方法所属的类的类名与该方法的方法名。凭借这些dubug信息,开始慢慢“玩”APP,每跳转一个界面看看都用到了哪些类,该类所属的Activity又是哪一个。点击界面上的按钮会触发哪些方法,就这样过了两周,开始慢慢测试一些小bug,对项目逻辑也有了些了解。</p><p>然后又接触了项目文档,虽然文档给的有些晚……文档是画面的迁移图,从某个界面经过相应的操作会跳转到哪一个界面,都描述的非常清楚(除了日文依旧看不懂)。然后在测试找bug的过程中,也学习了一些adb命令,比如查看当前界面对应的activity:<code>adb shell dumpsys activity | findstr "mFocusedActivity"</code>。通过这些命令的学习,我对项目有了更深的了解。</p><h4 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h4><ul><li>以前只会用git管理代码,入职后对SVN的使用有了一定的了解,包括update、commit、diff、merge代码等。</li><li>对上手一个处于开发中的大型项目有了一定的经验</li><li>学会了更多adb命令的使用</li></ul><blockquote><ul><li>adb shell dumpsys activity | findstr “mFocusedActivity” //获取当前界面的activity信息</li><li>adb shell input text “it’s text” //用adb命令输入文字</li><li>adb shell input keyevent 131 //左菜单键</li><li>adb shell input keyevent 132 //右菜单键</li><li>adb shell input keyevent 4 //返回键</li><li>adb install -r “apk路径” //-r 表示强制安装</li><li>adb uninstall -k “apk包名” //-k 表示卸载软件,但是保留配置和缓存文件</li><li>adb force-stop “apk包名” //强制停止应用</li></ul></blockquote>]]></content>
<summary type="html">
<p>实习已经一个月了,终于下定决定来做个总结,哈哈,自己也觉得太不容易了……虽然也已经过去了一个月,上班也没有太多的事情,都是偶尔改一个bug,大部分时间都在自己学自己的了。下面就对这一个月学习到的东西做个总结吧。</p>
<h3 id="接触项目"><a href="#接触项目" class="headerlink" title="接触项目"></a>接触项目</h3><p>第一次接触工作中的项目,而且是一个比较大的项目,从SVN上checkout的时候,打开一看,整个人都不好了。项目文件分了几十个包,每个包里又有上百个类,而大部分类的代码都在2000行以上……可能这是多人协作的常态了,也只能慢慢适应了。</p>
</summary>
<category term="work" scheme="http://jockio.github.io/categories/work/"/>
<category term="实习" scheme="http://jockio.github.io/tags/%E5%AE%9E%E4%B9%A0/"/>
</entry>
<entry>
<title>Handler Looper Messagequeue 间的关系</title>
<link href="http://jockio.github.io/2016/06/05/handler-looper-messagequeue/"/>
<id>http://jockio.github.io/2016/06/05/handler-looper-messagequeue/</id>
<published>2016-06-05T11:03:37.000Z</published>
<updated>2016-08-16T11:18:47.000Z</updated>
<content type="html"><![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>出于性能考虑,Android 中的 UI 操作为非线程安全的,这意味着如果有多个线程并发操作 UI 组件,将会导致性能安全问题。为了解决这个问题,Android 制定了一条规则:只允许在 UI 线程中更新 UI。因此,Handler 类应运而生。</p><h2 id="Handler-消息传递机制"><a href="#Handler-消息传递机制" class="headerlink" title="Handler 消息传递机制"></a>Handler 消息传递机制</h2><p>Handler 类的主要作用有两个:</p><blockquote><ol><li>在新启动的线程中发送消息</li><li>在主线程中接收消息,获取消息中数据以更新 UI</li></ol></blockquote><a id="more"></a><h3 id="原理"><a href="#原理" class="headerlink" title="原理"></a>原理</h3><p>当新启动的线程发送消息的时候,消息会发送到与之关联的 MessageQueue 中,而 Handler 会不断地从 MessageQueue 中获取并处理消息–这会导致 Handler 类中处理消息的方法被回调。</p><p>下面是关于 Handler 的应用,每隔 1s 更新 TextView 上的时间。<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MainActivity</span> <span class="keyword">extends</span> <span class="title">Activity</span></span>{</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> TextView textView;</span><br><span class="line"></span><br><span class="line"><span class="keyword">static</span> Handler handler = <span class="keyword">new</span> Handler{</span><br><span class="line"><span class="keyword">int</span> count;</span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">handleMessage</span><span class="params">(Message msg)</span></span>{</span><br><span class="line"><span class="keyword">switch</span>(msg.what){</span><br><span class="line"><span class="keyword">case</span> <span class="number">1</span>:</span><br><span class="line">count++;</span><br><span class="line">textView.setText(count + <span class="string">""</span>)</span><br><span class="line"><span class="keyword">break</span>;</span><br><span class="line"><span class="keyword">default</span>:</span><br><span class="line"><span class="keyword">break</span>;</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onCreate</span><span class="params">(Bundle savedInstanceState)</span></span>{</span><br><span class="line"><span class="keyword">super</span>.onCreate(savedInstanceState);</span><br><span class="line">setContentView(R.layout.main);</span><br><span class="line"></span><br><span class="line">textView = (TextView)findViewById(R.id.textView);</span><br><span class="line"></span><br><span class="line"><span class="keyword">new</span> Timer().schedule(<span class="keyword">new</span> TimerTask(){</span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">run</span><span class="params">()</span></span>{</span><br><span class="line">Message msg = Message.obtain();</span><br><span class="line">msg.what = <span class="number">1</span>;</span><br><span class="line">handler.sendMessage(msg);</span><br><span class="line">}</span><br><span class="line">}, <span class="number">0</span>, <span class="number">1000</span>);</span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p><p>这里要注意的是,TimerTask 对象的本质就是开启一条新的线程。</p><h2 id="Handler-Looper-MessageQueue-的工作原理"><a href="#Handler-Looper-MessageQueue-的工作原理" class="headerlink" title="Handler Looper MessageQueue 的工作原理"></a>Handler Looper MessageQueue 的工作原理</h2><p>先介绍一下与 Handler 一起工作的几个组件:</p><blockquote><ol><li>Message: Handler 接收和处理消息的对象</li><li>Looper: 每个线程只能拥有一个 Looper, 它的 loop 方法负责读取 MessageQueue 中的消息,读到消息之后就把消息发送给该消息的 Handler 进行处理。</li><li>MessageQueue: 消息队列采用先进先出的方式管理消息。程序创建 Looper 对象时,会在它的构造器中创建 MessageQueue 对象。下面是 Looper 的构造函数源码:</li></ol></blockquote><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">private</span> <span class="title">Looper</span><span class="params">()</span></span>{</span><br><span class="line"> mQueue = <span class="keyword">new</span> MessageQueue();</span><br><span class="line"> mRun = <span class="keyword">true</span>;</span><br><span class="line"> mThread = Thread.currentThread();</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>该构造函数采用 private 修饰,表明我们无法通过构造器来创建 Looper 对象。从上面代码中可以看出,程序在初始化 Looper 对象时会创建一个与之关联的 MessageQueue。</p><p>另外,由于 MessageQueue 是由 Looper 对象负责管理的,也就是说,如果希望 Handler 正常工作,必须在当前线程中有一个 Looper 对象。</p><blockquote><ol><li>在主线程中,系统已经初始化了一个 Looper 对象,因此程序直接创建 Handler 对象即可,然后就可以通过 Handler 来发送 处理消息了。</li><li>在子线程中,必须自己创建一个 Looper 对象,并启动它。创建 Looper 对象调用它的 prepare 方法即可(prepare 方法保证每个线程最多只有一个 Looper 对象),然后调用 Looper 的静态 loop 方法来启动它。loop 方法使用一个死循环不断地从MessageQueue 中取消息,并将取出的消息分发给该消息对应的 Handler 处理。</li></ol></blockquote><p>归纳起来,Looper MessageQueue Handler 各自的作用如下:</p><blockquote><ol><li>Looper: 每个线程只能拥有一个 Looper, 它的 loop 方法负责读取 MessageQueue 中的消息,读到消息之后就把消息发送给该消息所属的 Handler 进行处理。</li><li>MessageQueue: 由 Looper 进行管理,它采用先进先出的方式管理 Message。</li><li>Handler: 它把消息发送给 Looper 管理的 MessageQueue,并负责处理 Looper 分发给它的消息。</li></ol></blockquote><p>在子线程中使用 Handler 的步骤如下:</p><blockquote><ol><li>调用 Looper 对象的 prepare 方法为当前线程创建 Looper 对象。创建 Looper 对象时,它的构造器会创建与之配套的 MessageQueue。</li><li>有了 Looper 对象后,创建 Handler 类的实例,重写 handleMessage 方法,该方法负责处理来自于其它线程的消息。</li><li>调用 Looper 的 loop 方法启动 Looper。</li></ol></blockquote><p>示例代码如下:<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MainActivity</span> <span class="keyword">extends</span> <span class="title">Activity</span></span>{</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> MyThread myThread;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onCreate</span><span class="params">(Bundle savedInstanceState)</span></span>{</span><br><span class="line"><span class="keyword">super</span>.onCreate(savedInstanceState);</span><br><span class="line">setContentView(R.layout.main);</span><br><span class="line"></span><br><span class="line">myThread = <span class="keyword">new</span> MyThread();</span><br><span class="line">myThread.start();</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//处理点击事件 发送消息</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">click</span><span class="params">(View view)</span></span>{</span><br><span class="line">Message msg = Message.obtain();</span><br><span class="line">msg.what = <span class="number">6</span>;</span><br><span class="line">myThread.handler.sendMessage(msg);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MyThread</span> <span class="keyword">extends</span> <span class="title">Thread</span></span>{</span><br><span class="line"><span class="keyword">public</span> Handler handler;</span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">run</span><span class="params">()</span></span>{</span><br><span class="line">Looper.prepare();</span><br><span class="line">handler = <span class="keyword">new</span> Handler(){</span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">handleMessage</span><span class="params">(Message msg)</span></span>{</span><br><span class="line"><span class="comment">//处理消息事件</span></span><br><span class="line">}</span><br><span class="line">};</span><br><span class="line">Looper.loop();</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>]]></content>
<summary type="html">
<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>出于性能考虑,Android 中的 UI 操作为非线程安全的,这意味着如果有多个线程并发操作 UI 组件,将会导致性能安全问题。为了解决这个问题,Android 制定了一条规则:只允许在 UI 线程中更新 UI。因此,Handler 类应运而生。</p>
<h2 id="Handler-消息传递机制"><a href="#Handler-消息传递机制" class="headerlink" title="Handler 消息传递机制"></a>Handler 消息传递机制</h2><p>Handler 类的主要作用有两个:</p>
<blockquote>
<ol>
<li>在新启动的线程中发送消息</li>
<li>在主线程中接收消息,获取消息中数据以更新 UI</li>
</ol>
</blockquote>
</summary>
<category term="android" scheme="http://jockio.github.io/categories/android/"/>
<category term="android" scheme="http://jockio.github.io/tags/android/"/>
</entry>
<entry>
<title>音乐让我说</title>
<link href="http://jockio.github.io/2016/05/25/let-me-say-about-music/"/>
<id>http://jockio.github.io/2016/05/25/let-me-say-about-music/</id>
<published>2016-05-25T09:09:20.000Z</published>
<updated>2016-05-25T09:23:01.000Z</updated>
<content type="html"><![CDATA[<h2 id="爱音乐-爱生活"><a href="#爱音乐-爱生活" class="headerlink" title="爱音乐 爱生活"></a>爱音乐 爱生活</h2><p>曾经单曲循环了很久的那些歌:《夏天Alex-不再联系》《颜小健-我以为还差一首抒情歌》《曾轶可-有可能的夜晚》,不是因为旋律多好听,再或者是歌词道出了心声,而仅仅是因为当时的环境、那样的心情,让人深陷其中。<br><a id="more"></a></p><p>每天傍晚从防空洞吃完饭回来,总是很享受那段路。听着广播台里放着悠扬的音乐,渐行渐远的路上,声音源也从左耳切换到了右耳,很享受那短短的几秒钟,视听的转换真的很让人震撼,原来音乐还可以这样听。</p><p>很多年后阳光照进回忆里,这种感觉,特别好。别等,自己想要的东西,自己去追求得到,大概会成为一生的信念。</p>]]></content>
<summary type="html">
<h2 id="爱音乐-爱生活"><a href="#爱音乐-爱生活" class="headerlink" title="爱音乐 爱生活"></a>爱音乐 爱生活</h2><p>曾经单曲循环了很久的那些歌:《夏天Alex-不再联系》《颜小健-我以为还差一首抒情歌》《曾轶可-有可能的夜晚》,不是因为旋律多好听,再或者是歌词道出了心声,而仅仅是因为当时的环境、那样的心情,让人深陷其中。<br>
</summary>
<category term="随笔" scheme="http://jockio.github.io/categories/%E9%9A%8F%E7%AC%94/"/>
<category term="music" scheme="http://jockio.github.io/tags/music/"/>
</entry>
<entry>
<title>自定义 Android 日志工具</title>
<link href="http://jockio.github.io/2016/05/24/tools-of-log/"/>
<id>http://jockio.github.io/2016/05/24/tools-of-log/</id>
<published>2016-05-24T09:04:52.000Z</published>
<updated>2016-06-05T11:16:33.000Z</updated>
<content type="html"><![CDATA[<h2 id="LogUtils"><a href="#LogUtils" class="headerlink" title="LogUtils"></a>LogUtils</h2><p>在实际开发中,当应用程序发布时,我们往往需要清除程序中打印的日志。<br>一方面是减少资源的消耗,另一方面我们不希望让用户看到一些用于测试的敏感数据。<br>而一行行的删既费时又费力,而且也有可能没有完全清除。<br>此外,清除日志后对应用后继的维护与开发带来不便,因为我们也许还会需要那些打印出来的日志。<br>此工具类则解决这样一个问题:<br>当应用需要发布的时候,只要将<code>LEVEL_STATUS</code>改为<code>LEVEL_NONE</code>,日志信息就会被屏蔽。<br><a id="more"></a><br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> android.util.Log;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 此工具类对系统提供的打印日志类Log进行了封装</span></span><br><span class="line"><span class="comment"> * Created by Jockio on 2016/5/24</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">LogUtils</span> </span>{</span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">final</span> <span class="keyword">static</span> <span class="keyword">int</span> LEVEL_NONE = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">final</span> <span class="keyword">static</span> <span class="keyword">int</span> LEVEL_VERBOSE = <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">final</span> <span class="keyword">static</span> <span class="keyword">int</span> LEVEL_DEBUG = <span class="number">2</span>;</span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">final</span> <span class="keyword">static</span> <span class="keyword">int</span> LEVEL_INFO = <span class="number">3</span>;</span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">final</span> <span class="keyword">static</span> <span class="keyword">int</span> LEVEL_WARN = <span class="number">4</span>;</span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">final</span> <span class="keyword">static</span> <span class="keyword">int</span> LEVEL_ERROR = <span class="number">5</span>;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">static</span> String TAG = <span class="string">"LogUtils"</span>;</span><br><span class="line"> <span class="comment">//指示当前的打印状态</span></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">int</span> LEVEL_STATUS = LEVEL_ERROR;</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">v</span><span class="params">(String tag, String msg)</span></span>{</span><br><span class="line"> <span class="keyword">if</span>(LEVEL_STATUS >= LEVEL_VERBOSE){</span><br><span class="line"> Log.v(tag, msg);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">d</span><span class="params">(String tag, String msg)</span></span>{</span><br><span class="line"> <span class="keyword">if</span>(LEVEL_STATUS >= LEVEL_DEBUG){</span><br><span class="line"> Log.d(tag, msg);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">i</span><span class="params">(String tag, String msg)</span></span>{</span><br><span class="line"> <span class="keyword">if</span>(LEVEL_STATUS >= LEVEL_INFO){</span><br><span class="line"> Log.i(tag, msg);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">w</span><span class="params">(String tag, String msg)</span></span>{</span><br><span class="line"> <span class="keyword">if</span>(LEVEL_STATUS >= LEVEL_WARN){</span><br><span class="line"> Log.w(tag, msg);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">e</span><span class="params">(String tag, String msg)</span></span>{</span><br><span class="line"> <span class="keyword">if</span>(LEVEL_STATUS >= LEVEL_ERROR){</span><br><span class="line"> Log.e(tag, msg);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">v</span><span class="params">(String msg)</span></span>{</span><br><span class="line"> <span class="keyword">if</span>(LEVEL_STATUS >= LEVEL_VERBOSE){</span><br><span class="line"> Log.v(TAG, msg);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">d</span><span class="params">(String msg)</span></span>{</span><br><span class="line"> <span class="keyword">if</span>(LEVEL_STATUS >= LEVEL_DEBUG){</span><br><span class="line"> Log.d(TAG, msg);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">i</span><span class="params">(String msg)</span></span>{</span><br><span class="line"> <span class="keyword">if</span>(LEVEL_STATUS >= LEVEL_INFO){</span><br><span class="line"> Log.i(TAG, msg);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">w</span><span class="params">(String msg)</span></span>{</span><br><span class="line"> <span class="keyword">if</span>(LEVEL_STATUS >= LEVEL_WARN){</span><br><span class="line"> Log.w(TAG, msg);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">e</span><span class="params">(String msg)</span></span>{</span><br><span class="line"> <span class="keyword">if</span>(LEVEL_STATUS >= LEVEL_ERROR){</span><br><span class="line"> Log.e(TAG, msg);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>]]></content>
<summary type="html">
<h2 id="LogUtils"><a href="#LogUtils" class="headerlink" title="LogUtils"></a>LogUtils</h2><p>在实际开发中,当应用程序发布时,我们往往需要清除程序中打印的日志。<br>一方面是减少资源的消耗,另一方面我们不希望让用户看到一些用于测试的敏感数据。<br>而一行行的删既费时又费力,而且也有可能没有完全清除。<br>此外,清除日志后对应用后继的维护与开发带来不便,因为我们也许还会需要那些打印出来的日志。<br>此工具类则解决这样一个问题:<br>当应用需要发布的时候,只要将<code>LEVEL_STATUS</code>改为<code>LEVEL_NONE</code>,日志信息就会被屏蔽。<br>
</summary>
<category term="android" scheme="http://jockio.github.io/categories/android/"/>
<category term="tech" scheme="http://jockio.github.io/categories/android/tech/"/>
<category term="android" scheme="http://jockio.github.io/tags/android/"/>
</entry>
<entry>
<title>Android 系列笔记 十一 - Fragment 与 动画</title>
<link href="http://jockio.github.io/2016/05/22/android-note-day11/"/>
<id>http://jockio.github.io/2016/05/22/android-note-day11/</id>
<published>2016-05-22T06:14:33.000Z</published>
<updated>2016-07-07T09:12:19.000Z</updated>
<content type="html"><![CDATA[<h3 id="Fragment-生命周期"><a href="#Fragment-生命周期" class="headerlink" title="Fragment 生命周期"></a>Fragment 生命周期</h3><p>Fragment必须是依存与Activity而存在的,因此Activity的生命周期会直接影响到Fragment的生命周期。官网这张图很好的说明了两者生命周期的关系:</p><a id="more"></a><p><img src="/images/fragment_life.png" alt="Fragment 生命周期"></p><p>可以看到Fragment比Activity多了几个额外的生命周期回调方法:<br><strong>onAttach(Activity)</strong><br>当Fragment与Activity发生关联时调用。<br><strong>onCreateView(LayoutInflater, ViewGroup,Bundle)</strong><br>创建该Fragment的视图<br><strong>onActivityCreated(Bundle)</strong><br>当Activity的onCreate方法返回时调用<br><strong>onDestoryView()</strong><br>与onCreateView想对应,当该Fragment的视图被移除时调用<br><strong>onDetach()</strong><br>与onAttach相对应,当Fragment与Activity关联被取消时调用<br>注意:除了onCreateView,其他的所有方法如果你重写了,必须调用父类对于该方法的实现,</p><h3 id="Fragment"><a href="#Fragment" class="headerlink" title="Fragment"></a>Fragment</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Fragment1</span> <span class="keyword">extends</span> <span class="title">Fragment</span></span>{</span><br><span class="line">TextView tv;</span><br><span class="line">EditText et;</span><br><span class="line">Button button;</span><br><span class="line"><span class="comment">//返回的View对象会作为fragment1的内容显示在屏幕上</span></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> view <span class="title">onCreateView</span><span class="params">(LayoutInflater inflater, ViewGroup container,</span></span></span><br><span class="line"><span class="function"><span class="params">Bundle savedInstanceState)</span></span>{</span><br><span class="line">View view = inflater.inflate(R.layout.fragment1, <span class="keyword">null</span>);</span><br><span class="line">tv = (TextView)view.findViewById(R.id.textview);</span><br><span class="line">et = (EditText)view.findViewById(R.id.edittext);</span><br><span class="line">button = (Button)view.findViewById(R.id.button);</span><br><span class="line"></span><br><span class="line">button.setOnClickListener(<span class="keyword">new</span> View.OnClickListener(){</span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onClick</span><span class="params">(View v)</span></span>{</span><br><span class="line">String text = et.getText().toString();</span><br><span class="line">((MainActivity)getActivity()).setText(text);</span><br><span class="line">}</span><br><span class="line">});</span><br><span class="line"><span class="keyword">return</span> view;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setText</span><span class="params">(String text)</span></span>{</span><br><span class="line">tv.setText(text);</span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MainActivity</span> <span class="keyword">extends</span> <span class="title">Activity</span></span>{</span><br><span class="line">TextView tv;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">click</span><span class="params">(View v)</span></span>{</span><br><span class="line"><span class="comment">//把fragment界面显示在帧布局中</span></span><br><span class="line">Fragment1 fg1 = <span class="keyword">new</span> Fragment1();</span><br><span class="line">FragmentManager fm = getFragmentManager();</span><br><span class="line">FragmentTransaction ft = fm.beginTransaction();</span><br><span class="line"><span class="comment">//资源id: 要显示布局的id</span></span><br><span class="line">ft.replace(R.id.fl, fg1);</span><br><span class="line">ft.commit();</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setText</span><span class="params">(String text)</span></span>{</span><br><span class="line">tv.setText(text);</span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="帧动画"><a href="#帧动画" class="headerlink" title="帧动画"></a>帧动画</h3><p>多张图片快速切换,形成动画效果</p><p>资源文件 frameanimation.xml<br><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"><!--false 表示会循环播放--></span></span><br><span class="line"><span class="tag"><<span class="name">animation-list</span> <span class="attr">android:oneshot</span>=<span class="string">"false"</span>></span></span><br><span class="line"><span class="tag"><<span class="name">item</span> <span class="attr">android:drawable</span>=<span class="string">"@drawable/pic1"</span> <span class="attr">android:duration</span>=<span class="string">"200"</span> /></span></span><br><span class="line"><span class="tag"><<span class="name">item</span> <span class="attr">android:drawable</span>=<span class="string">"@drawable/pic2"</span> <span class="attr">android:duration</span>=<span class="string">"200"</span> /></span></span><br><span class="line"><span class="tag"><<span class="name">item</span> <span class="attr">android:drawable</span>=<span class="string">"@drawable/pic3"</span> <span class="attr">android:duration</span>=<span class="string">"200"</span> /></span></span><br><span class="line"><span class="tag"><<span class="name">item</span> <span class="attr">android:drawable</span>=<span class="string">"@drawable/pic4"</span> <span class="attr">android:duration</span>=<span class="string">"200"</span> /></span></span><br><span class="line"><span class="tag"><<span class="name">item</span> <span class="attr">android:drawable</span>=<span class="string">"@drawable/pic5"</span> <span class="attr">android:duration</span>=<span class="string">"200"</span> /></span></span><br><span class="line"><span class="tag"><<span class="name">item</span> <span class="attr">android:drawable</span>=<span class="string">"@drawable/pic6"</span> <span class="attr">android:duration</span>=<span class="string">"200"</span> /></span></span><br><span class="line"><span class="tag"><<span class="name">item</span> <span class="attr">android:drawable</span>=<span class="string">"@drawable/pic7"</span> <span class="attr">android:duration</span>=<span class="string">"200"</span> /></span></span><br><span class="line"><span class="tag"><<span class="name">item</span> <span class="attr">android:drawable</span>=<span class="string">"@drawable/pic8"</span> <span class="attr">android:duration</span>=<span class="string">"200"</span> /></span></span><br><span class="line"><span class="tag"><<span class="name">item</span> <span class="attr">android:drawable</span>=<span class="string">"@drawable/pic9"</span> <span class="attr">android:duration</span>=<span class="string">"200"</span> /></span></span><br><span class="line"><span class="tag"></<span class="name">animation-list</span>></span></span><br></pre></td></tr></table></figure></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MainActivity</span> <span class="keyword">extends</span> <span class="title">Activity</span></span>{</span><br><span class="line">ImageView iv;</span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">onCreate</span><span class="params">(Bundle savedInstanceState)</span></span>{</span><br><span class="line"><span class="keyword">super</span>.onCreate(savedInstanceState);</span><br><span class="line">setContentView(R.layout.main);</span><br><span class="line"></span><br><span class="line">iv = (ImageView)findViewById(R.id.imageView);</span><br><span class="line"><span class="comment">//把帧动画的资源文件指定为iv的背景</span></span><br><span class="line">iv.setBackgroundResource(R.drawable.frameanimation);</span><br><span class="line">AnimationDrawable ad = (AnimationDrawable)iv.getBackground();</span><br><span class="line">ad.start();</span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="补间动画"><a href="#补间动画" class="headerlink" title="补间动画"></a>补间动画</h3><p>组件由原始状态向终极状态转变时,为了让过渡更自然而自动生成的动画</p><h4 id="平移动画"><a href="#平移动画" class="headerlink" title="平移动画"></a>平移动画</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//平移</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">translate</span><span class="params">(View v)</span></span>{</span><br><span class="line"><span class="comment">//定义位移动画</span></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">10: 表示 x 坐标起始位置</span></span><br><span class="line"><span class="comment">imageView 的真实 x 坐标 + 10</span></span><br><span class="line"><span class="comment">100: 表示 x 坐标的结束位置</span></span><br><span class="line"><span class="comment">20: 表示 y 坐标的起始位置</span></span><br><span class="line"><span class="comment">200: 表示 y 坐标的结束位置</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line">TranslateAnimation ta = <span class="keyword">new</span> TranslateAnimation(</span><br><span class="line"><span class="number">10</span>, <span class="number">100</span>, <span class="number">20</span>, <span class="number">200</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">Animation.RELATIVE_TO_SELF, 1: x 坐标的起始位置</span></span><br><span class="line"><span class="comment">imageView 的真实 x + 1 * imageView 的宽度</span></span><br><span class="line"><span class="comment">Animation.RELATIVE_TO_SELF, 0.5f: y 坐标的起始位置</span></span><br><span class="line"><span class="comment">imageView 的真实 y + 0.5 * imageView 的高度</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line">TranslateAnimation ta = <span class="keyword">new</span> TranslateAnimation(</span><br><span class="line">Animation.RELATIVE_TO_SELF, <span class="number">1</span>,</span><br><span class="line">Animation.RELATIVE_TO_SELF, <span class="number">3</span>,</span><br><span class="line">Animation.RELATIVE_TO_SELF, <span class="number">0.5f</span>,</span><br><span class="line">Animation.RELATIVE_TO_SELF, <span class="number">2</span>);</span><br><span class="line"><span class="comment">//设置播放时间</span></span><br><span class="line">ta.setDuration(<span class="number">2000</span>);</span><br><span class="line"><span class="comment">//会播放两次</span></span><br><span class="line">ta.setRepeatCount(<span class="number">1</span>);</span><br><span class="line"><span class="comment">//重复的那一次动画的模式</span></span><br><span class="line">ta.setRepeatMode(Animation.REVERSE);</span><br><span class="line">imageView.startAnimation(ta);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h4 id="缩放"><a href="#缩放" class="headerlink" title="缩放"></a>缩放</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//缩放</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">scale</span><span class="params">(View v)</span></span>{</span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">0.5f: 表示 x 坐标缩放的初始位置</span></span><br><span class="line"><span class="comment">0.5 * imageView 的宽度</span></span><br><span class="line"><span class="comment">2: 表示 x 坐标缩放的结束位置</span></span><br><span class="line"><span class="comment">2 * imageView 的宽度</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line">ScaleAnimation sa = <span class="keyword">new</span> ScaleAnimation(<span class="number">0.5f</span>, <span class="number">2</span>, <span class="number">0.1f</span>, <span class="number">3</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">//设置缩放的中心点</span></span><br><span class="line">ScaleAnimation sa = <span class="keyword">new</span> ScaleAnimation(<span class="number">0.5f</span>, <span class="number">2</span>, <span class="number">0.1f</span>, <span class="number">3</span>,</span><br><span class="line">imageView.getWidth() / <span class="number">2</span>, imageView.getHeight() / <span class="number">2</span>);</span><br><span class="line">sa.setDuration(<span class="number">2000</span>);</span><br><span class="line">sa.setRepeatCount(<span class="number">1</span>);</span><br><span class="line">sa.setRepeatMode(Animation.REVERSE);</span><br><span class="line"><span class="comment">//填充动画的结束位置</span></span><br><span class="line">sa.setFillAfter(<span class="keyword">true</span>);</span><br><span class="line">imageView.startAnimation(sa);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h4 id="透明"><a href="#透明" class="headerlink" title="透明"></a>透明</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">alpha</span><span class="params">(View v)</span></span>{</span><br><span class="line">AlphaAnimation aa = <span class="keyword">new</span> AlphaAnimation(<span class="number">0</span>, <span class="number">0.5f</span>);</span><br><span class="line">aa.setDuration(<span class="number">2000</span>);</span><br><span class="line">imageView.startAnimation(aa);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h4 id="旋转"><a href="#旋转" class="headerlink" title="旋转"></a>旋转</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">rotate</span><span class="params">(View v)</span></span>{</span><br><span class="line"><span class="comment">//相对中心点,从20度转到180度</span></span><br><span class="line">RotateAnimation ra = <span class="keyword">new</span> RotateAnimation(<span class="number">20</span>, <span class="number">180</span>,</span><br><span class="line">imageView.getWidth() / <span class="number">2</span>, imageView.getHeight() / <span class="number">2</span>);</span><br><span class="line">ra.setDuration(<span class="number">2000</span>);</span><br><span class="line">imageView.startAnimation(ra);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h4 id="补间动画集合"><a href="#补间动画集合" class="headerlink" title="补间动画集合"></a>补间动画集合</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">fly</span><span class="params">(View v)</span></span>{</span><br><span class="line">AlphaAnimation aa = <span class="keyword">new</span> AlphaAnimation(<span class="number">0</span>, <span class="number">0.5f</span>);</span><br><span class="line">aa.setDuration(<span class="number">2000</span>);</span><br><span class="line">RotateAnimation ra = <span class="keyword">new</span> RotateAnimation(<span class="number">20</span>, <span class="number">180</span>,</span><br><span class="line">imageView.getWidth() / <span class="number">2</span>, imageView.getHeight() / <span class="number">2</span>);</span><br><span class="line">ra.setDuration(<span class="number">2000</span>);</span><br><span class="line"></span><br><span class="line">AnimationSet set = <span class="keyword">new</span> AnimationSet(<span class="keyword">false</span>);</span><br><span class="line">set.add(aa);</span><br><span class="line">set.add(ra);</span><br><span class="line"></span><br><span class="line">imageView.startAnimation(set);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="属性动画:3-0-之后新特性"><a href="#属性动画:3-0-之后新特性" class="headerlink" title="属性动画:3.0 之后新特性"></a>属性动画:3.0 之后新特性</h3><p>补间动画并没有改变控件的真实位置,只是重新绘制了界面<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">translate</span><span class="params">(View v)</span></span>{</span><br><span class="line">TranslateAnimation ta = <span class="keyword">new</span> TranslateAnimation(<span class="number">0</span>, <span class="number">150</span>, <span class="number">0</span>, <span class="number">0</span>);</span><br><span class="line">ta.setDuration(<span class="number">2000</span>);</span><br><span class="line">ta.setFillAfter(<span class="keyword">true</span>);</span><br><span class="line">imageView.startAnimation(ta);</span><br><span class="line"></span><br><span class="line"><span class="comment">//target: 动画作用于哪一个组件</span></span><br><span class="line"><span class="comment">//改变的是控件的哪一个属性</span></span><br><span class="line"><span class="comment">//都是经过哪些 x 坐标点</span></span><br><span class="line">ObjectAnimator oa = ObjectAnimator.ofFloat(imageView,</span><br><span class="line"><span class="string">"translationX"</span>, <span class="number">10</span>, <span class="number">50</span>, <span class="number">20</span>, <span class="number">100</span>);</span><br><span class="line">oa.setDuration(<span class="number">2000</span>);</span><br><span class="line">oa.setRepeatCount(<span class="number">1</span>);</span><br><span class="line">oa.setRepeatMode(ValueAnimator.REVERSE);</span><br><span class="line">oa.start();</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//缩放</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">scale</span><span class="params">(View v)</span></span>{</span><br><span class="line">ObjectAnimator oa = ObjectAnimator.ofFloat(imageView, <span class="string">"scaleX"</span>, <span class="number">1</span>, <span class="number">1.6f</span>, <span class="number">1.2f</span>, <span class="number">2</span>);</span><br><span class="line">oa.setDuration(<span class="number">2000</span>);</span><br><span class="line">oa.start();</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//透明</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">alpha</span><span class="params">(View v)</span></span>{</span><br><span class="line">ObjectAnimator oa = ObjectAnimator.ofFloat(imageView, <span class="string">"alpha"</span>, <span class="number">0</span>, <span class="number">0.6f</span>, <span class="number">0.2f</span>, <span class="number">1</span>);</span><br><span class="line">oa.setDuration(<span class="number">2000</span>);</span><br><span class="line">oa.start();</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//旋转</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">rotate</span><span class="params">(View v)</span></span>{</span><br><span class="line">ObjectAnimator oa = ObjectAnimator.ofFloat(imageView, <span class="string">"rotation"</span>, <span class="number">0</span>, <span class="number">90</span>, <span class="number">180</span>, <span class="number">90</span>, <span class="number">360</span>);</span><br><span class="line">oa.setDuration(<span class="number">2000</span>);</span><br><span class="line">oa.start();</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//属性动画集合</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">fly</span><span class="params">(View v)</span></span>{</span><br><span class="line">AnimatorSet set = <span class="keyword">new</span> AnimatorSet();</span><br><span class="line"></span><br><span class="line">ObjectAnimator oa1 = ObjectAnimator.ofFloat(imageView, <span class="string">"rotation"</span>, <span class="number">0</span>, <span class="number">90</span>, <span class="number">180</span>, <span class="number">90</span>, <span class="number">360</span>);</span><br><span class="line">oa1.setDuration(<span class="number">2000</span>);</span><br><span class="line"></span><br><span class="line">ObjectAnimator oa2 = ObjectAnimator.ofFloat(imageView, <span class="string">"alpha"</span>, <span class="number">0</span>, <span class="number">0.6f</span>, <span class="number">0.2f</span>, <span class="number">1</span>);</span><br><span class="line">oa2.setDuration(<span class="number">2000</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">//按顺序执行</span></span><br><span class="line">set.playSequentially(oa1, oa2);</span><br><span class="line"><span class="comment">//所有动画一起执行</span></span><br><span class="line"><span class="comment">//set.playTogether(oa1, oa2);</span></span><br><span class="line">set.start();</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p><h3 id="使用xml定义属性动画"><a href="#使用xml定义属性动画" class="headerlink" title="使用xml定义属性动画"></a>使用xml定义属性动画</h3><p>资源文件类型:Property Animation<br>资源文件名 objanimator.xml<br><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><?xml version="1.0" encoding="utf-8"?></span><br><span class="line"><span class="tag"><<span class="name">set</span>></span></span><br><span class="line"><span class="tag"><<span class="name">objectAnimator</span></span></span><br><span class="line"><span class="tag"><span class="attr">android:propertyName</span>=<span class="string">"translationX"</span></span></span><br><span class="line"><span class="tag"><span class="attr">android:duration</span>=<span class="string">"2000"</span></span></span><br><span class="line"><span class="tag"><span class="attr">android:repeatCount</span>=<span class="string">"1"</span></span></span><br><span class="line"><span class="tag"><span class="attr">android:repeatMode</span>=<span class="string">"reverse"</span></span></span><br><span class="line"><span class="tag"><span class="attr">android:valueFrom</span>=<span class="string">"-100"</span></span></span><br><span class="line"><span class="tag"><span class="attr">android:valueTo</span>=<span class="string">"100"</span>/></span></span><br><span class="line"><span class="tag"></<span class="name">set</span>></span></span><br></pre></td></tr></table></figure></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">xml</span><span class="params">(View v)</span></span>{</span><br><span class="line">Animator at = AnimatorInflater.loadAnimator(<span class="keyword">this</span>, R.animator.objanimator);</span><br><span class="line">at.setTarget(imageView);</span><br><span class="line">at.start();</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h3 id="Fragment-生命周期"><a href="#Fragment-生命周期" class="headerlink" title="Fragment 生命周期"></a>Fragment 生命周期</h3><p>Fragment必须是依存与Activity而存在的,因此Activity的生命周期会直接影响到Fragment的生命周期。官网这张图很好的说明了两者生命周期的关系:</p>
</summary>
<category term="android" scheme="http://jockio.github.io/categories/android/"/>
<category term="notes" scheme="http://jockio.github.io/categories/android/notes/"/>
<category term="android" scheme="http://jockio.github.io/tags/android/"/>
</entry>
<entry>
<title>Android 系列笔记 十 - 内容提供者</title>
<link href="http://jockio.github.io/2016/05/21/android-note-day10/"/>
<id>http://jockio.github.io/2016/05/21/android-note-day10/</id>
<published>2016-05-21T07:46:53.000Z</published>
<updated>2016-06-05T11:19:16.000Z</updated>
<content type="html"><![CDATA[<h3 id="ContentProvider-内容提供者"><a href="#ContentProvider-内容提供者" class="headerlink" title="ContentProvider 内容提供者"></a>ContentProvider 内容提供者</h3><p>作用:把私有数据暴露给其它应用,通常是把私有数据库的数据暴露给其它应用</p><blockquote><p>ContentProvider作为安卓的四大组件之一,使用时首先要在配置清单文件中声明。<br>如果ContentProvider在清单文件中声明了权限,则同时要在配置清单中定义这个权限,同样,内容访问者要访问这个provider要首先声明相应的使用权限。</p></blockquote><a id="more"></a><p>在application节点下添加以下内容:<br><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">provider</span></span></span><br><span class="line"><span class="tag">//其它应用访问内容提供者的地址</span></span><br><span class="line"><span class="tag"><span class="attr">android:authorities</span>=<span class="string">"自定义唯一识别码"</span></span></span><br><span class="line"><span class="tag"><span class="attr">android:name</span>=<span class="string">"包名+类名"</span></span></span><br><span class="line"><span class="tag"><span class="attr">android:exported</span>=<span class="string">"true"</span> //若为<span class="attr">false</span>,则不允许其他应用访问</span></span><br><span class="line"><span class="tag"><span class="attr">android:readPermission</span>=<span class="string">"自定义一"</span>//读权限</span></span><br><span class="line"><span class="tag"><span class="attr">android:writePermission</span>=<span class="string">"自定义二"</span>/></span>//写权限</span><br></pre></td></tr></table></figure></p><p>若provider声明了权限,则要在Manifest节点下定义相应的权限<br><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">permission</span> <span class="attr">android:name</span>=<span class="string">"自定义一"</span>/></span></span><br><span class="line"><span class="tag"><<span class="name">permission</span> <span class="attr">android:name</span>=<span class="string">"自定义二"</span>/></span></span><br></pre></td></tr></table></figure></p><p>自定义ContentProvider继承自ContentProvider,实现父类的方法<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">final</span> <span class="keyword">static</span> <span class="keyword">int</span> INSERT = <span class="number">1</span>;</span><br><span class="line"><span class="keyword">final</span> <span class="keyword">static</span> <span class="keyword">int</span> DELETE = <span class="number">2</span>;</span><br><span class="line"><span class="keyword">final</span> <span class="keyword">static</span> <span class="keyword">int</span> UPDATE = <span class="number">3</span>;</span><br><span class="line"><span class="keyword">final</span> <span class="keyword">static</span> <span class="keyword">int</span> QUERYALL = <span class="number">4</span>;</span><br><span class="line"><span class="keyword">final</span> <span class="keyword">static</span> <span class="keyword">int</span> QUERYITEM = <span class="number">5</span>;</span><br><span class="line"><span class="comment">//自定义内容提供者唯一标识符</span></span><br><span class="line"><span class="keyword">static</span> String authorities = <span class="string">"com.example.myProvider"</span>;</span><br><span class="line"><span class="keyword">static</span> UriMatcher uriMatcher;</span><br><span class="line">MyOpehHelper mOpenHelper;</span><br><span class="line">SQLiteDatabase db;</span><br><span class="line"></span><br><span class="line"><span class="keyword">static</span>{</span><br><span class="line"><span class="comment">//检测其它用户传入的Uri与匹配器定义好的uri中,哪条匹配,不匹配返回 NO_MATCH</span></span><br><span class="line">uriMatcher=<span class="keyword">new</span> UriMatcher(UriMatcher.NO_MATCH)</span><br><span class="line"><span class="comment">//向内容提供者添加访问的Uri,根据Uri的访问相应的数据。</span></span><br><span class="line"><span class="comment">//content://authorities/person/insert 相匹配的话 返回 INSERT</span></span><br><span class="line">uriMatcher.addUri(authorities, <span class="string">"person/insert"</span>, INSERT);</span><br><span class="line">uriMatcher.addUri(authorities, <span class="string">"person/delete"</span>, DELETE);</span><br><span class="line">uriMatcher.addUri(authorities, <span class="string">"person/update"</span>, UPDATE);</span><br><span class="line">uriMatcher.addUri(authorities, <span class="string">"person/queryAll"</span>, QUERYALL);</span><br><span class="line"><span class="comment">//# 可以代表任意一个数字,匹配Uri的话返回相应的匹配码</span></span><br><span class="line">uriMatcher.addURI(authorities, <span class="string">"person/queryItem/#"</span>, QUERYITEM);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">onCreate</span><span class="params">()</span> </span>{</span><br><span class="line"> mOpenHelper = <span class="keyword">new</span> MyOpenHelper(getContext());</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> Cursor <span class="title">query</span><span class="params">(Uri uri, String[] projection,</span></span></span><br><span class="line"><span class="function"><span class="params">String selection, String[] selectionArgs, String sortOrder)</span> </span>{</span><br><span class="line"> db = mOpenHelper.getWritableDatabase();</span><br><span class="line"> <span class="comment">//使用Uri匹配器匹配传入的uri,匹配的话会返回定义好的匹配码</span></span><br><span class="line"> <span class="keyword">switch</span>(uriMatcher.match(uri)){</span><br><span class="line"> <span class="keyword">case</span> QUERYALL:</span><br><span class="line"> Cursor c = db.query(<span class="string">"person"</span>, projection, selection,</span><br><span class="line"> selectionArgs, <span class="keyword">null</span>, <span class="keyword">null</span>, sortOrder);</span><br><span class="line"> <span class="keyword">return</span> c;</span><br><span class="line"> <span class="keyword">case</span> QUERYITEM:<span class="comment">//查询单条数据</span></span><br><span class="line"> <span class="keyword">if</span>(db.isOpen()){</span><br><span class="line"> <span class="comment">//把Uri末尾携带的数据取出来</span></span><br><span class="line"> <span class="keyword">long</span> id = ContentUris.parseId(uri);</span><br><span class="line"> Cursor cursor = db.query(<span class="string">"person"</span>, projection, <span class="string">"_id=?"</span>,</span><br><span class="line"> <span class="keyword">new</span> String[]{id + <span class="string">""</span>}, <span class="keyword">null</span>, <span class="keyword">null</span>, sortOrder);</span><br><span class="line"> <span class="keyword">return</span> cursor;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line"> <span class="keyword">default</span>:</span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> RuntimeException(<span class="string">"Uri not match"</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">getType</span><span class="params">(Uri uri)</span> </span>{</span><br><span class="line"> <span class="keyword">switch</span> (uriMatcher.match(uri)){</span><br><span class="line"> <span class="keyword">case</span> QUERYALL:</span><br><span class="line"> <span class="keyword">return</span> <span class="string">"vnd.android.cursor.dir/person"</span>;</span><br><span class="line"> <span class="keyword">case</span> QUERYITEM:</span><br><span class="line"> <span class="keyword">return</span> <span class="string">"vnd.android.cursor.item/person"</span>;</span><br><span class="line"> <span class="keyword">default</span>:</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//此方法供其它应用调用,用于往数据库中插入数据</span></span><br><span class="line"><span class="comment">//values: 由其它应用传入,用于封装要插入的数据</span></span><br><span class="line"><span class="comment">//uri: 内容提供者的访问地址</span></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> Uri <span class="title">insert</span><span class="params">(Uri uri, ContentValues values)</span> </span>{</span><br><span class="line"> db = mOpenHelper.getWritableDatabase();</span><br><span class="line"> <span class="comment">//使用Uri匹配器匹配传入的uri,匹配的话会返回定义好的匹配码</span></span><br><span class="line"> <span class="keyword">switch</span>(uriMatcher.match(uri)){</span><br><span class="line"> <span class="keyword">case</span> INSERT:</span><br><span class="line"> <span class="keyword">long</span> id = db.insert(<span class="string">"person"</span>, <span class="keyword">null</span>, values);</span><br><span class="line"> <span class="keyword">return</span> ContentUris.withAppendedId(uri, id);</span><br><span class="line"> <span class="keyword">default</span>:</span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> RuntimeException(<span class="string">"Uri not match"</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">delete</span><span class="params">(Uri uri, String selection, String[] selectionArgs)</span></span>{</span><br><span class="line"><span class="keyword">int</span> i = db.delete(<span class="string">"person"</span>, selection, selectionArgs);</span><br><span class="line"><span class="keyword">return</span> i;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">update</span><span class="params">(Uri uri, ContentValues values, String selection, String[] selectionArgs)</span></span>{</span><br><span class="line"><span class="keyword">int</span> i = db.update(<span class="string">"person"</span>, values, selection, selectionArgs);</span><br><span class="line"><span class="keyword">return</span> i;</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p><h3 id="ContentResolver-内容访问者-访问内容提供者"><a href="#ContentResolver-内容访问者-访问内容提供者" class="headerlink" title="ContentResolver 内容访问者(访问内容提供者)"></a>ContentResolver 内容访问者(访问内容提供者)</h3><p>若要访问的内容提供者需要权限,则要在配置文件中声明相应的权限。<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">private</span> ContentResolver resolver;</span><br><span class="line"><span class="keyword">private</span> Uri uri;</span><br><span class="line"><span class="comment">//要访问的内容提供者的Uri前缀</span></span><br><span class="line">String authorities = <span class="string">"content://com.example.myProvider"</span>;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onCreate</span><span class="params">(Bundle savedInstanceState)</span> </span>{</span><br><span class="line"> <span class="keyword">super</span>.onCreate(savedInstanceState);</span><br><span class="line"> setContentView(R.layout.main);</span><br><span class="line"></span><br><span class="line"> resolver=getContentResolver();</span><br><span class="line"> <span class="comment">//insert();</span></span><br><span class="line"> <span class="comment">//delete();</span></span><br><span class="line"> <span class="comment">//update();</span></span><br><span class="line"> queryAll();</span><br><span class="line"> queryItem();</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">insert</span><span class="params">()</span></span>{</span><br><span class="line">ContentValues values = <span class="keyword">new</span> ContentValues();</span><br><span class="line">values.put(<span class="string">"name"</span>, <span class="string">"Jack"</span>);</span><br><span class="line">values.put(<span class="string">"money"</span>, <span class="string">"13000"</span>);</span><br><span class="line"><span class="comment">//url: 访问内容提供者的向数据库中插入数据的地址</span></span><br><span class="line">resolver.insert(Uri.parse(authorities + <span class="string">"/person/insert"</span>), values);;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">delete</span><span class="params">()</span></span>{</span><br><span class="line">resolver.delete(Uri.parse(<span class="string">"content://内容提供者的唯一标识符"</span>), <span class="string">"name = ?"</span>,</span><br><span class="line"><span class="keyword">new</span> String[]{<span class="string">"Jack"</span>});</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">update</span><span class="params">()</span></span>{</span><br><span class="line">ContentValues values = <span class="keyword">new</span> ContentValues();</span><br><span class="line">values.put(<span class="string">"name"</span>, <span class="string">"hello"</span>);</span><br><span class="line">resolver.update(Uri.parse(<span class="string">"content://内容提供者的唯一标识符"</span>), values,</span><br><span class="line"><span class="string">"name = ?"</span>, <span class="keyword">new</span> String[]{<span class="string">"Jack"</span>});</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">queryAll</span><span class="params">()</span></span>{</span><br><span class="line"> uri = Uri.parse(<span class="string">"content://com.example.myProvider/person/queryAll"</span>);</span><br><span class="line"> Cursor c = resolver.query(uri,<span class="keyword">new</span> String[]{<span class="string">"name"</span>, <span class="string">"age"</span>},</span><br><span class="line"> <span class="keyword">null</span>, <span class="keyword">null</span>, <span class="string">"age desc"</span>);</span><br><span class="line"> <span class="keyword">if</span>(c != <span class="keyword">null</span> && c.getCount() > <span class="number">0</span>) {</span><br><span class="line"> <span class="keyword">while</span> (c.moveToNext()) {</span><br><span class="line"> Log.i(<span class="string">"query from resolver"</span>, c.getString(<span class="number">0</span>) + <span class="string">" "</span> + c.getInt(<span class="number">1</span>));</span><br><span class="line"> }</span><br><span class="line"> c.close();</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">queryItem</span><span class="params">()</span></span>{</span><br><span class="line"> uri = Uri.parse(<span class="string">"content://com.example.myProvider/person/queryItem/#"</span>);</span><br><span class="line"> <span class="comment">//在Uri末尾添加一个id,把Uri末尾的#替换为id</span></span><br><span class="line"> uri = ContentUris.withAppendedId(uri,<span class="number">1</span>);</span><br><span class="line"> Cursor c = resolver.query(uri, <span class="keyword">new</span> String[]{<span class="string">"_id"</span>, <span class="string">"name"</span>, <span class="string">"age"</span>},</span><br><span class="line"> <span class="keyword">null</span>, <span class="keyword">null</span>, <span class="string">"age desc"</span>);</span><br><span class="line"> <span class="keyword">if</span>(c != <span class="keyword">null</span> && c.moveToFirst()) {</span><br><span class="line"> <span class="keyword">int</span> id = c.getInt(<span class="number">0</span>);</span><br><span class="line"> String name = c.getString(<span class="number">1</span>);</span><br><span class="line"> <span class="keyword">int</span> age = c.getInt(<span class="number">2</span>);</span><br><span class="line"> Log.i(<span class="string">"queryItem from reslover"</span>, id + <span class="string">" "</span> + name + <span class="string">" "</span> + age);</span><br><span class="line"> c.close();</span><br><span class="line"> }<span class="keyword">else</span> {</span><br><span class="line"> Log.i(<span class="string">"queryItem from reslover"</span>, <span class="string">"null"</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p><h3 id="备份短信"><a href="#备份短信" class="headerlink" title="备份短信"></a>备份短信</h3><p>1.清单文件中添加读取短信的权限<br>2.定义一个短信的 Java Bean 类 Message<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">List<Message> smsList = <span class="keyword">new</span> ArrayList<Message>();</span><br><span class="line">ContentResolver cr = getContentResolver();</span><br><span class="line">Uri uri = Uri.parse(<span class="string">"content://sms"</span>);</span><br><span class="line">Cursor cursor = cr.query(uri, <span class="keyword">new</span> String[]{<span class="string">"address"</span>, <span class="string">"date"</span>, <span class="string">"body"</span>, <span class="string">"type"</span>},</span><br><span class="line"> <span class="keyword">null</span>, <span class="keyword">null</span>, <span class="keyword">null</span>);</span><br><span class="line"><span class="keyword">while</span>(cursor.moveToNext()){</span><br><span class="line">String address = cursor.getString(<span class="number">0</span>);</span><br><span class="line"><span class="keyword">long</span> date = cursor.getLong(<span class="number">1</span>);</span><br><span class="line">String body = cursor.getString(<span class="number">2</span>);</span><br><span class="line">String type = cursor.getString(<span class="number">3</span>);</span><br><span class="line"></span><br><span class="line">Message sms = <span class="keyword">new</span> Message();</span><br><span class="line">smsList.add(sms);</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p><h3 id="插入短信"><a href="#插入短信" class="headerlink" title="插入短信"></a>插入短信</h3><p>清单文件中添加写短信与读短信的权限<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">ContentResolver cr = getContentResolver();</span><br><span class="line">ContentValues values = <span class="keyword">new</span> ContentValues();</span><br><span class="line">values.put(<span class="string">"address"</span>, <span class="number">23423</span>);</span><br><span class="line">values.put(<span class="string">"type"</span>, <span class="number">1</span>);</span><br><span class="line">values.put(<span class="string">"date"</span>, System.currentTimeMillis());</span><br><span class="line">values.put(<span class="string">"body"</span>, <span class="string">"hello, hhhh"</span>);</span><br><span class="line">Uri uri = Uri.parse(<span class="string">"content://sms"</span>);</span><br><span class="line">cr.insert(uri, valuse);</span><br></pre></td></tr></table></figure></p><h3 id="获取系统联系人"><a href="#获取系统联系人" class="headerlink" title="获取系统联系人"></a>获取系统联系人</h3><ol><li>raw_contacts 表<br> contact_id: 联系人 id</li><li>data 表<br> 存放联系人的详细信息,每行数据存放联系人单独的一条信息<br> data1: 联系人具体信息<br> raw_contact_id: 该行信息属于哪个联系人<br> mimetype_id: 该行信息属于什么类型<br> 注意:实际查询的时候,并不能直接查询mimetype_id字段,而是查询mimetype字段</li><li>mimetypes 表<br> 对应类型的字符串</li></ol><p>清单文件中添加相应的权限<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line">ContentResolver cr = getContentResolver();</span><br><span class="line">String authorities = <span class="string">"content://com.android.contacts"</span>;</span><br><span class="line">Cursor cursorContactId = cr.query(Uri.parse(authorities + <span class="string">"/raw_contacts"</span>), <span class="keyword">new</span> String[]{<span class="string">"contact_id"</span>}, <span class="keyword">null</span>, <span class="keyword">null</span>, <span class="keyword">null</span>);</span><br><span class="line"><span class="keyword">while</span>(cursorContactId.moveToNext()){</span><br><span class="line"><span class="comment">//获取联系人id</span></span><br><span class="line">String contactId = cursorContactId.getString(<span class="number">0</span>);</span><br><span class="line">Cursor cursorData = cr.query(Uri.parse(authorities + <span class="string">"/data"</span>,</span><br><span class="line"><span class="keyword">new</span> String[]{<span class="string">"data1"</span>, <span class="string">"raw_contact_id"</span>, <span class="string">"mimetype"</span>},</span><br><span class="line"><span class="string">"raw_contact_id = ?"</span>, <span class="keyword">new</span> String[]{contactId}, <span class="keyword">null</span>);</span><br><span class="line"><span class="comment">//获取所有字段的名字</span></span><br><span class="line">String[] names = cursorData.getColumnNames();</span><br><span class="line"></span><br><span class="line">Person person = <span class="keyword">new</span> Person();</span><br><span class="line">whilw(cursorData.moveToNext()){</span><br><span class="line">String data1 = cursorData.getString(<span class="number">0</span>);</span><br><span class="line">String mimetype = cursorData.getString(<span class="number">1</span>);</span><br><span class="line"><span class="keyword">if</span>(mimetype.equals(<span class="string">"vnd.android.cursor.item/email_v2"</span>)){</span><br><span class="line">person.setEmail(data1);</span><br><span class="line">}<span class="keyword">else</span> <span class="keyword">if</span>(mimetype.equals(<span class="string">"vnd.android.cursor.item/phone_v2"</span>)){</span><br><span class="line">person.setPhone(data1);</span><br><span class="line">}</span><br><span class="line"><span class="keyword">else</span> <span class="keyword">if</span>(mimetype.equals(<span class="string">"vnd.android.cursor.item/name"</span>)){</span><br><span class="line">person.setName(data1);</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p><h3 id="插入联系人"><a href="#插入联系人" class="headerlink" title="插入联系人"></a>插入联系人</h3><p>清单文件中添加相应的权限<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line">ContentResolver cr = getContentResolver();</span><br><span class="line">String authorities = <span class="string">"content://com.android.contacts"</span>;</span><br><span class="line"><span class="comment">//先查询raw_contacts表,获取最新联系人的主键,然后主键+1,就是要插入联系人的id</span></span><br><span class="line">Cursor cursorContactId = cr.query(Uri.parse(authorities + <span class="string">"/raw_contacts"</span>), <span class="keyword">new</span> String[]{<span class="string">"contact_id"</span>}, <span class="keyword">null</span>, <span class="keyword">null</span>, <span class="keyword">null</span>);</span><br><span class="line"><span class="comment">//默认联系人id为1</span></span><br><span class="line"><span class="keyword">int</span> contact_id = <span class="number">1</span>;</span><br><span class="line"><span class="keyword">while</span>(cursorContactId.moveToLast()){</span><br><span class="line"><span class="keyword">int</span> _id = cursorContactId.getInt(<span class="number">0</span>);</span><br><span class="line">contact_id = ++_id;</span><br><span class="line">}</span><br><span class="line">ContentValues values = <span class="keyword">new</span> ContentValues();</span><br><span class="line">values.put(<span class="string">"contact_id"</span>, contact_id);</span><br><span class="line">cr.insert(Uri.parse(authorities + <span class="string">"/raw_contacts"</span>), values);</span><br><span class="line"></span><br><span class="line">values.clear();</span><br><span class="line">values.put(<span class="string">"data1"</span>, <span class="string">"Jack"</span>);</span><br><span class="line">values.put(<span class="string">"raw_contact_id"</span>, contact_id);</span><br><span class="line">values.put(<span class="string">"mimetype"</span>, <span class="string">"vnd.android.cursor.item/name"</span>);</span><br><span class="line"></span><br><span class="line">values.clear();</span><br><span class="line">values.put(<span class="string">"data1"</span>, <span class="string">"hello@163.com"</span>);</span><br><span class="line">values.put(<span class="string">"raw_contact_id"</span>, contact_id);</span><br><span class="line">values.put(<span class="string">"mimetype"</span>, <span class="string">"vnd.android.cursor.item/email_v2"</span>);</span><br><span class="line"></span><br><span class="line">values.clear();</span><br><span class="line">values.put(<span class="string">"data1"</span>, <span class="string">"2453254532"</span>);</span><br><span class="line">values.put(<span class="string">"raw_contact_id"</span>, contact_id);</span><br><span class="line">values.put(<span class="string">"mimetype"</span>, <span class="string">"vnd.android.cursor.item/phone_v2"</span>);</span><br><span class="line">cr.insert(Uri.parse(authorities + <span class="string">"/data"</span>), values);</span><br></pre></td></tr></table></figure></p><h3 id="注册内容观察者"><a href="#注册内容观察者" class="headerlink" title="注册内容观察者"></a>注册内容观察者</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">ContentResolver cr = getContentResolver();</span><br><span class="line"><span class="comment">//notifyForDescendents: 如果是true,那么只要以 content://sms 开头的uri的数据改变,都能收到通知。</span></span><br><span class="line"><span class="comment">//比如 content://sms/inbox</span></span><br><span class="line">cr.registerContentObserver(Uri.parse(<span class="string">"content://sms"</span>),</span><br><span class="line"><span class="keyword">true</span>, <span class="keyword">new</span> MyObserver(<span class="keyword">new</span> Handler()));</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MyObserver</span> <span class="keyword">extends</span> <span class="title">ContentObserver</span></span>{</span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="title">MyObserver</span><span class="params">(Handler handler)</span></span>{</span><br><span class="line"><span class="keyword">super</span>(handler);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//收到数据改变的通知,调用此方法</span></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onChange</span><span class="params">(<span class="keyword">boolean</span> selfChange)</span></span>{</span><br><span class="line"><span class="keyword">super</span>.onChange(selfChange);</span><br><span class="line"><span class="comment">//读取短信数据库</span></span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="内容提供者中发送数据改变的通知"><a href="#内容提供者中发送数据改变的通知" class="headerlink" title="内容提供者中发送数据改变的通知"></a>内容提供者中发送数据改变的通知</h3><p>插入、删除、更新等数据改变的操作,发送数据改变的通知<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//uri: 通知发送到哪一个uri上,所有注册在这个uri上的内容观察者都可以收到这个通知</span></span><br><span class="line">getContext().getContentResolver().notifyChange(uri, <span class="keyword">null</span>);</span><br></pre></td></tr></table></figure></p>]]></content>
<summary type="html">
<h3 id="ContentProvider-内容提供者"><a href="#ContentProvider-内容提供者" class="headerlink" title="ContentProvider 内容提供者"></a>ContentProvider 内容提供者</h3><p>作用:把私有数据暴露给其它应用,通常是把私有数据库的数据暴露给其它应用</p>
<blockquote>
<p>ContentProvider作为安卓的四大组件之一,使用时首先要在配置清单文件中声明。<br>如果ContentProvider在清单文件中声明了权限,则同时要在配置清单中定义这个权限,同样,内容访问者要访问这个provider要首先声明相应的使用权限。</p>
</blockquote>
</summary>
<category term="android" scheme="http://jockio.github.io/categories/android/"/>
<category term="notes" scheme="http://jockio.github.io/categories/android/notes/"/>
<category term="android" scheme="http://jockio.github.io/tags/android/"/>
</entry>
<entry>
<title>用服务打造自定义音乐播放器</title>
<link href="http://jockio.github.io/2016/05/20/my-music-player/"/>
<id>http://jockio.github.io/2016/05/20/my-music-player/</id>
<published>2016-05-20T08:51:53.000Z</published>
<updated>2016-05-20T09:20:20.000Z</updated>
<content type="html"><![CDATA[<h2 id="自定义音乐播放器"><a href="#自定义音乐播放器" class="headerlink" title="自定义音乐播放器"></a>自定义音乐播放器</h2><p>本节通过服务与 SeekBar 的使用完成自定义音乐播放器项目<br>通过在 MusicService.java 文件中指定要播放音乐的路径,来选择播放网络上或者本地存储中的音乐。<br>注意:如果播放的是网络上的音乐,不要忘记在清单文件中添加访问网络的权限哦~<br><a id="more"></a></p><h2 id="布局文件"><a href="#布局文件" class="headerlink" title="布局文件"></a>布局文件</h2><p>activity_main.xml<br><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line"><?xml version="1.0" encoding="utf-8"?></span><br><span class="line"><span class="tag"><<span class="name">LinearLayout</span> <span class="attr">xmlns:android</span>=<span class="string">"http://schemas.android.com/apk/res/android"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">xmlns:tools</span>=<span class="string">"http://schemas.android.com/tools"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"match_parent"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:paddingBottom</span>=<span class="string">"@dimen/activity_vertical_margin"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:paddingLeft</span>=<span class="string">"@dimen/activity_horizontal_margin"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:paddingRight</span>=<span class="string">"@dimen/activity_horizontal_margin"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:paddingTop</span>=<span class="string">"@dimen/activity_vertical_margin"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:orientation</span>=<span class="string">"vertical"</span>></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">Button</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:id</span>=<span class="string">"@+id/play_button"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">style</span>=<span class="string">"@style/MyButtonStyle"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:text</span>=<span class="string">"@string/play"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:onClick</span>=<span class="string">"play"</span>/></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">Button</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:id</span>=<span class="string">"@+id/pause_button"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">style</span>=<span class="string">"@style/MyButtonStyle"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:text</span>=<span class="string">"@string/pause"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:onClick</span>=<span class="string">"pause"</span>/></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">Button</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:id</span>=<span class="string">"@+id/continue_button"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">style</span>=<span class="string">"@style/MyButtonStyle"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:text</span>=<span class="string">"@string/continue_button"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:onClick</span>=<span class="string">"continuePlay"</span>/></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">TextView</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:id</span>=<span class="string">"@+id/time_textview"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">style</span>=<span class="string">"@style/MyButtonStyle"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:text</span>=<span class="string">"time"</span>/></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">SeekBar</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:id</span>=<span class="string">"@+id/seekbar"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"wrap_content"</span> /></span></span><br><span class="line"><span class="tag"></<span class="name">LinearLayout</span>></span></span><br></pre></td></tr></table></figure></p><h2 id="主界面"><a href="#主界面" class="headerlink" title="主界面"></a>主界面</h2><p>MainActivity.java<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> android.content.ComponentName;</span><br><span class="line"><span class="keyword">import</span> android.content.Intent;</span><br><span class="line"><span class="keyword">import</span> android.content.ServiceConnection;</span><br><span class="line"><span class="keyword">import</span> android.os.Handler;</span><br><span class="line"><span class="keyword">import</span> android.os.IBinder;</span><br><span class="line"><span class="keyword">import</span> android.os.Message;</span><br><span class="line"><span class="keyword">import</span> android.support.v7.app.AppCompatActivity;</span><br><span class="line"><span class="keyword">import</span> android.os.Bundle;</span><br><span class="line"><span class="keyword">import</span> android.view.View;</span><br><span class="line"><span class="keyword">import</span> android.widget.SeekBar;</span><br><span class="line"><span class="keyword">import</span> android.widget.TextView;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.text.SimpleDateFormat;</span><br><span class="line"><span class="keyword">import</span> java.util.Calendar;</span><br><span class="line"><span class="keyword">import</span> java.util.Date;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MainActivity</span> <span class="keyword">extends</span> <span class="title">AppCompatActivity</span> </span>{</span><br><span class="line"> <span class="keyword">static</span> SeekBar seekBar;</span><br><span class="line"> <span class="keyword">static</span> TextView timeTextView;</span><br><span class="line"> <span class="keyword">static</span> Calendar calendar;</span><br><span class="line"> <span class="keyword">static</span> SimpleDateFormat simpleDateFormat = <span class="keyword">new</span> SimpleDateFormat(<span class="string">"mm:ss"</span>);</span><br><span class="line"> MusicInterface musicInterface;</span><br><span class="line"> Intent intent;</span><br><span class="line"> MyServiceConnection conn;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">static</span> Handler handler = <span class="keyword">new</span> Handler(){</span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">handleMessage</span><span class="params">(Message msg)</span> </span>{</span><br><span class="line"> <span class="keyword">super</span>.handleMessage(msg);</span><br><span class="line"> Bundle bundle = msg.getData();</span><br><span class="line"> <span class="keyword">int</span> max = bundle.getInt(<span class="string">"max"</span>);</span><br><span class="line"> <span class="keyword">int</span> position = bundle.getInt(<span class="string">"position"</span>);</span><br><span class="line"> seekBar.setMax(max);</span><br><span class="line"> seekBar.setProgress(position);</span><br><span class="line"></span><br><span class="line"> <span class="comment">//将毫秒转为相应的时间</span></span><br><span class="line"> calendar = Calendar.getInstance();</span><br><span class="line"> calendar.setTimeInMillis(max);</span><br><span class="line"> Date date = calendar.getTime();</span><br><span class="line"> String total = simpleDateFormat.format(date);</span><br><span class="line"></span><br><span class="line"> calendar.setTimeInMillis(position);</span><br><span class="line"> date = calendar.getTime();</span><br><span class="line"> simpleDateFormat = <span class="keyword">new</span> SimpleDateFormat(<span class="string">"mm:ss"</span>);</span><br><span class="line"> String current = simpleDateFormat.format(date);</span><br><span class="line"></span><br><span class="line"> timeTextView.setText(current + <span class="string">"/"</span> + total);</span><br><span class="line"> }</span><br><span class="line"> };</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">onCreate</span><span class="params">(Bundle savedInstanceState)</span> </span>{</span><br><span class="line"> <span class="keyword">super</span>.onCreate(savedInstanceState);</span><br><span class="line"> setContentView(R.layout.activity_main);</span><br><span class="line"></span><br><span class="line"> initView();</span><br><span class="line"></span><br><span class="line"> intent = <span class="keyword">new</span> Intent(<span class="keyword">this</span>, MusicService.class);</span><br><span class="line"> startService(intent);</span><br><span class="line"> conn = <span class="keyword">new</span> MyServiceConnection();</span><br><span class="line"> bindService(intent, conn, BIND_AUTO_CREATE);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">initView</span><span class="params">()</span></span>{</span><br><span class="line"> seekBar = (SeekBar) findViewById(R.id.seekbar);</span><br><span class="line"> seekBar.setOnSeekBarChangeListener(<span class="keyword">new</span> MyOnSeekBarChangeListener());</span><br><span class="line"> timeTextView= (TextView) findViewById(R.id.time_textview);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="class"><span class="keyword">class</span> <span class="title">MyOnSeekBarChangeListener</span> <span class="keyword">implements</span> <span class="title">SeekBar</span>.<span class="title">OnSeekBarChangeListener</span></span>{</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onProgressChanged</span><span class="params">(SeekBar seekBar, <span class="keyword">int</span> progress, <span class="keyword">boolean</span> fromUser)</span> </span>{</span><br><span class="line"></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onStartTrackingTouch</span><span class="params">(SeekBar seekBar)</span> </span>{</span><br><span class="line"></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 当滑动seekBar松开手后触发的事件</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> seekBar</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onStopTrackingTouch</span><span class="params">(SeekBar seekBar)</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> position = seekBar.getProgress();</span><br><span class="line"> musicInterface.seekTo(position);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="class"><span class="keyword">class</span> <span class="title">MyServiceConnection</span> <span class="keyword">implements</span> <span class="title">ServiceConnection</span></span>{</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onServiceConnected</span><span class="params">(ComponentName name, IBinder service)</span> </span>{</span><br><span class="line"> musicInterface = (MusicInterface) service;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onServiceDisconnected</span><span class="params">(ComponentName name)</span> </span>{</span><br><span class="line"></span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 开始播放音乐</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> v</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">play</span><span class="params">(View v)</span></span>{</span><br><span class="line"> musicInterface.play();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 暂停播放</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> v</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">pause</span><span class="params">(View v)</span></span>{</span><br><span class="line"> musicInterface.pause();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 继续播放</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> v</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">continuePlay</span><span class="params">(View v)</span></span>{</span><br><span class="line"> musicInterface.continuePlay();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 进程销毁后,解绑服务,停止服务</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">onDestroy</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">super</span>.onDestroy();</span><br><span class="line"> <span class="keyword">if</span>(conn != <span class="keyword">null</span>) {</span><br><span class="line"> unbindService(conn);</span><br><span class="line"> stopService(intent);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p><h2 id="自定义中间人接口"><a href="#自定义中间人接口" class="headerlink" title="自定义中间人接口"></a>自定义中间人接口</h2><p>MusicInterface.java<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">MusicInterface</span> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">void</span> <span class="title">play</span><span class="params">()</span></span>;</span><br><span class="line"> <span class="function"><span class="keyword">void</span> <span class="title">pause</span><span class="params">()</span></span>;</span><br><span class="line"> <span class="function"><span class="keyword">void</span> <span class="title">continuePlay</span><span class="params">()</span></span>;</span><br><span class="line"> <span class="function"><span class="keyword">void</span> <span class="title">seekTo</span><span class="params">(<span class="keyword">int</span> position)</span></span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p><h2 id="自定义服务"><a href="#自定义服务" class="headerlink" title="自定义服务"></a>自定义服务</h2><p>MusicService.java<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> android.app.Service;</span><br><span class="line"><span class="keyword">import</span> android.content.Intent;</span><br><span class="line"><span class="keyword">import</span> android.media.MediaPlayer;</span><br><span class="line"><span class="keyword">import</span> android.os.Binder;</span><br><span class="line"><span class="keyword">import</span> android.os.Bundle;</span><br><span class="line"><span class="keyword">import</span> android.os.IBinder;</span><br><span class="line"><span class="keyword">import</span> android.os.Message;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.io.IOException;</span><br><span class="line"><span class="keyword">import</span> java.util.Timer;</span><br><span class="line"><span class="keyword">import</span> java.util.TimerTask;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MusicService</span> <span class="keyword">extends</span> <span class="title">Service</span> </span>{</span><br><span class="line"> MediaPlayer player;</span><br><span class="line"> Timer timer;</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onCreate</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">super</span>.onCreate();</span><br><span class="line"> player = <span class="keyword">new</span> MediaPlayer();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onDestroy</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">super</span>.onDestroy();</span><br><span class="line"> <span class="keyword">if</span>(player != <span class="keyword">null</span>) {</span><br><span class="line"> player.stop();</span><br><span class="line"> player.release();</span><br><span class="line"> player = <span class="keyword">null</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span>(timer != <span class="keyword">null</span>){</span><br><span class="line"> timer.cancel();</span><br><span class="line"> timer = <span class="keyword">null</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> IBinder <span class="title">onBind</span><span class="params">(Intent intent)</span> </span>{</span><br><span class="line"> <span class="comment">// <span class="doctag">TODO:</span> Return the communication channel to the service.</span></span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">new</span> MusicController();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="class"><span class="keyword">class</span> <span class="title">MusicController</span> <span class="keyword">extends</span> <span class="title">Binder</span> <span class="keyword">implements</span> <span class="title">MusicInterface</span></span>{</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">play</span><span class="params">()</span> </span>{</span><br><span class="line"> MusicService.<span class="keyword">this</span>.play();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">pause</span><span class="params">()</span> </span>{</span><br><span class="line"> MusicService.<span class="keyword">this</span>.pause();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">continuePlay</span><span class="params">()</span> </span>{</span><br><span class="line"> MusicService.<span class="keyword">this</span>.continuePlay();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">seekTo</span><span class="params">(<span class="keyword">int</span> position)</span> </span>{</span><br><span class="line"> MusicService.<span class="keyword">this</span>.seekTo(position);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">play</span><span class="params">()</span></span>{</span><br><span class="line"> <span class="keyword">if</span>(player != <span class="keyword">null</span>) {</span><br><span class="line"> player.reset();</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> <span class="comment">//播放本地音乐</span></span><br><span class="line"> String path = getFilesDir() + <span class="string">"/gaobie.mp3"</span>;</span><br><span class="line"> <span class="comment">//播放网络音乐</span></span><br><span class="line"> <span class="comment">//String path = "http://www.hello.com/a.mp3";</span></span><br><span class="line"> player.setDataSource(path);</span><br><span class="line"> player.prepareAsync();</span><br><span class="line"> player.setOnPreparedListener(<span class="keyword">new</span> MediaPlayer.OnPreparedListener() {</span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onPrepared</span><span class="params">(MediaPlayer mp)</span> </span>{</span><br><span class="line"> mp.start();</span><br><span class="line"> addTimer();</span><br><span class="line"> }</span><br><span class="line"> });</span><br><span class="line"> } <span class="keyword">catch</span> (IOException e) {</span><br><span class="line"> e.printStackTrace();</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">pause</span><span class="params">()</span></span>{</span><br><span class="line"> player.pause();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">continuePlay</span><span class="params">()</span></span>{</span><br><span class="line"> player.start();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 播放指定位置的音乐</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> position</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">seekTo</span><span class="params">(<span class="keyword">int</span> position)</span></span>{</span><br><span class="line"> player.seekTo(position);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 添加计时器,周期性的执行run方法</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">addTimer</span><span class="params">()</span></span>{</span><br><span class="line"> <span class="keyword">if</span>(timer == <span class="keyword">null</span>){</span><br><span class="line"> timer = <span class="keyword">new</span> Timer();</span><br><span class="line"> }</span><br><span class="line"> timer.schedule(<span class="keyword">new</span> TimerTask() {</span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">run</span><span class="params">()</span> </span>{</span><br><span class="line"> Message msg = Message.obtain();</span><br><span class="line"> Bundle bundle = <span class="keyword">new</span> Bundle();</span><br><span class="line"> bundle.putInt(<span class="string">"max"</span>, player.getDuration());</span><br><span class="line"> bundle.putInt(<span class="string">"position"</span>, player.getCurrentPosition());</span><br><span class="line"> msg.setData(bundle);</span><br><span class="line"> MainActivity.handler.sendMessage(msg);</span><br><span class="line"> }</span><br><span class="line"> }, <span class="number">5</span>, <span class="number">500</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p><h2 id="最终效果"><a href="#最终效果" class="headerlink" title="最终效果"></a>最终效果</h2><p><img src="/images/musicPlayer.png" alt="MusicPlayer"></p>]]></content>
<summary type="html">
<h2 id="自定义音乐播放器"><a href="#自定义音乐播放器" class="headerlink" title="自定义音乐播放器"></a>自定义音乐播放器</h2><p>本节通过服务与 SeekBar 的使用完成自定义音乐播放器项目<br>通过在 MusicService.java 文件中指定要播放音乐的路径,来选择播放网络上或者本地存储中的音乐。<br>注意:如果播放的是网络上的音乐,不要忘记在清单文件中添加访问网络的权限哦~<br>
</summary>
<category term="android" scheme="http://jockio.github.io/categories/android/"/>
<category term="android" scheme="http://jockio.github.io/tags/android/"/>
</entry>
<entry>
<title>Android 系列笔记 九 - MediaPlayer</title>
<link href="http://jockio.github.io/2016/05/20/android-note-day09/"/>
<id>http://jockio.github.io/2016/05/20/android-note-day09/</id>
<published>2016-05-20T08:29:02.000Z</published>
<updated>2016-06-05T11:19:10.000Z</updated>
<content type="html"><![CDATA[<h3 id="图片大小的计算:图片的像素-每个像素所占的大小"><a href="#图片大小的计算:图片的像素-每个像素所占的大小" class="headerlink" title="图片大小的计算:图片的像素 * 每个像素所占的大小"></a>图片大小的计算:图片的像素 * 每个像素所占的大小</h3><ol><li>单色位图:只能表示两种颜色,使用两个数字 0 与 1 表示,使用一个长度为 1 的二进制数组就可以表示了,每个像素占用 1/8 个字节</li><li>16 色位图:能表示 16 种颜色,需要 16 个数字, 0 - 15, 0000 - 1111<br> 使用一个长度为 4 的二进制数组就能够表示了,每个像素占用 1/2 个字节<a id="more"></a></li><li>256 色位图:能表示 256 种颜色<br> 需要 256 个数字:0 - 255, 0000 0000 - 1111 1111<br> 使用一个长度为 8 的二进制数字<br> 每个像素占用 1 个字节</li><li>24 位位图<br> 每个像素占用 24 位,也就是 3 个字节,所以叫 24 位位图<br> R: 0 - 255<br> G: 0 - 255<br> B: 0 - 255</li></ol><h3 id="利用缩放加载大图片"><a href="#利用缩放加载大图片" class="headerlink" title="利用缩放加载大图片"></a>利用缩放加载大图片</h3><p>计算机把图片所有像素信息全部解析出来,保存至内存<br>Android 保存图片像素信息,是用 ARGB 保存的,每个像素占用 4 个字节<br>手机屏幕 320 x 480,总像素 153600<br>图片宽高 2400 x 3200,总像素 7680000<br>2400 / 320 = 7<br>3200 / 480 = 6<br>用大的数来缩放,这样才可以在屏幕上显示完整的图片<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">click</span><span class="params">(View v)</span></span>{</span><br><span class="line">Options opt = <span class="keyword">new</span> Options();</span><br><span class="line"><span class="comment">//不为像素申请内存,只获取图片宽高</span></span><br><span class="line">opt.inJustDecodeBounds = <span class="keyword">true</span>;</span><br><span class="line">BitmapFactory.decodeFile(<span class="string">"/sdcaed/dog.jpg"</span>, opt);</span><br><span class="line"><span class="keyword">int</span> width = opt.outWidth();</span><br><span class="line"><span class="keyword">int</span> height = opt.outHeight();</span><br><span class="line"></span><br><span class="line"><span class="comment">//获取屏幕宽高</span></span><br><span class="line">Display dp = getWindowManager().getDefaultDisplay();</span><br><span class="line"><span class="keyword">int</span> screenWidth = dp.getWidth();</span><br><span class="line"><span class="keyword">int</span> screenHeight = dp.getHeight();</span><br><span class="line"><span class="comment">//api 13 才能使用</span></span><br><span class="line"><span class="comment">//dp.getSize(new Point())</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//计算缩放比例</span></span><br><span class="line"><span class="keyword">int</span> scale = <span class="number">1</span>;</span><br><span class="line"><span class="keyword">int</span> scaleWidth = width / screenWidth;</span><br><span class="line"><span class="keyword">int</span> scaleHeight = height /screenHeight;</span><br><span class="line">scale = scaleWidth >= screenHeight ? scaleWidth : scaleHeight;</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span>(scaleWidth >= scaleHeight && scaleWidth >= <span class="number">1</span>){</span><br><span class="line">scale = scaleWidth;</span><br><span class="line">}<span class="keyword">else</span> <span class="keyword">if</span>(scaleWidth < scaleHeight && scaleHeight >= <span class="number">1</span>){</span><br><span class="line">scale = scaleHeight;</span><br><span class="line">}</span><br><span class="line"><span class="comment">//设置缩放比例</span></span><br><span class="line">opt.inSampleSize = scale;</span><br><span class="line">opt.inJustDecodeBounds = <span class="keyword">false</span>;</span><br><span class="line">Bitmap bm = BitmapFactory.decodeFile(<span class="string">"/sdcaed/dog.jpg"</span>, opt);</span><br><span class="line"></span><br><span class="line">imageView.setImageBitmap(bm);</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p><h3 id="创建图片副本"><a href="#创建图片副本" class="headerlink" title="创建图片副本"></a>创建图片副本</h3><p>在内存中创建一个图片的拷贝<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//这个对象是只读的</span></span><br><span class="line">Bitmap bm = BitmapFactory.decodeFile(<span class="string">"/sdcaed/dog.jpg"</span>);</span><br><span class="line"><span class="comment">//创建图片副本</span></span><br><span class="line"><span class="comment">//在内存中创建一个与原图一模一样大小的bitmap对象,里面还没有绘制任何内容</span></span><br><span class="line"><span class="comment">//该对象可读可写</span></span><br><span class="line">Bitmap bmCopy = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(), bm.getConfig());</span><br><span class="line"><span class="comment">//创建画笔</span></span><br><span class="line">Paint paint = <span class="keyword">new</span> Paint();</span><br><span class="line"><span class="comment">//创建画板对象</span></span><br><span class="line">Canvas canvas = <span class="keyword">new</span> Canvas(bmCopy);</span><br><span class="line"><span class="comment">//开始绘制</span></span><br><span class="line">canvas.drawBitmap(bm, <span class="keyword">new</span> Matrix(), paint);</span><br></pre></td></tr></table></figure></p><h3 id="简单特效处理"><a href="#简单特效处理" class="headerlink" title="简单特效处理"></a>简单特效处理</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">Matrix matrix = <span class="keyword">new</span> Matrix();</span><br><span class="line"><span class="comment">//平移 将顶点相对于bitmap平移至(20, 40)</span></span><br><span class="line">matrix.setTranslate(<span class="number">20</span>, <span class="number">40</span>);</span><br><span class="line"><span class="comment">//以图片右下角顶点缩放 宽放大两倍,高缩小到0.5倍</span></span><br><span class="line">matrix.setScale(<span class="number">2</span>, <span class="number">0.5f</span>);</span><br><span class="line"><span class="comment">//以图片中心点缩放 宽放大两倍,高缩小到0.5倍</span></span><br><span class="line">matrix.setScale(<span class="number">2</span>, <span class="number">0.5f</span>, bm.getWidth() /<span class="number">2</span>, bm.getHeight() / <span class="number">2</span>);</span><br><span class="line"><span class="comment">//旋转 相对左上角</span></span><br><span class="line">matrix.setRotate(<span class="number">45</span>);</span><br><span class="line"><span class="comment">//旋转中心点在中心</span></span><br><span class="line">matrix.setRotate(<span class="number">45</span>, bm.getWidth() /<span class="number">2</span>, bm.getHeight() /<span class="number">2</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">//镜面效果</span></span><br><span class="line">matrix.setScale(-<span class="number">1</span>, <span class="number">1</span>);</span><br><span class="line">matrix.postTranslate(bm.getWidth(), <span class="number">0</span>);</span><br><span class="line"><span class="comment">//倒影效果</span></span><br><span class="line">matrix.setScale(<span class="number">1</span>, -<span class="number">1</span>);</span><br><span class="line">matrix.postTranslate(<span class="number">0</span>, bm.getHeight());</span><br></pre></td></tr></table></figure><h3 id="触摸事件:画板"><a href="#触摸事件:画板" class="headerlink" title="触摸事件:画板"></a>触摸事件:画板</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line">Bitmap bm = BitmapFactory.decodeResources(getResources(), R.drawable.bg);</span><br><span class="line">Bitmap bmCopy = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(), bm.getConfig());</span><br><span class="line">Paint paint = <span class="keyword">new</span> Paint();</span><br><span class="line">paint.setColor(Color.RED);</span><br><span class="line">paint.setStrokeWidth(<span class="number">4</span>);</span><br><span class="line"><span class="comment">//创建画板对象</span></span><br><span class="line">Canvas canvas = <span class="keyword">new</span> Canvas(bmCopy);</span><br><span class="line"><span class="comment">//开始绘制</span></span><br><span class="line">canvas.drawBitmap(bm, <span class="keyword">new</span> Matrix(), paint);</span><br><span class="line">imageView.setImageBitmap(bmCopy);</span><br><span class="line"></span><br><span class="line">imageView.setOnTouchListener(<span class="keyword">new</span> OnTouchListener(){</span><br><span class="line"><span class="keyword">int</span> startX;</span><br><span class="line"><span class="keyword">int</span> startY;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">onTouch</span><span class="params">(View v, MotionEvent event)</span></span>{</span><br><span class="line"><span class="keyword">int</span> action = event.getAction();</span><br><span class="line"><span class="keyword">switch</span>(action){</span><br><span class="line"><span class="keyword">case</span> MotionEvent.ACTION_DOWN:</span><br><span class="line">startX = (<span class="keyword">int</span>)event.getX();</span><br><span class="line">startY = (<span class="keyword">int</span>)event.getY(); </span><br><span class="line"><span class="keyword">break</span>;</span><br><span class="line"><span class="keyword">case</span> MotionEvent.ACTION_MOVE:</span><br><span class="line"><span class="keyword">int</span> x = (<span class="keyword">int</span>)event.getX();</span><br><span class="line"><span class="keyword">int</span> y = (<span class="keyword">int</span>)event.getY();</span><br><span class="line">canvas.drawLine(startX, startY, x, y, paint);</span><br><span class="line">imageView.setImageBitmap(bmCopy);</span><br><span class="line">startX = x;</span><br><span class="line">startY = y;</span><br><span class="line"><span class="keyword">break</span>;</span><br><span class="line"><span class="keyword">case</span> MotionEvent.ACTION_UP:</span><br><span class="line"><span class="keyword">break</span>;</span><br><span class="line">}</span><br><span class="line"><span class="comment">//返回 true: 告诉系统,这个触摸事件由我处理</span></span><br><span class="line"><span class="comment">//返回 false: 告诉系统,这个事件我不处理,这时系统会把触摸事件传递给 imageView 的父节点</span></span><br><span class="line"><span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">}</span><br><span class="line">});</span><br></pre></td></tr></table></figure><h3 id="画板图片的保存"><a href="#画板图片的保存" class="headerlink" title="画板图片的保存"></a>画板图片的保存</h3><p>SD卡每次准备的时候,系统会遍历SD卡中的所有文件,系统会把所有的多媒体文件都放在一个MediaStore数据库中生成一个索引,数据库中保存了文件的文件名、路径、大小、长度、艺术家等。<br>图库、音乐、视频每次启动时,其实不会去遍历SD卡寻找多媒体文件,而是从MediaStore数据库中读取多媒体文件,通过库中的索引找到相对应的多媒体文件后,把文件显示在界面<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">File file = <span class="keyword">new</span> File(getFilesDir(), <span class="string">"zuopin.png"</span>);</span><br><span class="line">FileOutputStream fos = <span class="keyword">new</span> FileOutputStream(file);</span><br><span class="line">bmCopy.compress(CompressFormat.PNG, <span class="number">100</span>, fos);</span><br><span class="line"></span><br><span class="line">Intent intent = <span class="keyword">new</span> Intent();</span><br><span class="line">intent.setAction(Intent.ACTION_MEDIA_MOUNTED);</span><br><span class="line">intent.setData(Uri.fromFile(Environment.getExternalStorageDirectory()));</span><br><span class="line">sendBroadcast(intent);</span><br></pre></td></tr></table></figure></p><h3 id="播放网络音乐"><a href="#播放网络音乐" class="headerlink" title="播放网络音乐"></a>播放网络音乐</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">interface</span> <span class="title">MusicInterface</span></span>{</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">play</span><span class="params">()</span></span>;</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">pause</span><span class="params">()</span></span>;</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">continuePlay</span><span class="params">()</span></span>;</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">seekTo</span><span class="params">(<span class="keyword">int</span> position)</span></span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MusicService</span> <span class="keyword">extends</span> <span class="title">Service</span></span>{</span><br><span class="line">MediaPlayer mediaPlayer;</span><br><span class="line">Timer timer;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> IBinder <span class="title">onBind</span><span class="params">(Intent intent)</span></span>{</span><br><span class="line"><span class="keyword">return</span> <span class="keyword">new</span> MusicController();</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onCreate</span><span class="params">()</span></span>{</span><br><span class="line">mediaPlayer = <span class="keyword">new</span> MediaPlayer();</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onDestory</span><span class="params">()</span></span>{</span><br><span class="line"><span class="keyword">super</span>.onDestory();</span><br><span class="line">mediaPlayer.stop();</span><br><span class="line">mediaPlayer.release();</span><br><span class="line">mediaPlayer = <span class="keyword">null</span>;</span><br><span class="line"><span class="keyword">if</span>(timer != <span class="keyword">null</span>){</span><br><span class="line">timer.cancel();</span><br><span class="line">timer = <span class="keyword">null</span>;</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MusicController</span> <span class="keyword">extends</span> <span class="title">Binder</span> <span class="keyword">implements</span> <span class="title">MusicInterface</span></span>{</span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">play</span><span class="params">()</span></span>{</span><br><span class="line">MusicService.<span class="keyword">this</span>.play();</span><br><span class="line">}</span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">pause</span><span class="params">()</span></span>{</span><br><span class="line">MusicService.<span class="keyword">this</span>.pause();</span><br><span class="line">}</span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">continuePlay</span><span class="params">()</span></span>{</span><br><span class="line">MusicService.<span class="keyword">this</span>.continuePlay();</span><br><span class="line">}</span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">seekTo</span><span class="params">(<span class="keyword">int</span> position)</span></span>{</span><br><span class="line">MusicService.<span class="keyword">this</span>.seekTo(position);</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">play</span><span class="params">()</span></span>{</span><br><span class="line">musicPlayer.reset();</span><br><span class="line"><span class="keyword">try</span>{</span><br><span class="line"><span class="comment">//播放本地音乐</span></span><br><span class="line"><span class="comment">//musicPlayer.setDataSource(getFilesDir + "/a.mp3");</span></span><br><span class="line"><span class="comment">//musicPlayer.prepare();</span></span><br><span class="line"><span class="comment">//musicPlayer.start();</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//播放网络音乐</span></span><br><span class="line">musicPlayer.setDataSource(<span class="string">"http://hello.com/bzd.mp3"</span>);</span><br><span class="line">musicPlayer.prepareAsync();</span><br><span class="line">musicPlayer.setOnPreparedListener(<span class="keyword">new</span> OnPreparedListener(){</span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onPrepared</span><span class="params">(MediaPlayer player)</span></span>{</span><br><span class="line">player.start();</span><br><span class="line">addTimer();</span><br><span class="line">}</span><br><span class="line">});</span><br><span class="line">}<span class="keyword">catch</span>(Exception e){</span><br><span class="line">e.printStackTrace();</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">continuePlay</span><span class="params">()</span></span>{</span><br><span class="line">musicPlayer.start();</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">pause</span><span class="params">()</span></span>{</span><br><span class="line">musicPlayer.pause();</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">seekTo</span><span class="params">(<span class="keyword">int</span> position)</span></span>{</span><br><span class="line">musicPlayer.seekTo(position);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">addTimer</span><span class="params">()</span></span>{</span><br><span class="line"><span class="keyword">if</span>(timer == <span class="keyword">null</span>)</span><br><span class="line">timer = <span class="keyword">new</span> Timer();</span><br><span class="line">timer.schedule(<span class="keyword">new</span> TimerTask(){</span><br><span class="line"><span class="comment">//获取歌曲总时长</span></span><br><span class="line"><span class="keyword">int</span> duration = musicPlayer.getDuration();</span><br><span class="line"><span class="comment">//获取歌曲当前播放进度</span></span><br><span class="line"><span class="keyword">int</span> position = musicPlayer.getCurrentPosition();</span><br><span class="line">Message msg = Message.obtain();</span><br><span class="line">Bundle bundle = <span class="keyword">new</span> Bundle();</span><br><span class="line">bundle.putInt(<span class="string">"duration"</span>, duration);</span><br><span class="line">bundle.putInt(<span class="string">"position"</span>, position);</span><br><span class="line">msg.setData(bundle);</span><br><span class="line">MainActivity.handler.sendMessage(msg)</span><br><span class="line">}, <span class="number">5</span>, <span class="number">500</span>);<span class="comment">//开始计时任务后的5毫秒,第一次执行run方法,以后每500毫秒执行一次</span></span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MainActivity</span> <span class="keyword">extends</span> <span class="title">Activity</span></span>{</span><br><span class="line">MusicInterface <span class="class"><span class="keyword">interface</span></span>;</span><br><span class="line">MyServiceConnection conn;</span><br><span class="line">Intent intent;</span><br><span class="line"><span class="keyword">static</span> SeekBar seekBar;</span><br><span class="line"></span><br><span class="line"><span class="keyword">static</span> Handler handler =<span class="keyword">new</span> Handler(){</span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">handleMessage</span><span class="params">(Message msg)</span></span>{</span><br><span class="line">Bundle bundle = msg.getData();</span><br><span class="line"><span class="keyword">int</span> duration = bundle.getInt(<span class="string">"duration"</span>);</span><br><span class="line"><span class="keyword">int</span> position = bundle.getInt(<span class="string">"position"</span>);</span><br><span class="line">seekBar.setMax(duration);</span><br><span class="line">seekBar.setProgress(position);</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">onCreate</span><span class="params">(Bundle savedInstanceState)</span></span>{</span><br><span class="line"><span class="keyword">super</span>.onCreate(savedInstanceState);</span><br><span class="line">setContentView(R.layout.main);</span><br><span class="line"></span><br><span class="line">seekBar = (SeekBar)findViewById(R.id.seekbar);</span><br><span class="line">seekBar.setOnSeekBarChangeListener(<span class="keyword">new</span> MyOnSeekBarChangeListener());</span><br><span class="line"></span><br><span class="line">intent = <span class="keyword">new</span> Intent(<span class="keyword">this</span>, MusicService.class);</span><br><span class="line">startService(intent);</span><br><span class="line">conn = <span class="keyword">new</span> MyServiceConnection();</span><br><span class="line">bindService(intent, conn, BIND_AUTO_CREATE);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MyOnSeekBarChangeListener</span> <span class="keyword">implements</span> <span class="title">OnSeekBarChangeListener</span></span>{</span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onStopTrackingTouch</span><span class="params">(SeekBar seekBar)</span></span>{</span><br><span class="line"><span class="comment">//拖动seekBar后,改变播放进度</span></span><br><span class="line"><span class="keyword">int</span> position = seekBar.getProgress();</span><br><span class="line"><span class="class"><span class="keyword">interface</span>.<span class="title">seekTo</span>(<span class="title">position</span>)</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onStartTrackingTouch</span><span class="params">(SeekBar seekBar)</span></span>{</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onProgressChanged</span><span class="params">(SeekBar seekBar,</span></span></span><br><span class="line"><span class="function"><span class="params"><span class="keyword">int</span> progress, <span class="keyword">boolean</span> fromUser)</span></span>{</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MyServiceConnection</span> <span class="keyword">implements</span> <span class="title">ServiceConnection</span></span>{</span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onServiceConnected</span><span class="params">(ComponentName name, IBinder service)</span></span>{</span><br><span class="line"><span class="class"><span class="keyword">interface</span> </span>= (MusicInterface)service;</span><br><span class="line">}</span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onServiceDisconnected</span><span class="params">(ComponentName name)</span></span>{</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">play</span><span class="params">(View v)</span></span>{</span><br><span class="line"><span class="class"><span class="keyword">interface</span>.<span class="title">play</span>()</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">pause</span><span class="params">(View v)</span></span>{</span><br><span class="line"><span class="class"><span class="keyword">interface</span>.<span class="title">pause</span>()</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">continuePlay</span><span class="params">(View v)</span></span>{</span><br><span class="line"><span class="class"><span class="keyword">interface</span>.<span class="title">continuePlay</span>()</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//退出应用 并销毁服务</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">exit</span><span class="params">(View v)</span></span>{</span><br><span class="line">unbindService(conn);</span><br><span class="line">stopService(intent);</span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="播放视频-MediaPlayer-SurfaceView"><a href="#播放视频-MediaPlayer-SurfaceView" class="headerlink" title="播放视频 MediaPlayer + SurfaceView"></a>播放视频 MediaPlayer + SurfaceView</h3><p>双缓冲技术<br>重量级组件<br>只要不可见,就不会创建,可见时才会创建<br>只要不可见,就会销毁<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MainActivity</span> <span class="keyword">extends</span> <span class="title">Activity</span></span>{</span><br><span class="line">MediaPlayer player;</span><br><span class="line">SurfaceView sv;</span><br><span class="line"><span class="keyword">static</span> <span class="keyword">int</span> currentPosition;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">protected</span> coid <span class="title">onCreate</span><span class="params">(Bundle savedInstanceState)</span></span>{</span><br><span class="line"><span class="keyword">super</span>.onCreate(savedInstanceState);</span><br><span class="line">setContentView(R.layout.main);</span><br><span class="line"></span><br><span class="line">sv= (SurfaceView)findViewById(R.id.surfaceView);</span><br><span class="line"><span class="keyword">final</span> SurfaceHolder sh = sv.getHolder();</span><br><span class="line"></span><br><span class="line">sh.addCallback(<span class="keyword">new</span> Callback(){</span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">surfacceDestoryed</span><span class="params">(SurfaceHolder holder)</span></span>{</span><br><span class="line"><span class="keyword">if</span>(plyer != <span class="keyword">null</span>){</span><br><span class="line">currentPosition = player.getCurrentPosition();</span><br><span class="line">player.stop();</span><br><span class="line">player.release();</span><br><span class="line">player = <span class="keyword">null</span>;</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">surfacceCreated</span><span class="params">(SurfaceHolder holder)</span></span>{</span><br><span class="line"><span class="keyword">if</span>(player == <span class="keyword">null</span>){</span><br><span class="line">player = <span class="keyword">new</span> MediaPlayer();</span><br><span class="line">player.reset();</span><br><span class="line"><span class="keyword">try</span>{</span><br><span class="line">player.setDataSource(getFilesDir + <span class="string">"/a.mp4"</span>);</span><br><span class="line">palyer.setDisplay(holder);</span><br><span class="line">player.prepare();</span><br><span class="line">player.start();</span><br><span class="line">player.seekTo(currentPosition);</span><br><span class="line">}<span class="keyword">catch</span>(Exception e){</span><br><span class="line">e.printStackTrace();</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">surfacceChanged</span><span class="params">(SurfaceHolder holder,</span></span></span><br><span class="line"><span class="function"><span class="params"><span class="keyword">int</span> format, <span class="keyword">int</span> width, <span class="keyword">int</span> height)</span></span>{</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line">});</span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p><h3 id="VideoView"><a href="#VideoView" class="headerlink" title="VideoView"></a>VideoView</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//本地播放</span></span><br><span class="line">video.setVideoPath(getFilesDir + <span class="string">"/a.mp4"</span>);</span><br><span class="line">video.start();</span><br></pre></td></tr></table></figure><h3 id="FFMPEG"><a href="#FFMPEG" class="headerlink" title="FFMPEG"></a>FFMPEG</h3><p>开源免费的音视频编解码器</p><h3 id="Vitamio-视频播放第三方框架"><a href="#Vitamio-视频播放第三方框架" class="headerlink" title="Vitamio 视频播放第三方框架"></a>Vitamio 视频播放第三方框架</h3><p>封装了 FFMPEG 的视频播放框架<br>对外提供的 API 全部都是 java api<br>封装的有 VideoView<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//检测硬件是否支持 Vitamio 引擎</span></span><br><span class="line"><span class="keyword">if</span>(!LibsChecker.checkVitamioLibs(<span class="keyword">this</span>)){</span><br><span class="line"><span class="keyword">return</span>;</span><br><span class="line">}</span><br><span class="line">video.setVideoPath(getFilesDir + <span class="string">"/a.rmvb"</span>);</span><br><span class="line">video.start();</span><br><span class="line">video.setMediaController(<span class="keyword">new</span> MediaController(<span class="keyword">this</span>));</span><br></pre></td></tr></table></figure></p><h3 id="拍照与摄像"><a href="#拍照与摄像" class="headerlink" title="拍照与摄像"></a>拍照与摄像</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="title">image</span><span class="params">(View v)</span></span>{</span><br><span class="line">Intent intent = <span class="keyword">new</span> Intent();</span><br><span class="line">intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);</span><br><span class="line">File file = <span class="keyword">new</span> File(getFilesDir + <span class="string">"/a.jpg"</span>);</span><br><span class="line">intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));</span><br><span class="line">startActivityForResult(intent, <span class="number">10</span>);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">onActivityResult</span><span class="params">(<span class="keyword">int</span> requestCode, <span class="keyword">int</span> responseCode, Intent data)</span></span>{</span><br><span class="line"><span class="keyword">super</span>.onActivityResult(requestCode, responseCode, intent);</span><br><span class="line"><span class="keyword">if</span>(requestCode == <span class="number">10</span>){</span><br><span class="line"><span class="comment">//拍照成功</span></span><br><span class="line">}<span class="keyword">else</span> <span class="keyword">if</span>(requestCode == <span class="number">20</span>){</span><br><span class="line"><span class="comment">//摄像成功</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="title">video</span><span class="params">(View v)</span></span>{</span><br><span class="line">Intent intent = <span class="keyword">new</span> Intent();</span><br><span class="line">intent.setAction(MediaStore.ACTION_VIDEO_CAPTURE);</span><br><span class="line">File file = <span class="keyword">new</span> File(getFilesDir + <span class="string">"/a.3gp"</span>);</span><br><span class="line">intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));</span><br><span class="line"><span class="comment">//第二个属性 0: 低质 1: 高质</span></span><br><span class="line">intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, <span class="number">1</span>);</span><br><span class="line"></span><br><span class="line">startActivityForResult(intent, <span class="number">20</span>);</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h3 id="图片大小的计算:图片的像素-每个像素所占的大小"><a href="#图片大小的计算:图片的像素-每个像素所占的大小" class="headerlink" title="图片大小的计算:图片的像素 * 每个像素所占的大小"></a>图片大小的计算:图片的像素 * 每个像素所占的大小</h3><ol>
<li>单色位图:只能表示两种颜色,使用两个数字 0 与 1 表示,使用一个长度为 1 的二进制数组就可以表示了,每个像素占用 1/8 个字节</li>
<li>16 色位图:能表示 16 种颜色,需要 16 个数字, 0 - 15, 0000 - 1111<br> 使用一个长度为 4 的二进制数组就能够表示了,每个像素占用 1/2 个字节
</summary>
<category term="android" scheme="http://jockio.github.io/categories/android/"/>
<category term="notes" scheme="http://jockio.github.io/categories/android/notes/"/>
<category term="android" scheme="http://jockio.github.io/tags/android/"/>
</entry>
<entry>
<title>Android 系列笔记 八 - 服务</title>
<link href="http://jockio.github.io/2016/05/19/android-note-day08/"/>
<id>http://jockio.github.io/2016/05/19/android-note-day08/</id>
<published>2016-05-19T07:41:01.000Z</published>
<updated>2016-06-05T11:19:03.000Z</updated>
<content type="html"><![CDATA[<p>服务:长期后台运行的没有界面的组件<br>服务的目的:长期后台运行<br>系统不容易回收掉进程。即使回收了,内存充足的时候,会把进程重新创建。</p><h3 id="创建服务"><a href="#创建服务" class="headerlink" title="创建服务"></a>创建服务</h3><p>1.创建服务,并在清单文件中配置服务<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MyService</span> <span class="keyword">extends</span> <span class="title">Service</span></span>{</span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> IBinder <span class="title">onBind</span><span class="params">(Intent intent)</span></span>{</span><br><span class="line"><span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p><a id="more"></a><p>2.开启服务<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Intent intent = <span class="keyword">new</span> Intent(<span class="keyword">this</span>, MyService.class);</span><br><span class="line">startService(intent);</span><br></pre></td></tr></table></figure></p><p>3.关闭服务<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Intent intent = <span class="keyword">new</span> Intent(<span class="keyword">this</span>, MyService.class);</span><br><span class="line">stopService(intent);</span><br></pre></td></tr></table></figure></p><h3 id="进程分为5个等级的优先级:(从高到低)"><a href="#进程分为5个等级的优先级:(从高到低)" class="headerlink" title="进程分为5个等级的优先级:(从高到低)"></a>进程分为5个等级的优先级:(从高到低)</h3><blockquote><p>1.Foreground process 前台进程 用户正在玩的应用程序对应的进程<br>2.Visible process 可视进程 用户仍然可以看到这个进程的页面<br>3.Service process 服务进程 应用程序有一个服务组件在后台运行<br>4.Background process 后台进程 应用程序没有服务在运行 并且最小化(activity onStop)<br>5.Empty process 空进程 没有任何正在运行的activity 任务栈空了</p></blockquote><p>android系统进程管理是按照一定的规则的:<br>应用程序一旦被打开,通常情况下关闭后(清空任务栈)进程不会停止,方便下一次应用启动。<br>android系统有一套内存清理机制,按照优先级回收系统的内存。</p><h3 id="服务的生命周期"><a href="#服务的生命周期" class="headerlink" title="服务的生命周期"></a>服务的生命周期</h3><blockquote><p>onCreate():服务第一次创建时调用<br>onStartCommand():服务启动时调用<br>onDestory():服务销毁时调用</p></blockquote><h3 id="电话录音机"><a href="#电话录音机" class="headerlink" title="电话录音机"></a>电话录音机</h3><p>电话的状态<br>1.空闲状态<br>2.响铃状态<br>3.摘机状态(接听)<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">RecordService</span> <span class="keyword">extends</span> <span class="title">Service</span></span>{</span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> IBinder <span class="title">onBind</span><span class="params">(Intent intent)</span></span>{</span><br><span class="line"><span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onCreate</span><span class="params">()</span></span>{</span><br><span class="line"><span class="keyword">super</span>.onCreate();</span><br><span class="line">TelephonyManager tm = (TelephonyManager)getSystemServie(TELEPHONY_SERVICE);</span><br><span class="line"><span class="comment">//第二个参数决定监听什么内容</span></span><br><span class="line">tm.listen(<span class="keyword">new</span> MyListener(), PhoneStateListener.LISTEN_CALL_STATE);</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MyListener</span> <span class="keyword">extends</span> <span class="title">PhoneStateListener</span></span>{</span><br><span class="line"><span class="keyword">private</span> MediaRecorder recorder;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line">onCallStateChanged(<span class="keyword">int</span> state, String incomingNumber){</span><br><span class="line"><span class="keyword">super</span>.onCallStateChanged(state, incomingNumber);</span><br><span class="line"><span class="keyword">switch</span>(state){</span><br><span class="line"><span class="keyword">case</span> TelephonyManager.CALL_STATE_IDLE:</span><br><span class="line"><span class="keyword">if</span>(recorder != <span class="keyword">null</span>){</span><br><span class="line">recorder.stop();</span><br><span class="line">recorder.release();</span><br><span class="line">recorder = <span class="keyword">null</span>;</span><br><span class="line">}</span><br><span class="line"><span class="keyword">break</span>;</span><br><span class="line"><span class="keyword">case</span> TelephonyManager.CALL_STATE_RINGING:</span><br><span class="line"><span class="comment">//初始化录音机</span></span><br><span class="line"><span class="keyword">if</span>(recorder == <span class="keyword">null</span>){</span><br><span class="line">recorder = <span class="keyword">new</span> MediaRecorder();</span><br><span class="line">recorder.setAudioSource(MediaRecorder.AudioSource.MIC);</span><br><span class="line">recorder.setOutFormat(MediaRecorder.OutputFormat.THREE_GPP);</span><br><span class="line">recorder.setOutputFile(getFilesDir().getPath() + <span class="string">"/recorder.3gp"</span>);</span><br><span class="line">recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);</span><br><span class="line"><span class="keyword">try</span>{</span><br><span class="line">recorder.prepare();</span><br><span class="line">}<span class="keyword">catch</span>(Exception e){</span><br><span class="line">e.printStackTrace();</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"><span class="keyword">break</span>;</span><br><span class="line"><span class="keyword">case</span> TelephonyManager.CALL_STATE_OFFHOOK:</span><br><span class="line"><span class="comment">//开始录音</span></span><br><span class="line">recorder.start();</span><br><span class="line"><span class="keyword">break</span>;</span><br><span class="line"><span class="keyword">default</span>:</span><br><span class="line"><span class="keyword">break</span>;</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p><h3 id="服务的两种启动方式及生命周期"><a href="#服务的两种启动方式及生命周期" class="headerlink" title="服务的两种启动方式及生命周期"></a>服务的两种启动方式及生命周期</h3><ol><li>startService(): 启动服务所在的进程属于服务进程<br>activity一旦启动服务,服务就跟activity没有关系了<br>onCreate()->onStartCommand()->onDestory()</li><li>bindService(): 启动服务所在的进程不属于服务进程<br>activity一旦与服务建立连接,activity销毁,服务也会销毁</li></ol><p>自定义一个接口:<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">interface</span> <span class="title">Person</span></span>{</span><br><span class="line"><span class="comment">//定义公共访问的方法</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">visitService</span><span class="params">()</span></span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p><p>在Activity中代码:<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line">MyServiceConnection conn;</span><br><span class="line">Intent intent;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onCreate</span><span class="params">(Bundle onSavedInstanceStste)</span></span>{</span><br><span class="line"><span class="keyword">super</span>.onCreate(onSavedInstanceStste);</span><br><span class="line">setContentView(R.layout.main);</span><br><span class="line">intent = <span class="keyword">new</span> Intent(<span class="keyword">this</span>, MyService.class);</span><br><span class="line"></span><br><span class="line">conn = <span class="keyword">new</span> MyServiceConnection();</span><br><span class="line">bindService(intent, conn, BIND_AUTO_CREATE);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">bind</span><span class="params">(View v)</span></span>{</span><br><span class="line"><span class="comment">//绑定服务 onCreate()->onBind()</span></span><br><span class="line">bindService(intent, conn, BIND_AUTO_CREATE);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">unbind</span><span class="params">(View v)</span></span>{</span><br><span class="line"><span class="comment">//解绑服务 onUnbind()->onDestory()</span></span><br><span class="line">unbindService(conn);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">Person p;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">click</span><span class="params">(View v)</span></span>{</span><br><span class="line">p.visitService();</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MyServiceConnection</span> <span class="keyword">implements</span> <span class="title">ServiceConnection</span></span>{</span><br><span class="line"><span class="comment">//连接服务成功,第二个参数即为中间人对象</span></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onServiceConnected</span><span class="params">(ComponentName name, IBinder service)</span></span>{</span><br><span class="line">p = (Person)service;</span><br><span class="line">}</span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onServiceDisconnected</span><span class="params">(ComponentName name)</span></span>{</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p><p>自定义Service中代码:<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MyService</span> <span class="keyword">extends</span> <span class="title">Service</span></span>{</span><br><span class="line"><span class="comment">//绑定时调用</span></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> IBinder <span class="title">onBind</span><span class="params">(Intent intent)</span></span>{</span><br><span class="line"><span class="comment">//返回一个Binder对象,即中间人对象</span></span><br><span class="line"><span class="keyword">return</span> <span class="keyword">new</span> XiaoLi();</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//创建内部类作为中间人,来访问服务中方法</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">XiaoLi</span> <span class="keyword">extends</span> <span class="title">Binder</span> <span class="keyword">implements</span> <span class="title">Person</span></span>{</span><br><span class="line"><span class="comment">//实现接口中用于公共访问的方法</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">visitService</span><span class="params">()</span></span>{</span><br><span class="line"><span class="comment">//访问service中的方法</span></span><br><span class="line">help();</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//自己的方法,不让外界访问</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">daMaJiang</span><span class="params">()</span></span>{</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//自定义服务的方法</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">help</span><span class="params">()</span></span>{</span><br><span class="line">System.out.println(<span class="string">"帮人办事"</span>);</span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p><h3 id="服务模拟音乐播放"><a href="#服务模拟音乐播放" class="headerlink" title="服务模拟音乐播放"></a>服务模拟音乐播放</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">interface</span> <span class="title">MusicInterface</span></span>{</span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">controlPlay</span><span class="params">()</span></span>;</span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">controlPause</span><span class="params">()</span></span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MainActivity</span> <span class="keyword">extends</span> <span class="title">Activity</span></span>{</span><br><span class="line">MusicServiceConnection conn;</span><br><span class="line">MusicInterface <span class="class"><span class="keyword">interface</span></span>;</span><br><span class="line">Intent intent;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onCreate</span><span class="params">(Bundle onSavedInstanceStste)</span></span>{</span><br><span class="line"><span class="keyword">super</span>.onCreate(onSavedInstanceStste);</span><br><span class="line">setContentView(R.layout.main);</span><br><span class="line">intent = <span class="keyword">new</span> Intent(<span class="keyword">this</span>, MusicService.class);</span><br><span class="line">conn = <span class="keyword">new</span> MusicServiceConnection();</span><br><span class="line"><span class="comment">//混合调用,为了把服务所在进程变为服务进程</span></span><br><span class="line">startService(intent);</span><br><span class="line"><span class="comment">//为了拿到中间人对象</span></span><br><span class="line">bindService(intent, conn, BIND_AUTO_CREATE);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">play</span><span class="params">(View v)</span></span>{</span><br><span class="line"><span class="class"><span class="keyword">interface</span>.<span class="title">controlPlay</span>()</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">pause</span><span class="params">(View v)</span></span>{</span><br><span class="line"><span class="class"><span class="keyword">interface</span>.<span class="title">controlPause</span>()</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MusicServiceConnection</span> <span class="keyword">implements</span> <span class="title">ServiceConnection</span></span>{</span><br><span class="line"><span class="comment">//连接服务成功,第二个参数即为中间人对象</span></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onServiceConnected</span><span class="params">(ComponentName name, IBinder service)</span></span>{</span><br><span class="line"><span class="class"><span class="keyword">interface</span> </span>= (MusicInterface)service;</span><br><span class="line">}</span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onServiceDisconnected</span><span class="params">(ComponentName name)</span></span>{</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MusicService</span> <span class="keyword">extends</span> <span class="title">Service</span></span>{</span><br><span class="line"><span class="comment">//绑定时调用</span></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> IBinder <span class="title">onBind</span><span class="params">(Intent intent)</span></span>{</span><br><span class="line"><span class="comment">//返回一个Binder对象,即中间人对象</span></span><br><span class="line"><span class="keyword">return</span> <span class="keyword">new</span> MusicController();</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MusicController</span> <span class="keyword">extends</span> <span class="title">Binder</span> <span class="keyword">implements</span> <span class="title">MusicInterface</span></span>{</span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">controlPlay</span><span class="params">()</span></span>{</span><br><span class="line">play();</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">controlPause</span><span class="params">()</span></span>{</span><br><span class="line">pause();</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">play</span><span class="params">()</span></span>{</span><br><span class="line">System.out.println(<span class="string">"开始播放音乐"</span>);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">pause</span><span class="params">()</span></span>{</span><br><span class="line">System.out.println(<span class="string">"暂停播放音乐"</span>);</span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="服务的混合调用"><a href="#服务的混合调用" class="headerlink" title="服务的混合调用"></a>服务的混合调用</h3><p>onCreate()->onStartCommand()->onBind()->onUnbind()->onDestory()</p><h3 id="使用代码配置广播接收者"><a href="#使用代码配置广播接收者" class="headerlink" title="使用代码配置广播接收者"></a>使用代码配置广播接收者</h3><ol><li>使用清单文件注册<br>广播一旦发出,系统就会去所有清单文件中寻找哪个广播接收者的action和广播的action是匹配的。如果找到了,就会把该广播接收者的进程启动起来</li><li>使用代码注册<br>需要使用广播接收者时,执行注册的代码;不需要时,解除注册</li></ol><h3 id="特殊的广播接收者"><a href="#特殊的广播接收者" class="headerlink" title="特殊的广播接收者"></a>特殊的广播接收者</h3><p>安卓中有一些广播接收者,必须使用代码注册,清单文件注册是无效的<br>1). 屏幕锁屏与解锁<br>2). 电量改变</p><h4 id="使用服务注册广播接收者"><a href="#使用服务注册广播接收者" class="headerlink" title="使用服务注册广播接收者"></a>使用服务注册广播接收者</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ScreenReceiver</span> <span class="keyword">extends</span> <span class="title">BroadcastReceiver</span></span>{</span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onReceive</span><span class="params">(Context context, Intent intent)</span></span>{</span><br><span class="line">String action = intent.getAction();</span><br><span class="line"><span class="keyword">if</span>(Intent.ACTION_SCREEN_ON,equals(action)){</span><br><span class="line"><span class="comment">//do something</span></span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>自定义服务代码中:<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> MyService extends Service{</span><br><span class="line">ScreenReceiver receiver;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> IBinder <span class="title">onBind</span><span class="params">(Intent intent)</span></span>{</span><br><span class="line"><span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onCreate</span><span class="params">()</span></span>{</span><br><span class="line"><span class="keyword">super</span>.onCreate();</span><br><span class="line"><span class="comment">//创建广播接收者</span></span><br><span class="line">receiver = <span class="keyword">new</span> ScreenReceiver();</span><br><span class="line"><span class="comment">//创建intent-filter</span></span><br><span class="line">IntentFilter filter= <span class="keyword">new</span> IntentFilter();</span><br><span class="line">filter.addAction(Intent.ACTION_SCREEN_ON);</span><br><span class="line">filter.addAction(Intent.ACTION_SCREEN_OFF);</span><br><span class="line"><span class="comment">//注册广播接收者</span></span><br><span class="line">registerReceiver(receiver, filter);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onDestory</span><span class="params">()</span></span>{</span><br><span class="line"><span class="keyword">super</span>.onDestory();</span><br><span class="line">unregisterReceiver(receiver);</span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p><h3 id="服务的分类"><a href="#服务的分类" class="headerlink" title="服务的分类"></a>服务的分类</h3><ol><li>本地服务<br> 服务与启动服务的activity在同一个进程中</li><li>远程服务<br> 服务与启动服务的activity不在同一个进程中</li></ol><h4 id="远程服务"><a href="#远程服务" class="headerlink" title="远程服务"></a>远程服务</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> MemoteService extends Service{</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> IBinder <span class="title">onBind</span><span class="params">(Intent intent)</span></span>{</span><br><span class="line"><span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onCreate</span><span class="params">()</span></span>{</span><br><span class="line"><span class="keyword">super</span>.onCreate();</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onDestory</span><span class="params">()</span></span>{</span><br><span class="line"><span class="keyword">super</span>.onDestory();</span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>启动远程服务<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">Intent intent = <span class="keyword">new</span> Intent();</span><br><span class="line">intent.setAction(<span class="string">"远程服务清单文件中配置的action"</span>);</span><br><span class="line"><span class="comment">//android 5.0 之后需要指定要启动的应用程序包名</span></span><br><span class="line">intent.setPackage(<span class="string">"com.jockio.learnandroid"</span>);</span><br><span class="line">startService(intent);</span><br></pre></td></tr></table></figure></p><h3 id="AIDL-进程间通信"><a href="#AIDL-进程间通信" class="headerlink" title="AIDL: 进程间通信"></a>AIDL: 进程间通信</h3><p>Android Interface Definition Language<br>步骤:</p><ol><li>将远程服务的方法抽取成一个单独的接口 java 文件</li><li>将接口文件的后缀名 java 改为 aidl, </li><li>在自动生成的接口 .java 文件中,有一个静态抽象类 Stub,它已经继承了 Binder 类,实现了抽取方法后的接口,这个类就是中间人</li><li>把 aidl 文件复制粘贴到要访问远程服务的项目中<br> 注意:aidl 包名跟原包名必须完全一致</li><li>在要访问远程服务的项目中,强转中间人对象时,直接使用 Stub.asInterface( Service service)</li></ol><h3 id="用-AIDL-模拟支付宝服务"><a href="#用-AIDL-模拟支付宝服务" class="headerlink" title="用 AIDL 模拟支付宝服务"></a>用 AIDL 模拟支付宝服务</h3><p>PayInterface.aidl<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">interface</span> <span class="title">PayInterface</span></span>{</span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">pay</span><span class="params">()</span></span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">PayService</span> <span class="keyword">extends</span> <span class="title">Service</span></span>{</span><br><span class="line"><span class="comment">//绑定时调用</span></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> IBinder <span class="title">onBind</span><span class="params">(Intent intent)</span></span>{</span><br><span class="line"><span class="comment">//返回一个Binder对象,即中间人对象</span></span><br><span class="line"><span class="keyword">return</span> <span class="keyword">new</span> PayController();</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">PayController</span> <span class="keyword">extends</span> <span class="title">Stub</span></span>{</span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">pay</span><span class="params">()</span> <span class="keyword">throws</span> RemoteException</span>{</span><br><span class="line">PayService.<span class="keyword">this</span>.pay();</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">pay</span><span class="params">()</span></span>{</span><br><span class="line">System.out.println(<span class="string">"完成支付"</span>);</span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>远程调用模拟支付宝服务<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//把 PayInterface.aidl 文件复制粘贴到项目中</span></span><br><span class="line"><span class="comment">//注意:PayInterface.aidl 包名跟原包名必须完全一致</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MainActivity</span> <span class="keyword">extends</span> <span class="title">Activity</span></span>{</span><br><span class="line">PayServiceConnection conn;</span><br><span class="line">Intent intent;</span><br><span class="line">PayInterface <span class="class"><span class="keyword">interface</span></span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onCreate</span><span class="params">(Bundle onSavedInstanceStste)</span></span>{</span><br><span class="line"><span class="keyword">super</span>.onCreate(onSavedInstanceStste);</span><br><span class="line">setContentView(R.layout.main);</span><br><span class="line"></span><br><span class="line">intent = <span class="keyword">new</span> Intent();</span><br><span class="line">intent.setAction(<span class="string">"支付宝服务的action"</span>);</span><br><span class="line"><span class="comment">//android 5.0 之后需要指定要启动的应用程序包名</span></span><br><span class="line"> intent.setPackage(<span class="string">"com.jockio.learnandroid"</span>);</span><br><span class="line">conn = <span class="keyword">new</span> PayServiceConnection();</span><br><span class="line"><span class="comment">//混合调用,为了把服务所在进程变为服务进程</span></span><br><span class="line">startService(intent);</span><br><span class="line"><span class="comment">//为了拿到中间人对象</span></span><br><span class="line">bindService(intent, conn, BIND_AUTO_CREATE);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">click</span><span class="params">(View v)</span></span>{</span><br><span class="line"><span class="class"><span class="keyword">interface</span>.<span class="title">pay</span>()</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">PayServiceConnection</span> <span class="keyword">implements</span> <span class="title">ServiceConnection</span></span>{</span><br><span class="line"><span class="comment">//连接服务成功,第二个参数即为中间人对象</span></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onServiceConnected</span><span class="params">(ComponentName name, IBinder service)</span></span>{</span><br><span class="line"><span class="class"><span class="keyword">interface</span> </span>= Stub.asInterface(service);</span><br><span class="line">}</span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onServiceDisconnected</span><span class="params">(ComponentName name)</span></span>{</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p><h3 id="进程优先级补充"><a href="#进程优先级补充" class="headerlink" title="进程优先级补充"></a>进程优先级补充</h3><h4 id="前台进程"><a href="#前台进程" class="headerlink" title="前台进程"></a>前台进程</h4><ol><li>拥有一个正在与用户进行交互的activity(onResume方法调用)的进程</li><li>拥有一个与正在和用户交互的activity绑定的服务的进程</li><li>拥有一个正在“运行于前台”的服务–服务的startForeground方法调用</li><li>拥有一个正在执行以下三个生命周期方法中任意一个的服务<br> onCreate() onStart() onDestory</li><li>拥有一个正在执行 onReceive 方法的广播接收者的进程</li></ol><h4 id="可见进程"><a href="#可见进程" class="headerlink" title="可见进程"></a>可见进程</h4><ol><li>拥有一个不在前台,但是用户依然可见的activity(onPause方法调用)的进程</li><li>拥有一个与可见(或前台)activity绑定的服务的进程</li></ol><h3 id="样式与主题"><a href="#样式与主题" class="headerlink" title="样式与主题"></a>样式与主题</h3><p>资源目录下,在 values 文件夹中,新建 styles.xml 文件<br><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><?xml version="1.0" encoding="utf-8"></span><br><span class="line"><resources></span><br><span class="line"><style name="myStyle"></span><br><span class="line"><item name="android:textSize">20sp</item></span><br><span class="line"></style></span><br><span class="line"><!--继承方式一--></span><br><span class="line"><style name="textviewStyle" parent="myStyle"/></span><br><span class="line"><!--继承方式二--></span><br><span class="line"><style name="myStyle.another"/></span><br><span class="line"></span><br><span class="line"><!--主题--></span><br><span class="line"><style name="themeStyle"></span><br><span class="line"><item name="android:background">#f0f0ff</item></span><br><span class="line"></style></span><br><span class="line"></resources></span><br></pre></td></tr></table></figure></p><p>布局文件中<br><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">TextView</span></span></span><br><span class="line"><span class="tag"><span class="attr">android:text</span>=<span class="string">"标题"</span></span></span><br><span class="line"><span class="tag"><span class="attr">style</span>=<span class="string">"@style/myStyle.another"</span>/></span></span><br></pre></td></tr></table></figure></p><h3 id="国际化"><a href="#国际化" class="headerlink" title="国际化"></a>国际化</h3><p>新建文件夹 values-en, 新建strings.xml<br><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><?xml version="1.0" encoding="utf-8"></span><br><span class="line"><resources></span><br><span class="line"><string name="app_name">hello</string></span><br><span class="line"></resources></span><br></pre></td></tr></table></figure></p><p>新建文件夹 values-zh, 新建strings.xml<br><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><?xml version="1.0" encoding="utf-8"></span><br><span class="line"><resources></span><br><span class="line"><string name="app_name">你好</string></span><br><span class="line"></resources></span><br></pre></td></tr></table></figure></p>]]></content>
<summary type="html">
<p>服务:长期后台运行的没有界面的组件<br>服务的目的:长期后台运行<br>系统不容易回收掉进程。即使回收了,内存充足的时候,会把进程重新创建。</p>
<h3 id="创建服务"><a href="#创建服务" class="headerlink" title="创建服务"></a>创建服务</h3><p>1.创建服务,并在清单文件中配置服务<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MyService</span> <span class="keyword">extends</span> <span class="title">Service</span></span>&#123;</span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> IBinder <span class="title">onBind</span><span class="params">(Intent intent)</span></span>&#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
</summary>
<category term="android" scheme="http://jockio.github.io/categories/android/"/>
<category term="notes" scheme="http://jockio.github.io/categories/android/notes/"/>
<category term="android" scheme="http://jockio.github.io/tags/android/"/>
</entry>
<entry>
<title>Android 系列笔记 七 - 广播</title>
<link href="http://jockio.github.io/2016/05/18/android-note-day07/"/>
<id>http://jockio.github.io/2016/05/18/android-note-day07/</id>
<published>2016-05-18T06:55:08.000Z</published>
<updated>2016-06-05T11:18:57.000Z</updated>
<content type="html"><![CDATA[<h3 id="获取打电话的广播"><a href="#获取打电话的广播" class="headerlink" title="获取打电话的广播"></a>获取打电话的广播</h3><p>1.在清单文件中配置receiver,指定要接收广播的类型,并添加相应的权限。<br><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">receiver</span> <span class="attr">android:name</span> = <span class="string">"包名+类名"</span>></span></span><br><span class="line"><span class="tag"><<span class="name">intent-filter</span>></span></span><br><span class="line"><span class="tag"><<span class="name">action</span> <span class="attr">android:name</span> = <span class="string">"android.intent.action.NEW_OUTGOING_CALL"</span>/></span>//外拨电话</span><br><span class="line"><span class="tag"></<span class="name">intent-filter</span>></span></span><br><span class="line"><span class="tag"></<span class="name">receiver</span>></span></span><br></pre></td></tr></table></figure></p><a id="more"></a><p>2.创建一个类继承自BrocastReceiver 并重写onReceive()方法,该方法在接收到广播的时候调用<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//在打电话广播中,会携带拨打电话的号码</span></span><br><span class="line">String phoneNumber = getResultData();<span class="comment">//获取数据</span></span><br><span class="line"><span class="comment">//把新的号码放到广播中</span></span><br><span class="line">setResultData(phoneNumber);</span><br></pre></td></tr></table></figure></p><p>即便广播接收者所在进程已经被关闭,当系统发送出的action跟该广播的action是匹配的,系统会启动该广播接收者所在的进程,并把广播发送给该广播接收者</p><h3 id="监听短信"><a href="#监听短信" class="headerlink" title="监听短信"></a>监听短信</h3><p>1.在清单文件中配置广播,并添加相应权限<br><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">receiver</span> <span class="attr">android:name</span> = <span class="string">"包名+类名"</span>></span></span><br><span class="line"><span class="tag"><<span class="name">intent-filter</span>></span></span><br><span class="line"><span class="tag"><<span class="name">action</span> <span class="attr">android:name</span> = <span class="string">"android.provider.Telephony.SMS_RECEIVED"</span>/></span></span><br><span class="line"><span class="tag"></<span class="name">intent-filter</span>></span></span><br><span class="line"><span class="tag"></<span class="name">receiver</span>></span></span><br></pre></td></tr></table></figure></p><p>2.创建一个类继承自BrocastReceiver 并重写onReceive()方法,该方法在接收到广播的时候调用<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">Object[] objs=intent.getExtras().get(<span class="string">"pdus"</span>);<span class="comment">//获得一组短信</span></span><br><span class="line"><span class="keyword">for</span>(Object obj:objs){</span><br><span class="line"><span class="comment">//得到短信对象</span></span><br><span class="line">SmsMessage smsMessage=SmsMessage.createFromPdu((<span class="keyword">byte</span>[])obj);</span><br><span class="line">String body=smsMessage.getMessageBody();</span><br><span class="line">String sender=smsMessage.getOriginatingAddress();</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p><blockquote><p>4.0之后,广播接收者所在进程如果从来没启动过,那么广播接收者不会生效<br>4.0之后,如果系统自动关闭广播接收者所在进程,在广播中的action跟该广播接收者的action匹配时,系统会启动该广播接收者所在的进程,但是如果是用户手动关闭该进程,那么该进程会进入冻结状态,再也不会启动,直到下一次用户手动启动该进程。</p></blockquote><h3 id="监控SD卡状态"><a href="#监控SD卡状态" class="headerlink" title="监控SD卡状态"></a>监控SD卡状态</h3><p>1.在清单文件中配置广播,并添加相应权限<br><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">receiver</span> <span class="attr">android:name</span> = <span class="string">"包名+类名"</span>></span></span><br><span class="line"><span class="tag"><<span class="name">intent-filter</span>></span></span><br><span class="line"><span class="tag"><<span class="name">action</span> <span class="attr">android:name</span> = <span class="string">"android.intent.action.MEDIA_MOUNTED"</span>/></span></span><br><span class="line"><span class="tag"><<span class="name">action</span> <span class="attr">android:name</span> = <span class="string">"android.intent.action.MEDIA_REMOVED"</span>/></span></span><br><span class="line"><span class="tag"><<span class="name">action</span> <span class="attr">android:name</span> = <span class="string">"android.intent.action.MEDIA_UNMOUNTED"</span>/></span></span><br><span class="line"><span class="tag"><<span class="name">data</span> <span class="attr">android:scheme</span> = <span class="string">"file"</span>/></span></span><br><span class="line"><span class="tag"></<span class="name">intent-filter</span>></span></span><br><span class="line"><span class="tag"></<span class="name">receiver</span>></span></span><br></pre></td></tr></table></figure></p><p>2.onReceive()<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//判断收到的是什么广播</span></span><br><span class="line">String action = intent.getAction();</span><br><span class="line"><span class="keyword">if</span>(action.equals(<span class="string">"android.intent.action.MEDIA_MOUNTED"</span>)){</span><br><span class="line">Toast.makeText(context, <span class="string">"SD卡可用"</span>, Toast.LENGTH_SHORT).show();</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p><h3 id="开机启动应用"><a href="#开机启动应用" class="headerlink" title="开机启动应用"></a>开机启动应用</h3><p>1.在清单文件中配置广播,并添加相应权限<br><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">receiver</span> <span class="attr">android:name</span> = <span class="string">"包名+类名"</span>></span></span><br><span class="line"><span class="tag"><<span class="name">intent-filter</span>></span></span><br><span class="line"><span class="tag"><<span class="name">action</span> <span class="attr">android:name</span> = <span class="string">"android.intent.action.BOOT_COMPLETED"</span>/></span></span><br><span class="line"><span class="tag"></<span class="name">intent-filter</span>></span></span><br><span class="line"><span class="tag"></<span class="name">receiver</span>></span></span><br></pre></td></tr></table></figure></p><p>2.onReceive()<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">Intent it = <span class="keyword">new</span> Intent(context, MainActivity.class);</span><br><span class="line"><span class="comment">//创建任务栈,存放启动的activity</span></span><br><span class="line">it.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);</span><br><span class="line">context.startActivity(it);</span><br></pre></td></tr></table></figure></p><h3 id="监控应用状态-安装、更新、卸载"><a href="#监控应用状态-安装、更新、卸载" class="headerlink" title="监控应用状态: 安装、更新、卸载"></a>监控应用状态: 安装、更新、卸载</h3><p>1.在清单文件中配置广播,并添加相应权限<br><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">receiver</span> <span class="attr">android:name</span> = <span class="string">"包名+类名"</span>></span></span><br><span class="line"><span class="tag"><<span class="name">intent-filter</span>></span></span><br><span class="line"><span class="tag"><<span class="name">action</span> <span class="attr">android:name</span> = <span class="string">"android.intent.action.PACKAGE_ADDED"</span>/></span></span><br><span class="line"><span class="tag"><<span class="name">action</span> <span class="attr">android:name</span> = <span class="string">"android.intent.action.PACKAGE_REPLACED"</span>/></span></span><br><span class="line"><span class="tag"><<span class="name">action</span> <span class="attr">android:name</span> = <span class="string">"android.intent.action.PACKAGE_REMOVED"</span>/></span></span><br><span class="line"><span class="tag"><<span class="name">data</span> <span class="attr">android:scheme</span> = <span class="string">"package"</span>/></span></span><br><span class="line"><span class="tag"></<span class="name">intent-filter</span>></span></span><br><span class="line"><span class="tag"></<span class="name">receiver</span>></span></span><br></pre></td></tr></table></figure></p><p>2.onReceive()<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//判断收到的是什么广播</span></span><br><span class="line">String action = intent.getAction();</span><br><span class="line"><span class="keyword">if</span>(action.equals(<span class="string">"android.intent.action.PACKAGE_ADDED"</span>)){</span><br><span class="line">Uri uri = intent.getData();</span><br><span class="line">Toast.makeText(context, uri.toString() + <span class="string">" 应用安装了"</span>, Toast.LENGTH_SHORT).show();</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p><h3 id="自定义广播"><a href="#自定义广播" class="headerlink" title="自定义广播"></a>自定义广播</h3><h4 id="发送自定义广播"><a href="#发送自定义广播" class="headerlink" title="发送自定义广播"></a>发送自定义广播</h4><p>一般都是隐式意图<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">Intent intent = <span class="keyword">new</span> Intent();</span><br><span class="line"><span class="comment">//自定义</span></span><br><span class="line">intent.setAction(<span class="string">"包名.动作"</span>);</span><br><span class="line">intent.putExtras(<span class="string">""</span>,<span class="string">""</span>);</span><br><span class="line">sendBroadcast(intent);</span><br></pre></td></tr></table></figure></p><h4 id="接收自定义广播"><a href="#接收自定义广播" class="headerlink" title="接收自定义广播"></a>接收自定义广播</h4><p>清单文件中配置广播接收者<br><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">receiver</span> <span class="attr">android:name</span> = <span class="string">"包名+类名"</span>></span></span><br><span class="line"><span class="tag"><<span class="name">intent-filter</span>></span></span><br><span class="line"><span class="tag"><<span class="name">action</span> <span class="attr">android:name</span> = <span class="string">"包名.动作"</span>/></span></span><br><span class="line"><span class="tag"></<span class="name">intent-filter</span>></span></span><br><span class="line"><span class="tag"></<span class="name">receiver</span>></span></span><br></pre></td></tr></table></figure></p><h3 id="发送无序广播"><a href="#发送无序广播" class="headerlink" title="发送无序广播"></a>发送无序广播</h3><p>没有顺序的广播,所有与广播中的action匹配的广播接收者都可以收到这条广播,并且是没有先后的顺序,视为同时收到<br><code>sendBroadcast(intent);//无序广播</code></p><h3 id="发送有序广播"><a href="#发送有序广播" class="headerlink" title="发送有序广播"></a>发送有序广播</h3><p>有顺序的广播,所有与广播中的action匹配的广播接收者都可以收到这条广播,但是是有先后的顺序,按照广播接收者的优先级排序<br><code>有序广播可以被拦截,可被终止,可以被修改数据</code><br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">Intent intent = <span class="keyword">new</span> Intent();</span><br><span class="line">intent.setAction(<span class="string">"it.java.fdm"</span>);</span><br><span class="line">sendOrderedBroadcast(intent,</span><br><span class="line"><span class="keyword">null</span>,<span class="comment">//第二个参数为接收广播需要的权限</span></span><br><span class="line"><span class="keyword">null</span>,<span class="comment">//最终的广播接收者,只接收该条广播并且一定可以收到,不需要在清单文件中配置</span></span><br><span class="line"><span class="keyword">null</span>,</span><br><span class="line"><span class="number">0</span>,</span><br><span class="line"><span class="string">"每人发100斤大米"</span>,</span><br><span class="line"><span class="keyword">null</span>);<span class="comment">//Bundle对象,携带数据</span></span><br><span class="line">sendBroadcast(intent);</span><br></pre></td></tr></table></figure></p><h3 id="有序广播接收者"><a href="#有序广播接收者" class="headerlink" title="有序广播接收者"></a>有序广播接收者</h3><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">receiver</span> <span class="attr">android:name</span> = <span class="string">"包名+类名"</span>></span></span><br><span class="line"><span class="tag"><<span class="name">intent-filter</span> <span class="attr">android:priority</span> = <span class="string">"1000"</span>></span></span><br><span class="line"><span class="tag"><<span class="name">action</span> <span class="attr">android:name</span> = <span class="string">"it.java.fdm"</span>/></span></span><br><span class="line"><span class="tag"></<span class="name">intent-filter</span>></span></span><br><span class="line"><span class="tag"></<span class="name">receiver</span>></span></span><br><span class="line"><span class="tag"><<span class="name">receiver</span> <span class="attr">android:name</span> = <span class="string">"包名+类名"</span>></span></span><br><span class="line"><span class="tag"><<span class="name">intent-filter</span> <span class="attr">android:priority</span> = <span class="string">"800"</span>></span></span><br><span class="line"><span class="tag"><<span class="name">action</span> <span class="attr">android:name</span> = <span class="string">"it.java.fdm"</span>/></span></span><br><span class="line"><span class="tag"></<span class="name">intent-filter</span>></span></span><br><span class="line"><span class="tag"></<span class="name">receiver</span>></span></span><br><span class="line"><span class="tag"><<span class="name">receiver</span> <span class="attr">android:name</span> = <span class="string">"包名+类名"</span>></span></span><br><span class="line"><span class="tag"><<span class="name">intent-filter</span> <span class="attr">android:priority</span> = <span class="string">"600"</span>></span></span><br><span class="line"><span class="tag"><<span class="name">action</span> <span class="attr">android:name</span> = <span class="string">"it.java.fdm"</span>/></span></span><br><span class="line"><span class="tag"></<span class="name">intent-filter</span>></span></span><br><span class="line"><span class="tag"></<span class="name">receiver</span>></span></span><br></pre></td></tr></table></figure><p>onReceive()中:<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">String data = getResultData();<span class="comment">//"每人发100斤大米"</span></span><br><span class="line">setResultData(<span class="string">"每人发120斤大米"</span>);<span class="comment">//修改数据</span></span><br></pre></td></tr></table></figure></p>]]></content>
<summary type="html">
<h3 id="获取打电话的广播"><a href="#获取打电话的广播" class="headerlink" title="获取打电话的广播"></a>获取打电话的广播</h3><p>1.在清单文件中配置receiver,指定要接收广播的类型,并添加相应的权限。<br><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">receiver</span> <span class="attr">android:name</span> = <span class="string">"包名+类名"</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">intent-filter</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">action</span> <span class="attr">android:name</span> = <span class="string">"android.intent.action.NEW_OUTGOING_CALL"</span>/&gt;</span>//外拨电话</span><br><span class="line"> <span class="tag">&lt;/<span class="name">intent-filter</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">receiver</span>&gt;</span></span><br></pre></td></tr></table></figure></p>
</summary>
<category term="android" scheme="http://jockio.github.io/categories/android/"/>
<category term="notes" scheme="http://jockio.github.io/categories/android/notes/"/>
<category term="android" scheme="http://jockio.github.io/tags/android/"/>
</entry>
<entry>
<title>Android 系列笔记 六</title>
<link href="http://jockio.github.io/2016/05/17/android-note-day06/"/>
<id>http://jockio.github.io/2016/05/17/android-note-day06/</id>
<published>2016-05-17T06:37:21.000Z</published>
<updated>2016-06-05T11:18:50.000Z</updated>
<content type="html"><![CDATA[<h3 id="页面跳转"><a href="#页面跳转" class="headerlink" title="页面跳转"></a>页面跳转</h3><p>activity只要配置为启动界面的intent_filter,就会生成应用图标与名称<br>隐式意图:通过指定的action与data<br>显式意图:直接指定目标activity的包名和类名<br><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"><!--给activity配置intent-filter--></span></span><br><span class="line"><span class="tag"><<span class="name">activity</span> <span class="attr">android:name</span>=<span class="string">".mainActivity"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">intent-filter</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">action</span> <span class="attr">android:name</span>=<span class="string">"com.java.intent"</span>/></span></span><br><span class="line"> <span class="tag"><<span class="name">category</span> <span class="attr">android:name</span>=<span class="string">"android.intent.category.DEFAULT"</span>/></span></span><br><span class="line"> <span class="tag"></<span class="name">intent-filter</span>></span></span><br><span class="line"><span class="tag"></<span class="name">activity</span>></span></span><br></pre></td></tr></table></figure></p><a id="more"></a><p>隐式意图<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">Intent intent = <span class="keyword">new</span> Intent();</span><br><span class="line">intent.setAction(<span class="string">"com.java.intent"</span>);</span><br><span class="line"><span class="comment">//下面两行代码不能共存</span></span><br><span class="line"><span class="comment">//intent.setData(Uri.parse(hello:123));</span></span><br><span class="line"><span class="comment">//intent.setType("text/username");</span></span><br><span class="line">intent.setDataAndType(Uri.parse(hello:<span class="number">123</span>), <span class="string">"text/username"</span>);</span><br><span class="line"><span class="comment">//若没有配置category,系统会自动添加默认的category</span></span><br><span class="line">intent.setCategory(Intent.CATEGORY_DEFAULT);</span><br><span class="line">Bundle bundle = <span class="keyword">new</span> Bundle();</span><br><span class="line">bundle.putString(<span class="string">"username"</span>, name);</span><br><span class="line">bundle.putString(<span class="string">"password"</span>, password);</span><br><span class="line">intent.putExtras(bundle);</span><br><span class="line">startActivity(intent);</span><br></pre></td></tr></table></figure></p><p>跳转后,获取数据<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">Intent intent = getIntent();</span><br><span class="line">Uri uri = intent.getData();</span><br><span class="line">String data = uri.toString();</span><br><span class="line">Bundle bundle = intent.getExtras();</span><br><span class="line">String username = bundle.get(<span class="string">"username"</span>);</span><br><span class="line">String password = bundle.get(<span class="string">"password"</span>);</span><br></pre></td></tr></table></figure></p><h3 id="显式、隐式意图-应用场景"><a href="#显式、隐式意图-应用场景" class="headerlink" title="显式、隐式意图 应用场景"></a>显式、隐式意图 应用场景</h3><blockquote><p>显式意图:启动用一个应用中的activity<br>隐式意图:启动不同应用中的activity<br>隐式意图效率要低于显式意图<br>如果系统中有多个activity与意图设置的action相匹配,那么在启动activity时会弹出对话框让用户选择启动哪一个应用。</p></blockquote><h3 id="返回activity时传递数据"><a href="#返回activity时传递数据" class="headerlink" title="返回activity时传递数据"></a>返回activity时传递数据</h3><p>应用场景:发送短信时,选择联系人<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">Intent intent = <span class="keyword">new</span> Intent();</span><br><span class="line">intent.putExtra(<span class="string">"name"</span>, <span class="string">"Jack"</span>);</span><br><span class="line"><span class="comment">//一旦这个activity被销毁,就会将结果返回给它的调用者,就是启动了这个activity的activity</span></span><br><span class="line">setResult(<span class="number">0</span>, intent);</span><br><span class="line"></span><br><span class="line"><span class="comment">//调用方</span></span><br><span class="line">Intent intent = <span class="keyword">new</span> Intent();</span><br><span class="line">intent.setClass(MainActivity.<span class="keyword">this</span>, Activity_2.class);</span><br><span class="line"><span class="comment">//第二个参数为请求码</span></span><br><span class="line">startActivityForResult(intent, <span class="number">0</span>);</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">onActivityResult</span><span class="params">(<span class="keyword">int</span> requestCode, <span class="keyword">int</span> resultCode, Intent data)</span></span>{</span><br><span class="line"><span class="keyword">super</span>.onActivityResult(requestCode, resultCode, data);</span><br><span class="line">data.getStringExtra(<span class="string">"name"</span>);</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p><h3 id="activity生命周期"><a href="#activity生命周期" class="headerlink" title="activity生命周期"></a>activity生命周期</h3><blockquote><p>完整生命周期:onCreate()->onStart()->onResume()->onPause()->onStop()->onDestory()<br>可视生命周期:onStart()->onResume()->onPause()->onStop()<br>前台生命周期:onResume()->onPause()<br>后台进入前台:onRestart()->onStart()->onResume()</p></blockquote><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">onCreate():被创建时调用的方法</span><br><span class="line">onStart():当activity界面用户可见时调用,但是没有获取焦点</span><br><span class="line">onResume():界面开始获取到焦点对应的方法。 (界面按钮可以被点击,文本框可以输入内容)</span><br><span class="line">onPause():界面失去焦点对应的方法(暂停)(按钮不可被点击,文本框不可输入内容,但是界面用户仍然能看见)</span><br><span class="line">onStop():当activity界面用户不可见时调用的方法</span><br><span class="line">onDestory():被销毁时调用的方法</span><br></pre></td></tr></table></figure><p>使用场景:<br>1.应用程序退出自动保存数据 ondestory oncreate<br>2.应用程序最小化 暂停的操作 onstop onstart 视频播放器<br>3.游戏的暂停和开始 前台生命周期</p><h3 id="内存不足时"><a href="#内存不足时" class="headerlink" title="内存不足时"></a>内存不足时</h3><blockquote><p>系统会优先杀死后台activity所在的进程,都杀光了,如果内存还是不足,那么就会杀死暂停状态的activity进程,如果还不够,有可能杀死前台进程。<br>如果有多个后台进程,在选择杀死目标时,采用最近最少使用算法。</p></blockquote><h3 id="任务栈"><a href="#任务栈" class="headerlink" title="任务栈"></a>任务栈</h3><ol><li>任务栈(task stack) (别名 back stack 后退栈), 用来记录存放用户开启的activity,帮助维护好用户体验。</li><li>一个应用程序一被开启,系统就给他分配一个任务栈,当所有activity都退出的时候,任务栈就清空了。</li><li>任务栈的id(getTaskId())是Integer类型的,自增长的。</li><li>在 android 操作系统中会存在多个任务栈,一个应用程序一个任务栈。</li><li>默认情况下关闭掉一个应用程序,实际上是清空了这个应用程序的任务栈,应用程序的进程还会保留。</li></ol><h3 id="activity的启动模式"><a href="#activity的启动模式" class="headerlink" title="activity的启动模式"></a>activity的启动模式</h3><ol><li>standard 默认的标准启动模式,每次startActivity都会创建一个新的activity的实例,按照后进先出的原则将activity添加到任务栈中,每次可见的activity都位于任务栈的栈顶。</li><li>singleTop 单一顶部,如果要开启的activity在任务栈的顶部已经存在,就不会创建新的实例,而是调用onNewIntent()方法。应用场景:浏览器书签。</li><li>singleTask 单一任务栈,activity只会在任务栈里面存在一个实例,如果要激活的activity在任务栈里面已经存在,则不会创建新的activity,而是复用这个已经存在的activity,调用onNewIntent()方法,并且清空这个activity任务栈上面所有的activity。应用场景:浏览器activity。整个任务栈只有一个实例,节约内存、CPU。<br>注意:activity还是运行在当前应用程序的任务栈里面的</li><li>singleInstance 单一实例 在整个手机操作系统中,只有一个实例存在,不同的应用打开这个activity,共享的是同一个activity。它会运行在自己单独,独立的任务栈里面,并且任务栈里面只有它一个实例存在。</li></ol><p>在manifest清单文件activity节点下配置<br><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">android:launchMode="standard"</span><br></pre></td></tr></table></figure></p><h3 id="横竖屏切换的生命周期"><a href="#横竖屏切换的生命周期" class="headerlink" title="横竖屏切换的生命周期"></a>横竖屏切换的生命周期</h3><p>默认情况下横竖屏切换activity会被销毁并重新创建</p><blockquote><p>应用启动(横屏):onCreate()->onStart()->onResume()<br>切换竖屏:onPause()->onStop()->onDestory()->onCreate()->onStart()->onResume()</p></blockquote><h4 id="两种解决方案:"><a href="#两种解决方案:" class="headerlink" title="两种解决方案:"></a>两种解决方案:</h4><p>1.让系统不要理会横竖屏切换(这样就不会重新触发生命周期方法)<br>在配置清单文件activity节点中添加<br><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">android:configChanges="orientation|keyboardHidden|screenSize"</span><br></pre></td></tr></table></figure></p><p>2.在配置清单文件activity节点中将屏幕朝向写死<br><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">android:screenOrientation=""//portrait竖屏 landscape横屏</span><br></pre></td></tr></table></figure></p>]]></content>
<summary type="html">
<h3 id="页面跳转"><a href="#页面跳转" class="headerlink" title="页面跳转"></a>页面跳转</h3><p>activity只要配置为启动界面的intent_filter,就会生成应用图标与名称<br>隐式意图:通过指定的action与data<br>显式意图:直接指定目标activity的包名和类名<br><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--给activity配置intent-filter--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">activity</span> <span class="attr">android:name</span>=<span class="string">".mainActivity"</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">intent-filter</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">action</span> <span class="attr">android:name</span>=<span class="string">"com.java.intent"</span>/&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">category</span> <span class="attr">android:name</span>=<span class="string">"android.intent.category.DEFAULT"</span>/&gt;</span></span><br><span class="line"> <span class="tag">&lt;/<span class="name">intent-filter</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">activity</span>&gt;</span></span><br></pre></td></tr></table></figure></p>
</summary>
<category term="android" scheme="http://jockio.github.io/categories/android/"/>
<category term="notes" scheme="http://jockio.github.io/categories/android/notes/"/>
<category term="android" scheme="http://jockio.github.io/tags/android/"/>
</entry>
<entry>
<title>Android 系列笔记 五</title>
<link href="http://jockio.github.io/2016/05/16/android-note-day05/"/>
<id>http://jockio.github.io/2016/05/16/android-note-day05/</id>
<published>2016-05-16T09:22:23.000Z</published>
<updated>2016-06-05T11:18:42.000Z</updated>
<content type="html"><![CDATA[<h3 id="多线程下载"><a href="#多线程下载" class="headerlink" title="多线程下载"></a>多线程下载</h3><p>原理:<br>服务器CPU分配给每条线程的时间片相同,服务器带宽平均分配给每条线程,所以客户端开启的线程越多,就能抢占到更多的服务器资源。<br><a id="more"></a><br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">multiThreadDownload</span><span class="params">(String path)</span></span>{</span><br><span class="line"><span class="keyword">int</span> threadCount = <span class="number">3</span>;</span><br><span class="line">URL url = <span class="keyword">new</span> URL(path);</span><br><span class="line"> conn = (HttpURLConnection) url.openConnection();</span><br><span class="line"> conn.setConnectTimeout(<span class="number">10000</span>);<span class="comment">//设置请求超时时间</span></span><br><span class="line"> conn.setReadTimeout(<span class="number">5000</span>);<span class="comment">//设置读取超时时间</span></span><br><span class="line"> conn.setRequestMethod(<span class="string">"GET"</span>);<span class="comment">//设置请求类型</span></span><br><span class="line"> conn.connect();</span><br><span class="line"></span><br><span class="line"> <span class="keyword">int</span> responseCode = conn.getResponseCode();<span class="comment">//获取请求响应码</span></span><br><span class="line"> <span class="keyword">if</span> (responseCode == <span class="number">200</span>) {<span class="comment">//请求成功</span></span><br><span class="line"> <span class="keyword">int</span> length = conn.getContentLength();</span><br><span class="line"> <span class="keyword">int</span> singleFileSize = length / threadCount;</span><br><span class="line"> <span class="comment">//生成一个跟要下载文件大小相同的临时文件</span></span><br><span class="line"> File tempFile = <span class="keyword">new</span> File(<span class="string">"abc.rmvb"</span>);</span><br><span class="line"> RandomAccessFile tempRaf = <span class="keyword">new</span> RandomAccessFile(tempFile, <span class="string">"rwd"</span>);</span><br><span class="line"> <span class="comment">//创建与服务器上资源同等大小的空文件</span></span><br><span class="line"> tempRaf.setLength(length);</span><br><span class="line"> tempRaf.close();</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i < threadCount; i++){</span><br><span class="line"> <span class="keyword">int</span> start = i * singleFileSize;</span><br><span class="line"> <span class="keyword">int</span> end = (i + <span class="number">1</span>) * singleFileSize - <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">if</span>(i == threadCount - <span class="number">1</span>)</span><br><span class="line"> end = length - <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">new</span> Thread(){</span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">run</span><span class="params">()</span></span>{</span><br><span class="line"> URL url = <span class="keyword">new</span> URL(path);</span><br><span class="line"> conn = (HttpURLConnection) url.openConnection();</span><br><span class="line"> conn.setConnectTimeout(<span class="number">10000</span>);<span class="comment">//设置请求超时时间</span></span><br><span class="line"> conn.setReadTimeout(<span class="number">5000</span>);<span class="comment">//设置读取超时时间</span></span><br><span class="line"> conn.setRequestMethod(<span class="string">"GET"</span>);<span class="comment">//设置请求类型</span></span><br><span class="line"><span class="comment">//设置文件读取起始位置及结束位置</span></span><br><span class="line">conn.setRequestProperty(<span class="string">"Range"</span>, <span class="string">"bytes="</span> + start + <span class="string">"-"</span> + end);</span><br><span class="line"> conn.connect();</span><br><span class="line"> <span class="keyword">if</span> (responseCode == <span class="number">206</span>) {<span class="comment">//请求部分数据,响应码为206</span></span><br><span class="line"> InputStream is = conn.getInputStream();</span><br><span class="line"> <span class="keyword">byte</span>[] buffer = <span class="keyword">new</span> <span class="keyword">byte</span>[<span class="number">1024</span>];</span><br><span class="line"> <span class="keyword">int</span> len = <span class="number">0</span>;</span><br><span class="line"> <span class="comment">//拿到临时文件输出流的引用</span></span><br><span class="line"> File file = <span class="keyword">new</span> File(<span class="string">"abc.rmvb.part"</span>);</span><br><span class="line"> RandomAccessFile raf = <span class="keyword">new</span> RandomAccessFile(file, <span class="string">"rwd"</span>);</span><br><span class="line"> <span class="comment">//将文件写入位置移动至start</span></span><br><span class="line"> raf.seek(start);</span><br><span class="line"> <span class="keyword">while</span>((len = is.read(buffer)) != -<span class="number">1</span>){</span><br><span class="line"> raf.write(buffer, <span class="number">0</span> ,len);</span><br><span class="line"> }</span><br><span class="line"> raf.close();</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }.start();</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p><h3 id="断点续传"><a href="#断点续传" class="headerlink" title="断点续传"></a>断点续传</h3><p>用单独文件记录下载位置<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">int</span> total;<span class="comment">//当前已经下载大小</span></span><br><span class="line">File progressFile = <span class="keyword">new</span> File(threadId + <span class="string">".txt"</span>);</span><br><span class="line">RandomAccessFile progressRaf = <span class="keyword">new</span> RandomAccessFile(progressFile, <span class="string">"rwd"</span>);</span><br><span class="line"><span class="comment">//每次读取数据后,同步把当前下载的总进度接入到进度临时文件中</span></span><br><span class="line">progressRaf.write((total + <span class="string">""</span>).getBytes());</span><br><span class="line">progressRaf.close();</span><br><span class="line"><span class="comment">//继续下载的时候 先判断记录文件是否存在</span></span><br><span class="line"><span class="comment">//若存在的话,读取已经下载的大小total,再继续下载</span></span><br><span class="line">start += total;</span><br></pre></td></tr></table></figure></p><h3 id="ProgressBar-进度条"><a href="#ProgressBar-进度条" class="headerlink" title="ProgressBar 进度条"></a>ProgressBar 进度条</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//可以在子线程中刷新UI</span></span><br><span class="line"><span class="comment">//设置进度条的最大值</span></span><br><span class="line">pb.setMax(length);</span><br><span class="line"><span class="comment">//设置当前进度</span></span><br><span class="line">pb.setProgress(total);</span><br></pre></td></tr></table></figure><h3 id="第三方框架-xUtils"><a href="#第三方框架-xUtils" class="headerlink" title="第三方框架 xUtils"></a>第三方框架 xUtils</h3><p>支持多线程、断点续传<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">download</span><span class="params">(String path)</span></span>{</span><br><span class="line">HttpUtils utils = <span class="keyword">new</span> HttpUtils();</span><br><span class="line">HttpHandler handler = utils.download(path,</span><br><span class="line"><span class="string">""</span>, <span class="comment">//保存路径</span></span><br><span class="line"><span class="keyword">true</span>, <span class="comment">//是否支持断点续传,如果服务器不支持range属性,则重新下载</span></span><br><span class="line"><span class="keyword">true</span>, <span class="comment">//如果从请求返回信息中获取到文件名,下载完成后自动重命名</span></span><br><span class="line"><span class="keyword">new</span> RequestCallBack<File>(){</span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onStart</span><span class="params">()</span></span>{</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line"><span class="comment">//下载成功后调用</span></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onSuccess</span><span class="params">(ResponseInfo<File> responseInfo)</span></span>{</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onFailure</span><span class="params">(HttpException error, String msg)</span></span>{</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onLoading</span><span class="params">(<span class="keyword">long</span> total, <span class="keyword">long</span> current, <span class="keyword">boolean</span> isUploading)</span></span>{</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line">});</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>]]></content>
<summary type="html">
<h3 id="多线程下载"><a href="#多线程下载" class="headerlink" title="多线程下载"></a>多线程下载</h3><p>原理:<br>服务器CPU分配给每条线程的时间片相同,服务器带宽平均分配给每条线程,所以客户端开启的线程越多,就能抢占到更多的服务器资源。<br>
</summary>
<category term="android" scheme="http://jockio.github.io/categories/android/"/>
<category term="notes" scheme="http://jockio.github.io/categories/android/notes/"/>
<category term="android" scheme="http://jockio.github.io/tags/android/"/>
</entry>
<entry>
<title>Android 系列笔记 四</title>
<link href="http://jockio.github.io/2016/05/15/android-note-day04/"/>
<id>http://jockio.github.io/2016/05/15/android-note-day04/</id>
<published>2016-05-15T11:05:09.000Z</published>
<updated>2016-06-05T11:18:35.000Z</updated>
<content type="html"><![CDATA[<h3 id="handler-消息处理器:用于发送、接收消息"><a href="#handler-消息处理器:用于发送、接收消息" class="headerlink" title="handler 消息处理器:用于发送、接收消息"></a>handler 消息处理器:用于发送、接收消息</h3><p>主线程中更新UI<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">Handler handler=<span class="keyword">new</span> Handler(){</span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">handleMessage</span><span class="params">(Message msg)</span></span>{</span><br><span class="line"><span class="keyword">super</span>.handleMessage(msg);</span><br><span class="line"><span class="keyword">switch</span>(msg.what){</span><br><span class="line"><span class="keyword">case</span> SUCCESS:</span><br><span class="line"><span class="keyword">break</span>;</span><br><span class="line"><span class="keyword">default</span>:</span><br><span class="line"><span class="keyword">break</span></span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line">};</span><br></pre></td></tr></table></figure></p><a id="more"></a><p>子线程向消息池发送消息<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">new</span> Thread(<span class="keyword">new</span> Runnable(){</span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">run</span><span class="params">()</span></span>{</span><br><span class="line">Message msg=<span class="keyword">new</span> Message();</span><br><span class="line">msg.what=<span class="number">0</span>;</span><br><span class="line">msg.obj=要操作的变量;</span><br><span class="line">handler.sendMessage(msg);</span><br><span class="line">}</span><br><span class="line">}).start();</span><br></pre></td></tr></table></figure></p><h3 id="get请求"><a href="#get请求" class="headerlink" title="get请求"></a>get请求</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line">HttpURLConnection conn = <span class="keyword">null</span>;</span><br><span class="line"><span class="keyword">try</span> {</span><br><span class="line"> Log.i(<span class="string">"getPicture"</span>, address);</span><br><span class="line"> URL url = <span class="keyword">new</span> URL(address);</span><br><span class="line"> conn = (HttpURLConnection) url.openConnection();</span><br><span class="line"> conn.setConnectTimeout(<span class="number">10000</span>);<span class="comment">//设置请求超时时间</span></span><br><span class="line"> conn.setReadTimeout(<span class="number">5000</span>);<span class="comment">//设置读取超时时间</span></span><br><span class="line"> conn.setRequestMethod(<span class="string">"GET"</span>);<span class="comment">//设置请求类型</span></span><br><span class="line"> conn.connect();</span><br><span class="line"></span><br><span class="line"> <span class="keyword">int</span> responseCode = conn.getResponseCode();<span class="comment">//获取请求响应码</span></span><br><span class="line"> <span class="keyword">if</span> (responseCode == <span class="number">200</span>) {<span class="comment">//请求成功</span></span><br><span class="line"> Log.i(<span class="string">"get picture"</span>, <span class="string">"loading......"</span>);</span><br><span class="line"> Bitmap bitmap = BitmapFactory.decodeStream(conn.getInputStream());</span><br><span class="line"> <span class="keyword">if</span>(bitmap!=<span class="keyword">null</span>) {</span><br><span class="line"> Message msg = <span class="keyword">new</span> Message();<span class="comment">//向主线程发送一条消息</span></span><br><span class="line"> msg.what = SUCCESS;</span><br><span class="line"> msg.obj = bitmap;</span><br><span class="line"> handler.sendMessage(msg);</span><br><span class="line"> }<span class="keyword">else</span>{</span><br><span class="line"> Message msg = <span class="keyword">new</span> Message();</span><br><span class="line"> msg.what = ERROR;</span><br><span class="line"> handler.sendMessage(msg);</span><br><span class="line"> }</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> Log.i(<span class="string">"error"</span>, <span class="string">"visit wrong"</span>);</span><br><span class="line"> }</span><br><span class="line">} <span class="keyword">catch</span> (Exception e) {</span><br><span class="line"> e.printStackTrace();</span><br><span class="line">} <span class="keyword">finally</span> {</span><br><span class="line"> <span class="keyword">if</span> (conn != <span class="keyword">null</span>)</span><br><span class="line"> conn.disconnect();</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="图片缓存"><a href="#图片缓存" class="headerlink" title="图片缓存"></a>图片缓存</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">String urlString = <span class="string">""</span>;</span><br><span class="line">URL url = <span class="keyword">new</span> URL(urlString);</span><br><span class="line">HttpURLConnection connection = (HttpURLConnection)url.openConnection();</span><br><span class="line">conn.setConnectTimeout(<span class="number">10000</span>);<span class="comment">//设置请求超时时间</span></span><br><span class="line">conn.setReadTimeout(<span class="number">5000</span>);<span class="comment">//设置读取超时时间</span></span><br><span class="line">conn.setRequestMethod(<span class="string">"GET"</span>);<span class="comment">//设置请求类型</span></span><br><span class="line">conn.connect();</span><br><span class="line">InputStream is = connection.getInputStream();</span><br><span class="line"><span class="keyword">byte</span>[] buffer = <span class="keyword">new</span> <span class="keyword">byte</span>[<span class="number">1024</span>];</span><br><span class="line">File file = <span class="keyword">new</span> File(getCacheDir(), <span class="string">""</span>);</span><br><span class="line">FileOutputStream fos = <span class="keyword">new</span> FileOutputStream(file);</span><br><span class="line"><span class="keyword">int</span> len = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">while</span>((len = is.read(buffer)) != -<span class="number">1</span>){</span><br><span class="line">fos.write(buffer, <span class="number">0</span>, len);</span><br><span class="line">}</span><br><span class="line">fos.close();</span><br></pre></td></tr></table></figure><h3 id="post请求"><a href="#post请求" class="headerlink" title="post请求"></a>post请求</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">new</span> Thread(<span class="keyword">new</span> Runnable(){</span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">run</span><span class="params">()</span></span>{</span><br><span class="line"><span class="comment">//执行网络操作</span></span><br><span class="line">runOnUiThread(<span class="keyword">new</span> Runnable(){</span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">run</span><span class="params">()</span></span>{</span><br><span class="line"><span class="comment">//就是在主线程中执行操作</span></span><br><span class="line"> Toast.makeText(getApplicationContext(),<span class="string">"hello"</span>,Toast.LENGTH_SHORT).show();</span><br><span class="line">HttpURLConnection conn = <span class="keyword">null</span>;</span><br><span class="line"><span class="keyword">try</span> {</span><br><span class="line"> String address = <span class="string">"www.baidu.com"</span>;</span><br><span class="line"> URL url = <span class="keyword">new</span> URL(address);</span><br><span class="line"> conn = (HttpURLConnection) url.openConnection();</span><br><span class="line"> conn.setConnectTimeout(<span class="number">10000</span>);<span class="comment">//设置请求超时时间</span></span><br><span class="line"> conn.setReadTimeout(<span class="number">5000</span>);<span class="comment">//设置读取超时时间</span></span><br><span class="line"> conn.setRequestMethod(<span class="string">"POST"</span>);<span class="comment">//设置请求类型</span></span><br><span class="line"> </span><br><span class="line"> String text = <span class="string">"username="</span> + name + <span class="string">"&password="</span> + password;</span><br><span class="line"> <span class="comment">//设置post请求属性</span></span><br><span class="line"> conn.setRequestProperty(<span class="string">"Content-Length"</span>, text.length() + <span class="string">""</span>);</span><br><span class="line"> conn.setDoOutput(<span class="keyword">true</span>);</span><br><span class="line"> OutputStream os = conn.getOutputStream();</span><br><span class="line"> os.write(text.getBytes());</span><br><span class="line"> conn.connect();</span><br><span class="line"></span><br><span class="line"> <span class="keyword">int</span> responseCode = conn.getResponseCode();<span class="comment">//获取请求响应码</span></span><br><span class="line"> <span class="keyword">if</span> (responseCode == <span class="number">200</span>) {<span class="comment">//请求成功</span></span><br><span class="line"> InputStream is = conn.getInputStream();</span><br><span class="line"> String info = Utils.getTextFromStream(is); </span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> Log.i(<span class="string">"error"</span>, <span class="string">"visit wrong"</span>);</span><br><span class="line"> }</span><br><span class="line">} <span class="keyword">catch</span> (Exception e) {</span><br><span class="line"> e.printStackTrace();</span><br><span class="line">} <span class="keyword">finally</span> {</span><br><span class="line"> <span class="keyword">if</span> (conn != <span class="keyword">null</span>)</span><br><span class="line"> conn.disconnect();</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line">});</span><br><span class="line">}</span><br><span class="line">});</span><br></pre></td></tr></table></figure><h3 id="编码问题"><a href="#编码问题" class="headerlink" title="编码问题"></a>编码问题</h3><p>将汉字转为以%开头的字符串<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">URLEncoder.encode(editText.getString(), <span class="string">"utf-8"</span>);</span><br></pre></td></tr></table></figure></p><p>采用iso8859-1编码对姓名进行逆转,转成字节数组,再使用utf-8对数据编码<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">username=<span class="keyword">new</span> String(username.getBytes(<span class="string">"iso8859-1"</span>),<span class="string">"utf-8"</span>);</span><br></pre></td></tr></table></figure></p>]]></content>
<summary type="html">
<h3 id="handler-消息处理器:用于发送、接收消息"><a href="#handler-消息处理器:用于发送、接收消息" class="headerlink" title="handler 消息处理器:用于发送、接收消息"></a>handler 消息处理器:用于发送、接收消息</h3><p>主线程中更新UI<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">Handler handler=<span class="keyword">new</span> Handler()&#123;</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">handleMessage</span><span class="params">(Message msg)</span></span>&#123;</span><br><span class="line"> <span class="keyword">super</span>.handleMessage(msg);</span><br><span class="line"> <span class="keyword">switch</span>(msg.what)&#123;</span><br><span class="line"> <span class="keyword">case</span> SUCCESS:</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">default</span>:</span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure></p>
</summary>
<category term="android" scheme="http://jockio.github.io/categories/android/"/>
<category term="notes" scheme="http://jockio.github.io/categories/android/notes/"/>
<category term="android" scheme="http://jockio.github.io/tags/android/"/>
</entry>
<entry>
<title>Android 系列笔记 三</title>
<link href="http://jockio.github.io/2016/05/14/android-note-day03/"/>
<id>http://jockio.github.io/2016/05/14/android-note-day03/</id>
<published>2016-05-14T10:38:19.000Z</published>
<updated>2016-06-05T11:18:28.000Z</updated>
<content type="html"><![CDATA[<h3 id="单元测试"><a href="#单元测试" class="headerlink" title="单元测试"></a>单元测试</h3><ul><li>新建一个类继承自AndroidTestCase,并实现自己的测试方法</li><li><p>在配置清单文件中添加</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><instrumentation</span><br><span class="line">android:name=<span class="string">"android.test.InstrumentationTestRunner"</span> </span><br><span class="line">android:targetPackage=<span class="string">"要测试程序的包名"</span> /></span><br></pre></td></tr></table></figure></li><li><p>在application节点下添加</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><uses-library android:name=<span class="string">"android.test.runner"</span> /></span><br></pre></td></tr></table></figure></li></ul><a id="more"></a><h3 id="SQLite-数据库的创建"><a href="#SQLite-数据库的创建" class="headerlink" title="SQLite 数据库的创建"></a>SQLite 数据库的创建</h3><p>1.定义一个类继承自SQLiteOpenHelper<br> 实现其构造函数及onCreate() onUpgrade()方法<br> super(Context context, String name, CursorFactory factory, int version)<br> 分别为 上下文 数据库文件名 游标工厂(默认为空) 版本号<br> 在onCreate()方法中初始化表 该方法在数据库第一次创建时调用<br> onUpgrade()方法在数据库版本升级时调用<br>2.定义一个Dao类实现数据库的管理<br> 新建一个上面帮助类变量,实现自己的构造方法,然后实现数据库管理功能<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">insert</span><span class="params">(Person person)</span></span>{</span><br><span class="line">SQLiteDatabase db = openHelper.getWritableDatabase();</span><br><span class="line"><span class="keyword">if</span>(db.isOpen()){ <span class="comment">//如果数据库已打开 执行数据的插入</span></span><br><span class="line"><span class="comment">//直接拼接SQL语句不安全,存在SQL注入</span></span><br><span class="line">String sql = <span class="string">"insert into person(name, age) values(?,?);"</span>;</span><br><span class="line">db.execSQL(sql, <span class="keyword">new</span> Object[]{person.getName(), person.getAge()});</span><br><span class="line">Log.v(<span class="string">"INFO"</span>, <span class="string">"已插入一条数据 "</span> + person.toString());</span><br><span class="line">db.close();</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">delete</span><span class="params">(<span class="keyword">int</span> id)</span></span>{</span><br><span class="line">SQLiteDatabase db = openHelper.getWritableDatabase();</span><br><span class="line"><span class="keyword">if</span>(db.isOpen()){</span><br><span class="line">db.execSQL(<span class="string">"delete from person where _id = ?"</span>, <span class="keyword">new</span> Object[]{id});</span><br><span class="line">db.close();</span><br><span class="line">Log.v(<span class="string">"INFO"</span>, <span class="string">"已删除数据 id = "</span> + id);</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">update</span><span class="params">(String name,<span class="keyword">int</span> id)</span></span>{</span><br><span class="line">SQLiteDatabase db = openHelper.getWritableDatabase();</span><br><span class="line"><span class="keyword">if</span>(db.isOpen()){</span><br><span class="line">db.execSQL(<span class="string">"update person set name=? where _id=?"</span>, <span class="keyword">new</span> Object[]{name,id});</span><br><span class="line">db.close();</span><br><span class="line">Log.v(<span class="string">"INFO"</span>, <span class="string">"已更新数据 id="</span>+id+<span class="string">", name="</span> + name);</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function">List<Person> <span class="title">queryAll</span><span class="params">()</span></span>{</span><br><span class="line">List<Person> personList = <span class="keyword">null</span>;</span><br><span class="line">SQLiteDatabase db = openHelper.getReadableDatabase();</span><br><span class="line">Cursor cursor = db.rawQuery(<span class="string">"select _id, name, age from person"</span>, <span class="keyword">null</span>);</span><br><span class="line">Person person = <span class="keyword">null</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span>(cursor != <span class="keyword">null</span> && cursor.getCount() > <span class="number">0</span>){</span><br><span class="line">personList = <span class="keyword">new</span> ArrayList<Person>();</span><br><span class="line"><span class="keyword">while</span>(cursor.moveToNext()){</span><br><span class="line">person = <span class="keyword">new</span> Person();</span><br><span class="line">person.setId(cursor.getInt(<span class="number">0</span>));</span><br><span class="line">person.setName(cursor.getString(<span class="number">1</span>));</span><br><span class="line">person.setAge(cursor.getInt(<span class="number">2</span>));</span><br><span class="line">personList.add(person);</span><br><span class="line">Log.v(<span class="string">"INFO"</span>, <span class="string">"查询数据:"</span> + person.toString());</span><br><span class="line">}</span><br><span class="line">cursor.close();<span class="comment">//数据库优化 使用完要记得关闭</span></span><br><span class="line">db.close();</span><br><span class="line">}</span><br><span class="line"><span class="keyword">return</span> personList;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function">Person <span class="title">query</span><span class="params">(<span class="keyword">int</span> id)</span></span>{</span><br><span class="line">Person person = <span class="keyword">null</span>;</span><br><span class="line">SQLiteDatabase db = openHelper.getReadableDatabase();</span><br><span class="line">Cursor cursor = db.rawQuery(<span class="string">"select _id, name, age from person where _id=?"</span>, <span class="keyword">new</span> String[]{String.valueOf(id)});</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span>(cursor != <span class="keyword">null</span> && cursor.moveToFirst()){</span><br><span class="line">person = <span class="keyword">new</span> Person();</span><br><span class="line">person.setId(cursor.getInt(<span class="number">0</span>));</span><br><span class="line">person.setName(cursor.getString(<span class="number">1</span>));</span><br><span class="line">person.setAge(cursor.getInt(<span class="number">2</span>));</span><br><span class="line">Log.v(<span class="string">"INFO"</span>, <span class="string">"查询数据:"</span> + person.toString());</span><br><span class="line">cursor.close();</span><br><span class="line">db.close();</span><br><span class="line">}</span><br><span class="line"><span class="keyword">return</span> person;</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p><h3 id="java-API-实现数据库增删改查"><a href="#java-API-实现数据库增删改查" class="headerlink" title="java API 实现数据库增删改查"></a>java API 实现数据库增删改查</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">insert</span><span class="params">(Person person)</span></span>{</span><br><span class="line">SQLiteDatabase db = openHelper.getWritableDatabase();</span><br><span class="line">ContentValues values = <span class="keyword">null</span>;</span><br><span class="line"><span class="keyword">if</span>(db.isOpen()){</span><br><span class="line">values = <span class="keyword">new</span> ContentValues();</span><br><span class="line">values.put(<span class="string">"name"</span>, person.getName());</span><br><span class="line">values.put(<span class="string">"age"</span>, person.getAge());</span><br><span class="line"><span class="keyword">long</span> row=db.insert(<span class="string">"person"</span>, <span class="keyword">null</span>, values);</span><br><span class="line">Log.v(<span class="string">"INFO"</span>, <span class="string">"第"</span>+row+<span class="string">"行受影响,"</span> + person.toString());</span><br><span class="line">db.close();</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">delete</span><span class="params">(<span class="keyword">int</span> id)</span></span>{</span><br><span class="line">SQLiteDatabase db = openHelper.getWritableDatabase();</span><br><span class="line"><span class="keyword">if</span>(db.isOpen()){</span><br><span class="line"><span class="keyword">long</span> count = db.delete(<span class="string">"person"</span>, <span class="string">"_id=?"</span>, <span class="keyword">new</span> String[]{String.valueOf(id)});</span><br><span class="line">Log.v(<span class="string">"INFO"</span>, <span class="string">"删除数据:"</span> + count + <span class="string">"行受影响,"</span>);</span><br><span class="line">db.close();</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">update</span><span class="params">(String name,<span class="keyword">int</span> id)</span></span>{</span><br><span class="line">SQLiteDatabase db = openHelper.getWritableDatabase();</span><br><span class="line">ContentValues values = <span class="keyword">null</span>;</span><br><span class="line"><span class="keyword">if</span>(db.isOpen()){</span><br><span class="line">values = <span class="keyword">new</span> ContentValues();</span><br><span class="line">values.put(<span class="string">"name"</span>, name);</span><br><span class="line"><span class="keyword">long</span> count = db.update(<span class="string">"person"</span>, values, <span class="string">"_id=?"</span>, <span class="keyword">new</span> String[]{String.valueOf(id)});</span><br><span class="line">Log.v(<span class="string">"INFO"</span>, <span class="string">"更新数据:"</span> + count + <span class="string">"行受影响,"</span>);</span><br><span class="line">db.close();</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function">List<Person> <span class="title">queryAll</span><span class="params">()</span></span>{</span><br><span class="line">List<Person> personList = <span class="keyword">null</span>;</span><br><span class="line">Person person = <span class="keyword">null</span>;</span><br><span class="line">SQLiteDatabase db = openHelper.getReadableDatabase();</span><br><span class="line"><span class="keyword">if</span>(db.isOpen()){</span><br><span class="line">personList = <span class="keyword">new</span> ArrayList<Person>();</span><br><span class="line">String[] columns = <span class="keyword">new</span> String[]{<span class="string">"_id"</span>, <span class="string">"name"</span>, <span class="string">"age"</span>};<span class="comment">//需要查询的列</span></span><br><span class="line">String selection = <span class="keyword">null</span>;<span class="comment">//选择条件为空 查询所有 </span></span><br><span class="line">String[] selectionArgs = <span class="keyword">null</span>;<span class="comment">//选择条件参数</span></span><br><span class="line">String groupBy = <span class="string">"name"</span>;<span class="comment">//分组查询 group by name</span></span><br><span class="line">String having = <span class="keyword">null</span>;<span class="comment">//过滤语句</span></span><br><span class="line">String orderBy = <span class="keyword">null</span>;<span class="comment">//排序</span></span><br><span class="line">Cursor cursor = db.query(<span class="string">"person"</span>, columns, selection, selectionArgs, groupBy, having, orderBy);</span><br><span class="line"><span class="keyword">if</span>(cursor != <span class="keyword">null</span> && cursor.getCount() > <span class="number">0</span>){</span><br><span class="line"><span class="keyword">while</span>(cursor.moveToNext()){</span><br><span class="line">person = <span class="keyword">new</span> Person();</span><br><span class="line">person.setName(cursor.getString(<span class="number">1</span>));</span><br><span class="line">person.setAge(cursor.getInt(<span class="number">2</span>));</span><br><span class="line">personList.add(person);</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line">cursor.close();</span><br><span class="line">db.close();</span><br><span class="line">}</span><br><span class="line"><span class="keyword">return</span> personList;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function">Person <span class="title">queryItem</span><span class="params">(<span class="keyword">int</span> id)</span></span>{</span><br><span class="line">Person person = <span class="keyword">null</span>;</span><br><span class="line">SQLiteDatabase db = openHelper.getReadableDatabase();</span><br><span class="line"><span class="keyword">if</span>(db.isOpen()){</span><br><span class="line">String[] columns = <span class="keyword">new</span> String[]{<span class="string">"_id"</span>, <span class="string">"name"</span>, <span class="string">"age"</span>};<span class="comment">//需要查询的列</span></span><br><span class="line">String selection = <span class="string">"_id=?"</span>;<span class="comment">//选择条件为空 查询所有 </span></span><br><span class="line">String[] selectionArgs = <span class="keyword">new</span> String[]{String.valueOf(id)};<span class="comment">//选择条件参数</span></span><br><span class="line">String groupBy = <span class="string">"name"</span>;<span class="comment">//分组查询 group by name</span></span><br><span class="line">String having = <span class="keyword">null</span>;<span class="comment">//过滤语句</span></span><br><span class="line">String orderBy = <span class="keyword">null</span>;<span class="comment">//排序</span></span><br><span class="line">Cursor cursor = db.query(<span class="string">"person"</span>, columns, selection, selectionArgs, groupBy, having, orderBy);</span><br><span class="line"><span class="keyword">if</span>(cursor != <span class="keyword">null</span> && cursor.moveToFirst()){</span><br><span class="line">person = <span class="keyword">new</span> Person();</span><br><span class="line">person.setName(cursor.getString(<span class="number">1</span>));</span><br><span class="line">person.setAge(cursor.getInt(<span class="number">2</span>));</span><br><span class="line">}</span><br><span class="line">cursor.close();</span><br><span class="line">db.close();</span><br><span class="line">}</span><br><span class="line"><span class="keyword">return</span> person;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="SQLite3的使用"><a href="#SQLite3的使用" class="headerlink" title="SQLite3的使用"></a>SQLite3的使用</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">adb shell</span><br><span class="line">ls <span class="comment">//列出当前目录下文件与文件夹</span></span><br><span class="line">cd /data/data/包名</span><br><span class="line">cd databases</span><br><span class="line"></span><br><span class="line">sqlite3 数据库文件名</span><br><span class="line">select * from person;</span><br><span class="line">delete from person where _id=<span class="number">3</span>;</span><br><span class="line"></span><br><span class="line">.table <span class="comment">//列出数据库中表名</span></span><br><span class="line">.mode column <span class="comment">//更改输出模式</span></span><br><span class="line">.exit <span class="comment">//退出SQLite3</span></span><br></pre></td></tr></table></figure><h3 id="SQLite事务操作"><a href="#SQLite事务操作" class="headerlink" title="SQLite事务操作"></a>SQLite事务操作</h3><p>要知道开启事务操作,效率要比不开启提升了10倍左右<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">testTransaction</span><span class="params">()</span></span>{</span><br><span class="line">SQLiteDatabase db = openHelper.getWritableDatabase();</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span>(db.isOpen()){</span><br><span class="line"><span class="keyword">try</span>{</span><br><span class="line"><span class="comment">//开启事务</span></span><br><span class="line">db.beginTransaction();</span><br><span class="line"></span><br><span class="line">String sql = <span class="string">"update person set balance=balance-1000 where name='ai';"</span>;</span><br><span class="line">db.execSQL(sql);</span><br><span class="line"></span><br><span class="line"><span class="comment">//double i = 10/0;</span></span><br><span class="line"></span><br><span class="line">String sql2 = <span class="string">"update person set balance=balance+1000 where name='zhangsan';"</span>;</span><br><span class="line">db.execSQL(sql2);</span><br><span class="line"></span><br><span class="line"><span class="comment">//标记事务成功</span></span><br><span class="line">db.setTransactionSuccessful();</span><br><span class="line">}<span class="keyword">catch</span>(Exception e){</span><br><span class="line">e.printStackTrace();</span><br><span class="line">}<span class="keyword">finally</span>{</span><br><span class="line"><span class="comment">//关闭事务</span></span><br><span class="line">db.endTransaction();</span><br><span class="line">db.close();</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p><h3 id="ListView"><a href="#ListView" class="headerlink" title="ListView"></a>ListView</h3><h4 id="自定义适配器一"><a href="#自定义适配器一" class="headerlink" title="自定义适配器一"></a>自定义适配器一</h4><p>getView()方法返回的为TextView<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MyAdapter</span> <span class="keyword">extends</span> <span class="title">BaseAdapter</span></span>{</span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">getCount</span><span class="params">()</span> </span>{</span><br><span class="line"><span class="keyword">return</span> personList.size();</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> Object <span class="title">getItem</span><span class="params">(<span class="keyword">int</span> position)</span> </span>{</span><br><span class="line"><span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">long</span> <span class="title">getItemId</span><span class="params">(<span class="keyword">int</span> position)</span> </span>{</span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment">* 返回的是ListView中某一行view对象</span></span><br><span class="line"><span class="comment">* position 当前返回的view的索引位置</span></span><br><span class="line"><span class="comment">* convertView 缓存对象</span></span><br><span class="line"><span class="comment">* parent ListView对象</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> View <span class="title">getView</span><span class="params">(<span class="keyword">int</span> position, View convertView, ViewGroup parent)</span> </span>{</span><br><span class="line">TextView tv = <span class="keyword">null</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">//向下滚动 上面内容消失后会被缓存</span></span><br><span class="line"><span class="keyword">if</span>(convertView != <span class="keyword">null</span>){<span class="comment">//复用缓存对象优化ListView</span></span><br><span class="line">tv = (TextView) convertView;</span><br><span class="line">Log.v(<span class="string">"INFO"</span>, <span class="string">"复用:"</span> + position);</span><br><span class="line">}<span class="keyword">else</span>{</span><br><span class="line">tv = <span class="keyword">new</span> TextView(getApplicationContext());</span><br><span class="line">Log.v(<span class="string">"INFO"</span>, <span class="string">"新建:"</span> + position);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">tv.setTextSize(<span class="number">30</span>);</span><br><span class="line">tv.setTextColor(Color.BLACK);</span><br><span class="line">Person person = personList.get(position);</span><br><span class="line">tv.setText(person.toString());</span><br><span class="line"><span class="keyword">return</span> tv;</span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p><h4 id="自定义适配器二"><a href="#自定义适配器二" class="headerlink" title="自定义适配器二"></a>自定义适配器二</h4><p>getView()方法返回的为Layout布局<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MyAdapter_2</span> <span class="keyword">extends</span> <span class="title">BaseAdapter</span></span>{</span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">getCount</span><span class="params">()</span> </span>{</span><br><span class="line"><span class="keyword">return</span> personList.size();</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> Object <span class="title">getItem</span><span class="params">(<span class="keyword">int</span> position)</span> </span>{</span><br><span class="line"><span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">long</span> <span class="title">getItemId</span><span class="params">(<span class="keyword">int</span> position)</span> </span>{</span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">* 返回的是ListView中某一行view对象</span></span><br><span class="line"><span class="comment">* position 当前返回的view的索引位置</span></span><br><span class="line"><span class="comment">* convertView 缓存对象</span></span><br><span class="line"><span class="comment">* parent ListView对象</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> View <span class="title">getView</span><span class="params">(<span class="keyword">int</span> position, View convertView, ViewGroup parent)</span> </span>{</span><br><span class="line">View view = <span class="keyword">null</span>;</span><br><span class="line">LayoutInflater inflater = <span class="keyword">null</span>;</span><br><span class="line"><span class="keyword">if</span>(convertView != <span class="keyword">null</span>){</span><br><span class="line">view = convertView;</span><br><span class="line">Log.v(<span class="string">"INFO"</span>, <span class="string">"复用:"</span> + position);</span><br><span class="line">}<span class="keyword">else</span>{</span><br><span class="line"><span class="comment">//将布局文件转换为一个对象</span></span><br><span class="line">inflater = MainActivity.<span class="keyword">this</span>.getLayoutInflater();</span><br><span class="line">view = inflater.inflate(R.layout.adapter2_itemlist, <span class="keyword">null</span>);</span><br><span class="line">Log.v(<span class="string">"INFO"</span>, <span class="string">"新建:"</span> + position);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">TextView name_textview = (TextView)view.findViewById(R.id.name_view);</span><br><span class="line">TextView age_textview = (TextView)view.findViewById(R.id.age_view);</span><br><span class="line">Person person = personList.get(position);</span><br><span class="line">name_textview.setText(person.getName());</span><br><span class="line">age_textview.setText(person.getAge() + <span class="string">""</span>);</span><br><span class="line"><span class="keyword">return</span> view;</span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p><h4 id="ListView-绑定ArrayAdapter适配器"><a href="#ListView-绑定ArrayAdapter适配器" class="headerlink" title="ListView 绑定ArrayAdapter适配器"></a>ListView 绑定ArrayAdapter适配器</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">String[] persons = <span class="keyword">new</span> String[]{<span class="string">"A"</span>,<span class="string">"B"</span>,<span class="string">"C"</span>,<span class="string">"D"</span>,<span class="string">"E"</span>,<span class="string">"F"</span>,<span class="string">"G"</span>,<span class="string">"H"</span>};</span><br><span class="line">arrayAdapter = <span class="keyword">new</span> ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1, persons);</span><br></pre></td></tr></table></figure><h4 id="ListView-绑定SimpleAdapter适配器"><a href="#ListView-绑定SimpleAdapter适配器" class="headerlink" title="ListView 绑定SimpleAdapter适配器"></a>ListView 绑定SimpleAdapter适配器</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">data = <span class="keyword">new</span> ArrayList<Map<String,Object>>();</span><br><span class="line"><span class="keyword">for</span>(Person person : personList){</span><br><span class="line">Map<String,Object> map = <span class="keyword">new</span> HashMap<String, Object>();</span><br><span class="line">map.put(<span class="string">"name"</span>, person.getName());</span><br><span class="line">map.put(<span class="string">"age"</span>, person.getAge());</span><br><span class="line">data.add(map);</span><br><span class="line">}</span><br><span class="line">String[] from = <span class="keyword">new</span> String[]{<span class="string">"name"</span>, <span class="string">"age"</span>};</span><br><span class="line"><span class="keyword">int</span>[] to = <span class="keyword">new</span> <span class="keyword">int</span>[]{R.id.title_textview, R.id.subtitle_textview};</span><br><span class="line">adapter = <span class="keyword">new</span> SimpleAdapter(getApplicationContext(), data, R.layout.item_list, from, to);</span><br></pre></td></tr></table></figure><h4 id="ListView动态更新"><a href="#ListView动态更新" class="headerlink" title="ListView动态更新"></a>ListView动态更新</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">adapter.notifyDataSetChanged();</span><br></pre></td></tr></table></figure><h3 id="对话框"><a href="#对话框" class="headerlink" title="对话框"></a>对话框</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">AlertDialog.Builder builder = <span class="keyword">new</span> Builder(<span class="keyword">this</span>);</span><br><span class="line">builder.setIcon(android.R.drawable.alert_dark_frame)</span><br><span class="line"> .setTitle(<span class="string">"Title"</span>)</span><br><span class="line"> .setMessage(<span class="string">"message"</span>)</span><br><span class="line"> .setPositiveButton(<span class="string">"确定"</span>, <span class="keyword">new</span> OnClickListener(){</span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onClick</span><span class="params">(DialogInterface dialog, <span class="keyword">int</span> which)</span></span>{</span><br><span class="line"> Toast.makeText(MainActivity.<span class="keyword">this</span>, <span class="string">"确定"</span>, Toast.LENGTH_SHORT).show();</span><br><span class="line"> }</span><br><span class="line"> })</span><br><span class="line"> .setNegativeButton(<span class="string">"取消"</span>, <span class="keyword">new</span> OnClickListener(){</span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onClick</span><span class="params">(DialogInterface dialog, <span class="keyword">int</span> which)</span></span>{</span><br><span class="line"> Toast.makeText(MainActivity.<span class="keyword">this</span>, <span class="string">"取消"</span>, Toast.LENGTH_SHORT).show();</span><br><span class="line"> }</span><br><span class="line"> });</span><br><span class="line">builder.create().show();</span><br></pre></td></tr></table></figure><h3 id="单选对话框"><a href="#单选对话框" class="headerlink" title="单选对话框"></a>单选对话框</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">final</span> String[] items = <span class="keyword">new</span> String[]{<span class="string">"男"</span>, <span class="string">"女"</span>};</span><br><span class="line">AlertDialog.Builder builder = <span class="keyword">new</span> Builder(<span class="keyword">this</span>);</span><br><span class="line">builder.setTitle(<span class="string">"请选择性别"</span>)</span><br><span class="line"> .setSingleChoiceItems(items, -<span class="number">1</span>, <span class="keyword">new</span> OnClickListener(){</span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onClick</span><span class="params">(DialogInterface dialog, <span class="keyword">int</span> which)</span></span>{</span><br><span class="line"> Toast.makeText(MainActivity.<span class="keyword">this</span>, <span class="string">"您选择的是"</span> + items[which], Toast.LENGTH_SHORT).show();</span><br><span class="line"> dialog.dismiss();</span><br><span class="line"> }</span><br><span class="line"> });</span><br><span class="line">builder.create().show();</span><br></pre></td></tr></table></figure><h3 id="多选会话框"><a href="#多选会话框" class="headerlink" title="多选会话框"></a>多选会话框</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">final</span> String[] items = <span class="keyword">new</span> String[]{<span class="string">"蓝莓"</span>, <span class="string">"西瓜"</span>, <span class="string">"香蕉"</span>, <span class="string">"苹果"</span>};</span><br><span class="line"><span class="keyword">boolean</span>[] checkedItems = <span class="keyword">new</span> <span class="keyword">boolean</span>[]{<span class="keyword">true</span>, <span class="keyword">true</span>, <span class="keyword">true</span>, <span class="keyword">false</span>};</span><br><span class="line">AlertDialog.Builder builder = <span class="keyword">new</span> Builder(<span class="keyword">this</span>);</span><br><span class="line">builder.setTitle(<span class="string">"请选择你喜欢的水果"</span>)</span><br><span class="line"> .setMultiChoiceItems(items, checkedItems, <span class="keyword">new</span> OnMultiChoiceClickListener(){</span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onClick</span><span class="params">(DialogInterface dialog, <span class="keyword">int</span> which, <span class="keyword">boolean</span> isChecked)</span></span>{</span><br><span class="line"> checkedItems[which] = isChecked;</span><br><span class="line"> }</span><br><span class="line"> })</span><br><span class="line"> .setPositiveButton(<span class="string">"确定"</span>, <span class="keyword">new</span> OnClickListener(){</span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onClick</span><span class="params">(DialogInterface dialog, <span class="keyword">int</span> which)</span></span>{</span><br><span class="line"> Toast.makeText(MainActivity.<span class="keyword">this</span>, <span class="string">"你选择的是:"</span>, Toast.LENGTH_SHORT).show();</span><br><span class="line"> dialog.dismiss();</span><br><span class="line"> }</span><br><span class="line"> });</span><br><span class="line">builder.create().show();</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h3 id="单元测试"><a href="#单元测试" class="headerlink" title="单元测试"></a>单元测试</h3><ul>
<li>新建一个类继承自AndroidTestCase,并实现自己的测试方法</li>
<li><p>在配置清单文件中添加</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&lt;instrumentation</span><br><span class="line"> android:name=<span class="string">"android.test.InstrumentationTestRunner"</span> </span><br><span class="line"> android:targetPackage=<span class="string">"要测试程序的包名"</span> /&gt;</span><br></pre></td></tr></table></figure>
</li>
<li><p>在application节点下添加</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;uses-library android:name=<span class="string">"android.test.runner"</span> /&gt;</span><br></pre></td></tr></table></figure>
</li>
</ul>
</summary>
<category term="android" scheme="http://jockio.github.io/categories/android/"/>
<category term="notes" scheme="http://jockio.github.io/categories/android/notes/"/>
<category term="android" scheme="http://jockio.github.io/tags/android/"/>
</entry>
</feed>