-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathatom.xml
634 lines (542 loc) · 128 KB
/
atom.xml
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
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Xuan's Space</title>
<subtitle>dailay note</subtitle>
<link href="/atom.xml" rel="self"/>
<link href="http://yangjingxuan.space/"/>
<updated>2018-01-29T03:28:11.000Z</updated>
<id>http://yangjingxuan.space/</id>
<author>
<name>JingXuan Yang</name>
<email>yangjingxuanmail@gmail.com</email>
</author>
<generator uri="http://hexo.io/">Hexo</generator>
<entry>
<title>Android 中常见内存泄露的几种情况</title>
<link href="http://yangjingxuan.space/2018/01/29/Android%20%E4%B8%AD%E5%B8%B8%E8%A7%81%E5%86%85%E5%AD%98%E6%B3%84%E9%9C%B2%E7%9A%84%E5%87%A0%E7%A7%8D%E6%83%85%E5%86%B5/"/>
<id>http://yangjingxuan.space/2018/01/29/Android 中常见内存泄露的几种情况/</id>
<published>2018-01-29T03:08:00.000Z</published>
<updated>2018-01-29T03:28:11.000Z</updated>
<content type="html"><![CDATA[<h3 id="Android-中常见内存泄露的几种情况"><a href="#Android-中常见内存泄露的几种情况" class="headerlink" title="Android 中常见内存泄露的几种情况"></a>Android 中常见内存泄露的几种情况</h3><p>我们在开发Android应用时,有时候会遇到程序因占用内存过高而造成的oom(out of memory),而本质的原因就是开发过程中内存使用的不合理以及应用中存在的内存泄露。<a id="more"></a></p>
<p>我们知道Java代码本身有自己的垃圾回收机制,所以在开发的过程中我们无需特意管理内存的分配,但是它仍旧有内存泄露的风险。我们如果引用了一个已经不再使用的对象,那么java代码的垃圾回收器就会因为一直持有引用而造成内存无法被回收。纵然短期内泄露的内存不多,但是在长期的使用过程中由于内存泄露的不断发生,最终程序就会因为内存泄露而产生oom。</p>
<p>这里引用一张C++/ Java的内存泄露图</p>
<p><img src="http://obr1dwgsb.bkt.clouddn.com/oom1.png" alt="oom1"></p>
<p>在c++与java还有一些主流的编程语言当中,都是通过上图中的对象可达性分析来判断对象是否存活的。基本的思路是通过GC Root 作为对象的起点,在起点这里对所有对象向下进行搜索,如果一个对象没有任何引用链连接时,那么这个对象可视为不可用,因此就会回收这个对象。</p>
<p> java 和 c++ 对内存管理最主要的区别就是:c++的内存泄露是开放的,而java则是开启了一个虚拟机封装起来,c++的内存泄露将影响到整一个系统,一旦泄露那么这块内存将一直不可用。java有了虚拟机的保护如果一旦出现内存泄露达到分配虚拟机内存上限时那么系统将会自动kill掉该进程,而不影响其他。</p>
<p>下面就Android日常开发我列举一些常见的内存泄露情况以及避免方式</p>
<p><img src="http://obr1dwgsb.bkt.clouddn.com/%E5%86%85%E5%AD%98%E6%B3%84%E9%9C%B2.png" alt="内存泄露"></p>
<p>上图已经整理出了常见的泄露方式还有一些需要说明的:</p>
<h4 id="1-持有Context对象"><a href="#1-持有Context对象" class="headerlink" title="1.持有Context对象"></a>1.持有Context对象</h4><p>Android中常见的context对象主要有两种:Activity和Application,其中View对象对整个activity保持引用。</p>
<p>如果有地方持有了相应的view类对象,一旦发生泄漏那么这整个Activity都会出现无法回收的情况。</p>
<h4 id="2-线程之间Handler使用"><a href="#2-线程之间Handler使用" class="headerlink" title="2.线程之间Handler使用"></a>2.线程之间Handler使用</h4><p>Handler 本身是异步的,可以使用静态内部类弱引用处理也可以通过生命周期<code>removeCallbacksAndMessages(null);</code>进行销毁,只要及时处理Handler,泄露还是很容易修复的。</p>
<h4 id="3-内部类与匿名内部类持有外部类对象引用"><a href="#3-内部类与匿名内部类持有外部类对象引用" class="headerlink" title="3.内部类与匿名内部类持有外部类对象引用"></a>3.内部类与匿名内部类持有外部类对象引用</h4><p>非静态内部类以及匿名内部类会持有一个隐式的强引用,如果该对象没有被回收,那么Activity 就会发生泄露。</p>
<p>其本质可以通过反编译源代码,内部类对象如何访问外部类成员变量,其实是有一个指针强引用了外部类的对象。</p>
<p>此处可以参考:<a href="http://www.cnblogs.com/dolphin0520/p/3811445.html" target="_blank" rel="external">Java内部类详解</a></p>
<h4 id="4-最小化变量作用域"><a href="#4-最小化变量作用域" class="headerlink" title="4.最小化变量作用域"></a>4.最小化变量作用域</h4><p>变量的使用也是值得注意的一点,Java的垃圾回收器会优先在方法执行结束后进行回收,如果将函数级的变量定义到类级别上,那么也就意味着整个垃圾回收器需要等待到该类的所有引用都被回收完成后才能进行垃圾回收。势必会对内存占用造成影响。优化属性的作用域是必须的,同样这也是封装原则,最小化作用域降低了通过包访问变量并减少了耦合。</p>
<h4 id="5-各类注册没有反注册"><a href="#5-各类注册没有反注册" class="headerlink" title="5.各类注册没有反注册"></a>5.各类注册没有反注册</h4><p>所有注册,订阅的操作都需要有一个与之相应的反注册,反订阅。</p>
<h4 id="6-webview泄露"><a href="#6-webview泄露" class="headerlink" title="6.webview泄露"></a>6.webview泄露</h4><p>webview也是一个大量占用内存控件,如果我们不及时清理WebView的内存,那最后可能会随着内存消耗的不断增加而发生OOM导致程序崩溃。</p>
]]></content>
<summary type="html">
<h3 id="Android-中常见内存泄露的几种情况"><a href="#Android-中常见内存泄露的几种情况" class="headerlink" title="Android 中常见内存泄露的几种情况"></a>Android 中常见内存泄露的几种情况</h3><p>我们在开发Android应用时,有时候会遇到程序因占用内存过高而造成的oom(out of memory),而本质的原因就是开发过程中内存使用的不合理以及应用中存在的内存泄露。
</summary>
<category term="开发小记" scheme="http://yangjingxuan.space/categories/%E5%BC%80%E5%8F%91%E5%B0%8F%E8%AE%B0/"/>
</entry>
<entry>
<title>Android Studio 优化构建速度解决方案</title>
<link href="http://yangjingxuan.space/2017/03/07/Android%20Studio%20%E4%BC%98%E5%8C%96%E6%9E%84%E5%BB%BA%E6%9E%B6%E6%9E%84%E9%80%9F%E5%BA%A6%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/"/>
<id>http://yangjingxuan.space/2017/03/07/Android Studio 优化构建架构速度解决方案/</id>
<published>2017-03-07T02:54:20.000Z</published>
<updated>2017-03-07T02:56:40.000Z</updated>
<content type="html"><![CDATA[<p>随着项目工程的扩大,程序编译时间也越来越长,同时也影响到了我们整个开发的速度。为了提高开发效率下面将列出一些优化方案:</p>
<blockquote>
<p>开发的时候尽可能的使用最新设备进行开发,运行在Android7.0(API level 24)</p>
<p>最新的Android 平台可以让你程序编译运行速度更快,如Android Runtime(ART)还有更好对multiple DEX 支持</p>
</blockquote>
<a id="more"></a>
<h5 id="1-优化配置文件"><a href="#1-优化配置文件" class="headerlink" title="1.优化配置文件"></a>1.优化配置文件</h5><ul>
<li><p>确保你的buildToolsVersion,Gradle最新</p>
<p>Android 编译工具随着版本的更新升级会不断的进行优化,使用最新的版本来开发</p>
<p><a href="https://developer.android.google.cn/studio/intro/update.html" target="_blank" rel="external">Android Studio and SDK tools</a></p>
<p><a href="https://developer.android.google.cn/studio/releases/gradle-plugin.html" target="_blank" rel="external">Gradle 更新</a></p>
</li>
<li><p>给你的开发环境配置特定的参数</p>
<p>大多数的配置都是在你开发正式环境版本所需要,而日常编译的时候并不用到这类配置,开启了不必要的配置会减慢你的编译速度</p>
<p>因此需要你配置一个特定的开发环境变量,如下面代码里”dev”(开发环境),”prod”(正式环境)</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></pre></td><td class="code"><pre><span class="line">android {</span><br><span class="line"> ...</span><br><span class="line"> defaultConfig {...}</span><br><span class="line"> buildTypes {...}</span><br><span class="line"> productFlavors {</span><br><span class="line"> // 可以参考如下配置</span><br><span class="line"> dev {</span><br><span class="line"> // 为了避免64k方法数限制,将开发环境的最低minSdkVersion 设置到 21以上 或更高</span><br><span class="line"> minSdkVersion 21</span><br><span class="line"> versionNameSuffix "-dev"</span><br><span class="line"> applicationIdSuffix '.dev'</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> prod {</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>如果你已经配置了上述的环境变量,当你在开发的时候需要混合加入一些新的变量,那么你可以通过<code>flavorDimensions</code> 配置维度 如:在新的环境变量”demo”, “full” 进行添加维度</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><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">android {</span><br><span class="line"> ...</span><br><span class="line"> defaultConfig {...}</span><br><span class="line"> buildTypes {...}</span><br><span class="line"></span><br><span class="line"> // 定义下面你需要用到变量维度</span><br><span class="line"> // 当你使用Gradle进行合并的时候,指定你需要的环境维度</span><br><span class="line"> </span><br><span class="line"> flavorDimensions "stage", "mode"</span><br><span class="line"></span><br><span class="line"> productFlavors {</span><br><span class="line"> dev {</span><br><span class="line"> dimension "stage"</span><br><span class="line"> minSdkVersion 21</span><br><span class="line"> versionNameSuffix "-dev"</span><br><span class="line"> applicationIdSuffix '.dev'</span><br><span class="line"> ...</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> prod {</span><br><span class="line"> dimension "stage"</span><br><span class="line"> ...</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> demo {</span><br><span class="line"> dimension "mode"</span><br><span class="line"> ...</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> full {</span><br><span class="line"> dimension "mode"</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>
</li>
</ul>
<h5 id="2-避免编译不必要的资源"><a href="#2-避免编译不必要的资源" class="headerlink" title="2.避免编译不必要的资源"></a>2.避免编译不必要的资源</h5><p>在开发环境编译的时候,你可以选定一种语言与一个屏幕分辨率参数,如下面</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></pre></td><td class="code"><pre><span class="line">android {</span><br><span class="line"> ...</span><br><span class="line"> productFlavors {</span><br><span class="line"> dev {</span><br><span class="line"> ...</span><br><span class="line"> resConfigs "en", "xxhdpi"</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>
<h5 id="3-开发版本编译关闭奔溃分析日志"><a href="#3-开发版本编译关闭奔溃分析日志" class="headerlink" title="3.开发版本编译关闭奔溃分析日志"></a>3.开发版本编译关闭奔溃分析日志</h5><p>如果你不需要奔溃分析日志报告,你可以直接关闭</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></pre></td><td class="code"><pre><span class="line">android {</span><br><span class="line"> ...</span><br><span class="line"> buildTypes {</span><br><span class="line"> debug {</span><br><span class="line"> ext.enableCrashlytics = false</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h5 id="4-使用静态配置值在你调试编译时"><a href="#4-使用静态配置值在你调试编译时" class="headerlink" title="4.使用静态配置值在你调试编译时"></a>4.使用静态配置值在你调试编译时</h5><p>当你在编译生成正式版本的时候会用到动态版本代码,版本名称,资源等,这些动态生成的配置参数可以在调试运行时候隔离他们,使用静态的配置值进行debug 版本编译,如下面的代码:</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></pre></td><td class="code"><pre><span class="line">int MILLIS_IN_MINUTE = 1000 * 60</span><br><span class="line">int minutesSinceEpoch = System.currentTimeMillis() / MILLIS_IN_MINUTE</span><br><span class="line"></span><br><span class="line">android {</span><br><span class="line"> ...</span><br><span class="line"> defaultConfig {</span><br><span class="line"> // 默认使用版本静态值</span><br><span class="line"> versionCode 1</span><br><span class="line"> versionName "1.0"</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><span class="line"> applicationVariants.all { variant -></span><br><span class="line"> if (variant.buildType.name == "release") {</span><br><span class="line"> variant.mergedFlavor.versionCode = minutesSinceEpoch;</span><br><span class="line"> variant.mergedFlavor.versionName = minutesSinceEpoch + "-" + variant.flavorName;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h5 id="5-使用静态依赖版本值"><a href="#5-使用静态依赖版本值" class="headerlink" title="5.使用静态依赖版本值"></a>5.使用静态依赖版本值</h5><p>诸如<code>com.android.tools.build:gradle:2.+</code>可以在编译调试的时候使用当前固定版本值替换</p>
<h5 id="6-配置DexOptions与启用-Library-per-dexing"><a href="#6-配置DexOptions与启用-Library-per-dexing" class="headerlink" title="6.配置DexOptions与启用 Library per-dexing"></a>6.配置DexOptions与启用 Library per-dexing</h5><ul>
<li><p>Library per-dexing </p>
<p>使用预生成库进行增量更新</p>
</li>
<li><p>maxProcessCount</p>
<p>设置最大的线程数</p>
</li>
<li><p>javaMaxHeapSize</p>
<p>设置最大堆空间</p>
<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><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">android {</span><br><span class="line"> ...</span><br><span class="line"> dexOptions {</span><br><span class="line"> preDexLibraries true</span><br><span class="line"> maxProcessCount 8</span><br><span class="line"> javaMaxHeapSize "2048m"</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
</li>
</ul>
<h5 id="7-增大Gradle编译堆栈空间"><a href="#7-增大Gradle编译堆栈空间" class="headerlink" title="7.增大Gradle编译堆栈空间"></a>7.增大Gradle编译堆栈空间</h5><p>如在你的 <code>gradle.properties</code> 文件下 增大设置堆栈空间</p>
<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">org.gradle.jvmargs = -Xmx2048m</span><br></pre></td></tr></table></figure>
<h5 id="8-使用WebP-图片格式"><a href="#8-使用WebP-图片格式" class="headerlink" title="8.使用WebP 图片格式"></a>8.使用WebP 图片格式</h5><p>将PNG图片转换成WebP </p>
<h5 id="9-禁用PNG图片处理"><a href="#9-禁用PNG图片处理" class="headerlink" title="9.禁用PNG图片处理"></a>9.禁用PNG图片处理</h5><p>如果你不想转换webp格式的图片,但是你仍旧想提高你的编译运行速度,那你可以参照如下配置 禁用PNG图片自动压缩</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></pre></td><td class="code"><pre><span class="line">android {</span><br><span class="line"> ...</span><br><span class="line"> aaptOptions {</span><br><span class="line"> cruncherEnabled false</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<blockquote>
<p>提示:当你以一次构建成功后,你会发现接下来的clean build操作会越来越快(即使不使用本页的任何优化)。这个是因为Gradle 进程会有一个“热身”提高性能的过程,类似JVM进程的预热期</p>
</blockquote>
<p>通过本页的一些优化后,应该能为你减少编译过程的大多数时间</p>
]]></content>
<summary type="html">
<p>随着项目工程的扩大,程序编译时间也越来越长,同时也影响到了我们整个开发的速度。为了提高开发效率下面将列出一些优化方案:</p>
<blockquote>
<p>开发的时候尽可能的使用最新设备进行开发,运行在Android7.0(API level 24)</p>
<p>最新的Android 平台可以让你程序编译运行速度更快,如Android Runtime(ART)还有更好对multiple DEX 支持</p>
</blockquote>
</summary>
<category term="开发小记" scheme="http://yangjingxuan.space/categories/%E5%BC%80%E5%8F%91%E5%B0%8F%E8%AE%B0/"/>
</entry>
<entry>
<title>ImageView Scale Type 使用指南</title>
<link href="http://yangjingxuan.space/2016/09/08/ImageView%20Scale%20Type%20%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97/"/>
<id>http://yangjingxuan.space/2016/09/08/ImageView Scale Type 使用指南/</id>
<published>2016-09-08T10:28:16.000Z</published>
<updated>2016-09-21T03:10:46.000Z</updated>
<content type="html"><![CDATA[<p>如果你是刚接触ImageView 的新同学,并且你对ScaleType 这个属性难以理解其字面效果的话,那么你可以花几分钟时间看完这篇文章,然后在你现在App中使用到的ImageView中,为他们设置上ScaleType这个属性看看效果</p>
<p>由于近期对ImageView图片缩放等展示样式使用较多,所以现将ImageView ScaleType这个属性设置样式效果展现出来</p>
<h4 id="Scalce-Type"><a href="#Scalce-Type" class="headerlink" title="Scalce Type"></a>Scalce Type</h4><p>官方对每一个Scalce Type 的设置都做了统一说明 <a href="https://developer.android.com/reference/android/widget/ImageView.ScaleType.html" target="_blank" rel="external">官方说明</a></p>
<p>你也可以在下面的截图中看到具体的展现效果</p>
<a id="more"></a>
<p><img src="http://obr1dwgsb.bkt.clouddn.com/%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7%202016-09-08%20%E4%B8%8B%E5%8D%885.08.59.png" alt="屏幕快照 2016-09-08 下午5.08.59"></p>
<h5 id="Center"><a href="#Center" class="headerlink" title="Center"></a>Center</h5><p>图片以原图的几何中心点和ImagView的几何中心点为基准,按图片的原来大小居中显示,不进行缩放</p>
<p>当图片超过View的长或宽时,则截取图片居中部分,当图片小于View的长或宽时只显示图片原来的大小</p>
<h5 id="Center-Crop"><a href="#Center-Crop" class="headerlink" title="Center Crop"></a>Center Crop</h5><p>图片以原图的几何中心点和ImagView的几何中心点为基准,将图片等比例进行放大,使得图片填充满整个View</p>
<p>按照View的大小截取图片</p>
<h5 id="Center-Inside"><a href="#Center-Inside" class="headerlink" title="Center Inside"></a>Center Inside</h5><p>图片以原图的几何中心点和ImagView的几何中心点为基准,将图片完整居中显示,不做任何缩放</p>
<h5 id="Matrix"><a href="#Matrix" class="headerlink" title="Matrix"></a>Matrix</h5><p>使用ImageView默认的Matrix,不改变原图的大小,从ImageView的左上角开始绘制原图</p>
<p>当原图超过ImageView的时则做裁剪</p>
<h5 id="Fit-Center"><a href="#Fit-Center" class="headerlink" title="Fit Center"></a>Fit Center</h5><p>使用 <code>Matrix.ScaleToFit.CENTER</code> 对图片进行缩放</p>
<p>将图片内容居中显示为目的,将图片进行缩放居中显示全图</p>
<h5 id="Fit-End"><a href="#Fit-End" class="headerlink" title="Fit End"></a>Fit End</h5><p>使用 <code>Matrix.ScaleToFit.END</code> 对图片进行缩放</p>
<p>将图片按比例缩放,在底部显示原图</p>
<h5 id="Fix-Start"><a href="#Fix-Start" class="headerlink" title="Fix Start"></a>Fix Start</h5><p>使用<code>Matrix.ScaleToFit.START</code>对图片进行缩放</p>
<p>将图片按比例缩放,在顶部显示原图</p>
<h5 id="Fit-XY"><a href="#Fit-XY" class="headerlink" title="Fit XY"></a>Fit XY</h5><p>使用<code>Matrix.ScaleToFit.FILL</code> 对图片进行缩放</p>
<p>不保持比例,将图片直接填充铺满整个View</p>
<h4 id="Adjust-View-Bounds"><a href="#Adjust-View-Bounds" class="headerlink" title="Adjust View Bounds"></a>Adjust View Bounds</h4><p>该属性是通过一个boolean值去设置,是否保持图片原图的长宽比</p>
<p>单独设置该属性不产生作用,需要配合maxWidth或maxHeight一起使用</p>
<p> <img src="http://obr1dwgsb.bkt.clouddn.com/%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7%202016-09-08%20%E4%B8%8B%E5%8D%886.14.59.png" alt="屏幕快照 2016-09-08 下午6.14.59"></p>
]]></content>
<summary type="html">
<p>如果你是刚接触ImageView 的新同学,并且你对ScaleType 这个属性难以理解其字面效果的话,那么你可以花几分钟时间看完这篇文章,然后在你现在App中使用到的ImageView中,为他们设置上ScaleType这个属性看看效果</p>
<p>由于近期对ImageView图片缩放等展示样式使用较多,所以现将ImageView ScaleType这个属性设置样式效果展现出来</p>
<h4 id="Scalce-Type"><a href="#Scalce-Type" class="headerlink" title="Scalce Type"></a>Scalce Type</h4><p>官方对每一个Scalce Type 的设置都做了统一说明 <a href="https://developer.android.com/reference/android/widget/ImageView.ScaleType.html">官方说明</a></p>
<p>你也可以在下面的截图中看到具体的展现效果</p>
</summary>
<category term="开发小记" scheme="http://yangjingxuan.space/categories/%E5%BC%80%E5%8F%91%E5%B0%8F%E8%AE%B0/"/>
</entry>
<entry>
<title>ble4.0蓝牙连接</title>
<link href="http://yangjingxuan.space/2016/08/20/BLE%204.0%E8%93%9D%E7%89%99%E8%BF%9E%E6%8E%A5/"/>
<id>http://yangjingxuan.space/2016/08/20/BLE 4.0蓝牙连接/</id>
<published>2016-08-20T08:31:10.000Z</published>
<updated>2016-09-21T03:10:31.000Z</updated>
<content type="html"><![CDATA[<p>从Android4.3(API 18) 开始,google开始引入低功耗蓝牙即蓝牙4.0模块,并提供了发现蓝牙,查询蓝牙Services和读写蓝牙特征值等api。 相比之前的传统蓝牙,低功耗蓝牙能显著的降低蓝牙设备功耗。</p>
<h5 id="关键名词解析"><a href="#关键名词解析" class="headerlink" title="关键名词解析"></a>关键名词解析</h5><p>GATT : GATT是一个通过的规范,ble上层的协议都是基于GATT,通过BLE连接发送与接收称为“属性”的数据块。目前所有的ble应用都是基于GATT。(这个通用的规范是指蓝牙设备如何在特定的应用程序中工作的规格说明)</p>
<a id="more"></a>
<p>ATT : GATT是在ATT协议的基础上建立的。ATT对BLE设备上的运行进行了优化,它使用了尽可能少的字节。每一个“属性”通过一个唯一的统一标识符uuid进行标识,每一个String类型的UUID使用128bit标准格式。“属性”通过ATT被格式化为characteristics和services。 </p>
<p>Characteristics : 特征值,一个特征值包括一个单一变量和0到n个用来描述该特征值的变量的Descriptor。一个特征值可以被理解成一个类型或者是一个类。</p>
<p>Descriptor : Descriptor被定义为描述特征值变量的值。例如:一个特征值可以被认为是一个可读的描述,或者一个特征值变量可以接受的范围,或者是一个特征值变量特定的测量单位。</p>
<p>Service : Service是特征值的集合。例如:可能有一个“心率监测仪”的service, 它可能包含了多个特征值,其中可能包括了一个叫做”心率测量”的特征值。</p>
<p>Profile : Profile描述了某个应用场景中设备有什么功能(执行什么工作)。在一个Profile里一般定义两个角色。如,一个报告者和一个监视着。</p>
<p>其中关系可以参考下图: <img src="http://obr1dwgsb.bkt.clouddn.com/%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7%202016-08-20%20%E4%B8%8B%E5%8D%884.30.23.png" alt="屏幕快照 2016-08-20 下午4.30.23"></p>
<h5 id="角色与责任"><a href="#角色与责任" class="headerlink" title="角色与责任"></a>角色与责任</h5><p>Android设备与BLE设备交互有两组角色:</p>
<p>中心设备(Central)与外围设备(Peripheral)</p>
<p>即包括:GATT server与 GATT client</p>
<p>以上的这两种角色主要是取决于在蓝牙设备ble连接成功后,上诉的这两个设备的通讯方式。</p>
<p>例如:当你有一部安卓手机与一个支持ble的蓝牙追踪器。Android手机作为一个中心设备,ble蓝牙追踪器作为一个外围设备。(为了建立蓝牙连接,必须要有一个设备充当中心设备与一个设备充当外围设备。如果两个设备同时是中心设备或外围设备是无法成功建立蓝牙连接)</p>
<p>一旦两者建立起连接后,便可以开始传输GATT协议的数据包,其中依据它们传输的数据形式,有一者充当Server的角色。例如,当ble追踪器想要给手机发送数据时,此时ble追踪器便充当着一个Server角色。而当手机要给ble追踪器发送数据时,手机便充当Server角色。</p>
<h5 id="蓝牙权限"><a href="#蓝牙权限" class="headerlink" title="蓝牙权限"></a>蓝牙权限</h5><p>为了在你的应用中使用蓝牙,你需要在manifest文件中添加蓝牙权限</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"><uses-permission android:name=<span class="string">"android.permission.BLUETOOTH"</span>/></span><br><span class="line"><uses-permission android:name=<span class="string">"android.permission.BLUETOOTH_ADMIN"</span>/></span><br><span class="line"><span class="comment">//如果想让你的app中,只支持ble蓝牙设备,可以加入以下声明</span></span><br><span class="line"><uses-feature android:name=<span class="string">"android.hardware.bluetooth_le"</span> android:required=<span class="string">"true"</span>/></span><br></pre></td></tr></table></figure>
<p>如果需要把app提供给不支持ble特性的蓝牙设备,需要将上面的声明改为 <code>android:required="fasle"</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="comment">// Initializes Bluetooth adapter.</span></span><br><span class="line"><span class="keyword">if</span> (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {</span><br><span class="line"> Toast.makeText(<span class="keyword">this</span>, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();</span><br><span class="line"> finish();</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h5 id="开始设置BLE"><a href="#开始设置BLE" class="headerlink" title="开始设置BLE"></a>开始设置BLE</h5><p>1.获取BluetoothAdapter,整个系统只有一个BluetoothAdapter。</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="comment">//初始化 BluetoothAdapter</span></span><br><span class="line"><span class="keyword">final</span> BluetoothManager bluetoothManager =</span><br><span class="line"> (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);</span><br><span class="line">mBluetoothAdapter = bluetoothManager.getAdapter();</span><br></pre></td></tr></table></figure>
<p>2.启动蓝牙</p>
<p>在开启蓝牙的时候应该优先判断BluetoothAdapter是否为空,并且蓝牙是否已经启动</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">private</span> BluetoothAdapter mBluetoothAdapter;</span><br><span class="line"><span class="comment">// 会弹出一个对话框询问用户是否开启蓝牙</span></span><br><span class="line"><span class="keyword">if</span> (mBluetoothAdapter == <span class="keyword">null</span> || !mBluetoothAdapter.isEnabled()) {</span><br><span class="line"> Intent enableBtIntent = <span class="keyword">new</span> Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);</span><br><span class="line"> startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h5 id="查找BLE蓝牙设备"><a href="#查找BLE蓝牙设备" class="headerlink" title="查找BLE蓝牙设备"></a>查找BLE蓝牙设备</h5><p>查找BLE设备的过程中,你可以使用<code>startLeScan()</code>方法进行蓝牙搜索,这个方法需要一个<code>BluetoothAdapter.LeScanCallback</code>作为参数,你需要去实现这个回调方法并判断哪些设备是你需要进行配对连接的。同时由于扫描是一个耗费手机电量的过程,因此需要遵循以下几点;</p>
<p>1.一旦扫描发现目标设备后,立即停止扫描</p>
<p>2.扫描超时后,应避免循环重复扫描浪费手机电量</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></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span><br><span class="line"> * Activity 扫描和发现蓝牙设备</span><br><span class="line"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">DeviceScanActivity</span> <span class="keyword">extends</span> <span class="title">ListActivity</span> </span>{</span><br><span class="line"></span><br><span class="line"> <span class="keyword">private</span> BluetoothAdapter mBluetoothAdapter;</span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">boolean</span> mScanning;</span><br><span class="line"> <span class="keyword">private</span> Handler mHandler;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 10秒后停止扫描</span></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">long</span> SCAN_PERIOD = <span class="number">10000</span>;</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">scanLeDevice</span><span class="params">(<span class="keyword">final</span> <span class="keyword">boolean</span> enable)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (enable) {</span><br><span class="line"> <span class="comment">// 超过你设定的超时时间后停止扫描</span></span><br><span class="line"> mHandler.postDelayed(<span class="keyword">new</span> Runnable() {</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"> mScanning = <span class="keyword">false</span>;</span><br><span class="line"> mBluetoothAdapter.stopLeScan(mLeScanCallback);</span><br><span class="line"> }</span><br><span class="line"> }, SCAN_PERIOD);</span><br><span class="line"></span><br><span class="line"> mScanning = <span class="keyword">true</span>;</span><br><span class="line"> mBluetoothAdapter.startLeScan(mLeScanCallback);</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> mScanning = <span class="keyword">false</span>;</span><br><span class="line"> mBluetoothAdapter.stopLeScan(mLeScanCallback);</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>如果你只需要扫描指定类型的外围设备时,你可以调用<code>startLeScan(UUID[], BluetoothAdapter.LeScanCallback)</code>只需要提供设备的uuid数组便可</p>
<p>以下是一个<code>LeScanCallback</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">private</span> LeDeviceListAdapter mLeDeviceListAdapter;</span><br><span class="line">...</span><br><span class="line"><span class="comment">// 蓝牙扫描 callback.</span></span><br><span class="line"><span class="keyword">private</span> BluetoothAdapter.LeScanCallback mLeScanCallback =</span><br><span class="line"> <span class="keyword">new</span> BluetoothAdapter.LeScanCallback() {</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">onLeScan</span><span class="params">(<span class="keyword">final</span> BluetoothDevice device, <span class="keyword">int</span> rssi,</span><br><span class="line"> <span class="keyword">byte</span>[] scanRecord)</span> </span>{</span><br><span class="line"> runOnUiThread(<span class="keyword">new</span> Runnable() {</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"> mLeDeviceListAdapter.addDevice(device);</span><br><span class="line"> mLeDeviceListAdapter.notifyDataSetChanged();</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>注意:搜索ble蓝牙与搜索普通蓝牙设备,不能同时进行搜索</p>
<h5 id="连接GATT-Server"><a href="#连接GATT-Server" class="headerlink" title="连接GATT Server"></a>连接GATT Server</h5><p>通过以下方法连接GATT Server</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">mBluetoothGatt = device.connectGatt(<span class="keyword">this</span>, <span class="keyword">false</span>, mGattCallback);</span><br></pre></td></tr></table></figure>
<p>连接成功后会返回一个<code>BluetoothGatt</code> 实例,通过这个实例可以进行GATT client 操作。此时app作为一个 GATT client ,而GattCallback是用来提供结果给客户端,例如连接状态等等。</p>
<h5 id="读取BLE属性"><a href="#读取BLE属性" class="headerlink" title="读取BLE属性"></a>读取BLE属性</h5><p>一旦你的app连接到一个GATT Server并且发现了服务services,就可以进行属性的读写操作了</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></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">DeviceControlActivity</span> <span class="keyword">extends</span> <span class="title">Activity</span> </span>{</span><br><span class="line"> ...</span><br><span class="line"> <span class="comment">// Demonstrates how to iterate through the supported GATT</span></span><br><span class="line"> <span class="comment">// Services/Characteristics.</span></span><br><span class="line"> <span class="comment">// In this sample, we populate the data structure that is bound to the</span></span><br><span class="line"> <span class="comment">// ExpandableListView on the UI.</span></span><br><span class="line"> <span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">displayGattServices</span><span class="params">(List<BluetoothGattService> gattServices)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (gattServices == <span class="keyword">null</span>) <span class="keyword">return</span>;</span><br><span class="line"> String uuid = <span class="keyword">null</span>;</span><br><span class="line"> String unknownServiceString = getResources().</span><br><span class="line"> getString(R.string.unknown_service);</span><br><span class="line"> String unknownCharaString = getResources().</span><br><span class="line"> getString(R.string.unknown_characteristic);</span><br><span class="line"> ArrayList<HashMap<String, String>> gattServiceData =</span><br><span class="line"> <span class="keyword">new</span> ArrayList<HashMap<String, String>>();</span><br><span class="line"> ArrayList<ArrayList<HashMap<String, String>>> gattCharacteristicData</span><br><span class="line"> = <span class="keyword">new</span> ArrayList<ArrayList<HashMap<String, String>>>();</span><br><span class="line"> mGattCharacteristics =</span><br><span class="line"> <span class="keyword">new</span> ArrayList<ArrayList<BluetoothGattCharacteristic>>();</span><br><span class="line"></span><br><span class="line"> <span class="comment">// Loops through available GATT Services.</span></span><br><span class="line"> <span class="keyword">for</span> (BluetoothGattService gattService : gattServices) {</span><br><span class="line"> HashMap<String, String> currentServiceData =</span><br><span class="line"> <span class="keyword">new</span> HashMap<String, String>();</span><br><span class="line"> uuid = gattService.getUuid().toString();</span><br><span class="line"> currentServiceData.put(</span><br><span class="line"> LIST_NAME, SampleGattAttributes.</span><br><span class="line"> lookup(uuid, unknownServiceString));</span><br><span class="line"> currentServiceData.put(LIST_UUID, uuid);</span><br><span class="line"> gattServiceData.add(currentServiceData);</span><br><span class="line"></span><br><span class="line"> ArrayList<HashMap<String, String>> gattCharacteristicGroupData =</span><br><span class="line"> <span class="keyword">new</span> ArrayList<HashMap<String, String>>();</span><br><span class="line"> List<BluetoothGattCharacteristic> gattCharacteristics =</span><br><span class="line"> gattService.getCharacteristics();</span><br><span class="line"> ArrayList<BluetoothGattCharacteristic> charas =</span><br><span class="line"> <span class="keyword">new</span> ArrayList<BluetoothGattCharacteristic>();</span><br><span class="line"> <span class="comment">// Loops through available Characteristics.</span></span><br><span class="line"> <span class="keyword">for</span> (BluetoothGattCharacteristic gattCharacteristic :</span><br><span class="line"> gattCharacteristics) {</span><br><span class="line"> charas.add(gattCharacteristic);</span><br><span class="line"> HashMap<String, String> currentCharaData =</span><br><span class="line"> <span class="keyword">new</span> HashMap<String, String>();</span><br><span class="line"> uuid = gattCharacteristic.getUuid().toString();</span><br><span class="line"> currentCharaData.put(</span><br><span class="line"> LIST_NAME, SampleGattAttributes.lookup(uuid,</span><br><span class="line"> unknownCharaString));</span><br><span class="line"> currentCharaData.put(LIST_UUID, uuid);</span><br><span class="line"> gattCharacteristicGroupData.add(currentCharaData);</span><br><span class="line"> }</span><br><span class="line"> mGattCharacteristics.add(charas);</span><br><span class="line"> gattCharacteristicData.add(gattCharacteristicGroupData);</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>
<h5 id="接受GATT通知"><a href="#接受GATT通知" class="headerlink" title="接受GATT通知"></a>接受GATT通知</h5><p>当蓝牙设备的特征改变时会通知ble程序,以下是设置特征值通知的例子</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="keyword">private</span> BluetoothGatt mBluetoothGatt;</span><br><span class="line">BluetoothGattCharacteristic characteristic;</span><br><span class="line"><span class="keyword">boolean</span> enabled;</span><br><span class="line">...</span><br><span class="line">mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);</span><br><span class="line">...</span><br><span class="line">BluetoothGattDescriptor descriptor = characteristic.getDescriptor(</span><br><span class="line"> UUID.fromString(SampleGattAttributes.CLIENT_CHARACTERISTIC_CONFIG));</span><br><span class="line">descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);</span><br><span class="line">mBluetoothGatt.writeDescriptor(descriptor);</span><br></pre></td></tr></table></figure>
<p>一旦启用特征值改变通知,当蓝牙设备特性发生变化后,便会回调函数<code>onCharacteristicChanged()</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></pre></td><td class="code"><pre><span class="line"><span class="meta">@Override</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">onCharacteristicChanged</span><span class="params">(BluetoothGatt gatt,</span><br><span class="line"> BluetoothGattCharacteristic characteristic)</span> </span>{</span><br><span class="line"> broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h5 id="关闭客户端连接"><a href="#关闭客户端连接" class="headerlink" title="关闭客户端连接"></a>关闭客户端连接</h5><p>在结束与ble设备的通讯后,需要结束并释放资源</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">public</span> <span class="keyword">void</span> <span class="title">close</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (mBluetoothGatt == <span class="keyword">null</span>) {</span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line"> }</span><br><span class="line"> mBluetoothGatt.close();</span><br><span class="line"> mBluetoothGatt = <span class="keyword">null</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>具体可以参考谷歌官方教程</p>
<p><a href="https://developer.android.com/guide/topics/connectivity/bluetooth-le.html" target="_blank" rel="external">Bluetooth Low Energy</a></p>
]]></content>
<summary type="html">
<p>从Android4.3(API 18) 开始,google开始引入低功耗蓝牙即蓝牙4.0模块,并提供了发现蓝牙,查询蓝牙Services和读写蓝牙特征值等api。 相比之前的传统蓝牙,低功耗蓝牙能显著的降低蓝牙设备功耗。</p>
<h5 id="关键名词解析"><a href="#关键名词解析" class="headerlink" title="关键名词解析"></a>关键名词解析</h5><p>GATT : GATT是一个通过的规范,ble上层的协议都是基于GATT,通过BLE连接发送与接收称为“属性”的数据块。目前所有的ble应用都是基于GATT。(这个通用的规范是指蓝牙设备如何在特定的应用程序中工作的规格说明)</p>
</summary>
<category term="开发小记" scheme="http://yangjingxuan.space/categories/%E5%BC%80%E5%8F%91%E5%B0%8F%E8%AE%B0/"/>
</entry>
<entry>
<title>WebChromeClient常用API与功能使用详解</title>
<link href="http://yangjingxuan.space/2016/05/17/WebChromeClient%E5%B8%B8%E7%94%A8API%E4%B8%8E%E5%8A%9F%E8%83%BD%E4%BD%BF%E7%94%A8%E8%AF%A6%E8%A7%A3/"/>
<id>http://yangjingxuan.space/2016/05/17/WebChromeClient常用API与功能使用详解/</id>
<published>2016-05-17T07:58:20.000Z</published>
<updated>2016-09-21T03:10:59.000Z</updated>
<content type="html"><![CDATA[<p>在WebView的开发过程中当你需要使用到一些高级功能可以通过设置WebChromeClient从而来辅助WebView处理 JavaScript 的对话框、网站图标、网站title、加载进度等。</p>
<h5 id="WebChromeClient常用的API方法"><a href="#WebChromeClient常用的API方法" class="headerlink" title="WebChromeClient常用的API方法"></a>WebChromeClient常用的API方法</h5><h6 id="1-通知应用程序当前网页加载的进度"><a href="#1-通知应用程序当前网页加载的进度" class="headerlink" title="1.通知应用程序当前网页加载的进度"></a>1.通知应用程序当前网页加载的进度</h6><a id="more"></a>
<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="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">(WebView view, <span class="keyword">int</span> newProgress)</span></span></span><br></pre></td></tr></table></figure>
<h6 id="2-获取网页title标题"><a href="#2-获取网页title标题" class="headerlink" title="2.获取网页title标题"></a>2.获取网页title标题</h6><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="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onReceivedTitle</span><span class="params">(WebView view, String title)</span></span></span><br></pre></td></tr></table></figure>
<p>获取标题的时间主要取决于网页前段设置标题的位置,一般设置在页面加载前面,可以较早调用到这个函数</p>
<h6 id="3-网页中有H5播放flash-video的时候按下全屏按钮将会调用到这个方法,一般用作设置网页播放全屏操作"><a href="#3-网页中有H5播放flash-video的时候按下全屏按钮将会调用到这个方法,一般用作设置网页播放全屏操作" class="headerlink" title="3.网页中有H5播放flash video的时候按下全屏按钮将会调用到这个方法,一般用作设置网页播放全屏操作"></a>3.网页中有H5播放flash video的时候按下全屏按钮将会调用到这个方法,一般用作设置网页播放全屏操作</h6><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="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onShowCustomView</span><span class="params">(View view, CustomViewCallback callback)</span></span></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></pre></td><td class="code"><pre><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">onHideCustomView</span><span class="params">()</span></span></span><br></pre></td></tr></table></figure></p>
<h4 id="WebView下载监听"><a href="#WebView下载监听" class="headerlink" title="WebView下载监听"></a>WebView下载监听</h4><p>通过设置webview下载监听进而监听网页下载<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">mWebView.setDownloadListener(<span class="keyword">new</span> DownloadListener() {</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">onDownloadStart</span><span class="params">(String url, String userAgent, String contentDisposition, String mimetype, <span class="keyword">long</span> contentLength)</span> </span>{</span><br><span class="line"> }</span><br><span class="line">});</span><br></pre></td></tr></table></figure></p>
<p>一般可在downloadStart 处进行下载处理</p>
<h5 id="WebChromeClient高级功能实现"><a href="#WebChromeClient高级功能实现" class="headerlink" title="WebChromeClient高级功能实现"></a>WebChromeClient高级功能实现</h5><h6 id="1-让你的webview支持File-Input-标签"><a href="#1-让你的webview支持File-Input-标签" class="headerlink" title="1.让你的webview支持File Input 标签"></a>1.让你的webview支持File Input 标签</h6><p>在Android 5.0 API 21后 借助新的 <em>onShowFileChooser()</em> 方法,您现在不但可以在 WebView 中使用输入表单字段,而且可以启动文件选择器从 Android 设备中选择图片和文件</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></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">onShowFileChooser</span><span class="params">(WebView webView, ValueCallback<Uri[]> filePathCallback,</span><br><span class="line"> WebChromeClient.FileChooserParams fileChooserParams)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (mFilePathCallback != <span class="keyword">null</span>) {</span><br><span class="line"> mFilePathCallback.onReceiveValue(<span class="keyword">null</span>);</span><br><span class="line"> }</span><br><span class="line"> mFilePathCallback = filePathCallback;</span><br><span class="line"></span><br><span class="line"> Intent takePictureIntent = <span class="keyword">new</span> Intent(MediaStore.ACTION_IMAGE_CAPTURE);</span><br><span class="line"> <span class="keyword">if</span> (takePictureIntent.resolveActivity(getPackageManager()) != <span class="keyword">null</span>) {</span><br><span class="line"> <span class="comment">// Create the File where the photo should go</span></span><br><span class="line"> File photoFile = <span class="keyword">null</span>;</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> photoFile = createImageFile();</span><br><span class="line"> takePictureIntent.putExtra(<span class="string">"PhotoPath"</span>, mCameraPhotoPath);</span><br><span class="line"> } <span class="keyword">catch</span> (IOException ex) {</span><br><span class="line"> <span class="comment">// Error occurred while creating the File</span></span><br><span class="line"> Log.e(TAG, <span class="string">"Unable to create Image File"</span>, ex);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">// Continue only if the File was successfully created</span></span><br><span class="line"> <span class="keyword">if</span> (photoFile != <span class="keyword">null</span>) {</span><br><span class="line"> mCameraPhotoPath = <span class="string">"file:"</span> + photoFile.getAbsolutePath();</span><br><span class="line"> takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,</span><br><span class="line"> Uri.fromFile(photoFile));</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> takePictureIntent = <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"> Intent contentSelectionIntent = <span class="keyword">new</span> Intent(Intent.ACTION_GET_CONTENT);</span><br><span class="line"> contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);</span><br><span class="line"> contentSelectionIntent.setType(<span class="string">"image/*"</span>);</span><br><span class="line"></span><br><span class="line"> Intent[] intentArray;</span><br><span class="line"> <span class="keyword">if</span> (takePictureIntent != <span class="keyword">null</span>) {</span><br><span class="line"> intentArray = <span class="keyword">new</span> Intent[]{takePictureIntent};</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> intentArray = <span class="keyword">new</span> Intent[<span class="number">0</span>];</span><br><span class="line"> }</span><br><span class="line"> Intent chooserIntent = <span class="keyword">new</span> Intent(Intent.ACTION_CHOOSER);</span><br><span class="line"> chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);</span><br><span class="line"> chooserIntent.putExtra(Intent.EXTRA_TITLE, <span class="string">"Image Chooser"</span>);</span><br><span class="line"> chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);</span><br><span class="line"> startActivityForResult(chooserIntent, INPUT_FILE_REQUEST_CODE);</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>在选择完图片后回调onActivityResult 获取图片<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></pre></td><td class="code"><pre><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">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">if</span> (requestCode != INPUT_FILE_REQUEST_CODE || mFilePathCallback == <span class="keyword">null</span>) {</span><br><span class="line"> <span class="keyword">super</span>.onActivityResult(requestCode, resultCode, data);</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"> Uri[] results = <span class="keyword">null</span>;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// Check that the response is a good one</span></span><br><span class="line"> <span class="keyword">if</span> (resultCode == Activity.RESULT_OK) {</span><br><span class="line"> <span class="keyword">if</span> (data == <span class="keyword">null</span>) {</span><br><span class="line"> <span class="comment">// If there is not data, then we may have taken a photo</span></span><br><span class="line"> <span class="keyword">if</span> (mCameraPhotoPath != <span class="keyword">null</span>) {</span><br><span class="line"> results = <span class="keyword">new</span> Uri[]{Uri.parse(mCameraPhotoPath)};</span><br><span class="line"> }</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> String dataString = data.getDataString();</span><br><span class="line"> <span class="keyword">if</span> (dataString != <span class="keyword">null</span>) {</span><br><span class="line"> results = <span class="keyword">new</span> Uri[]{Uri.parse(dataString)};</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"> mFilePathCallback.onReceiveValue(results);</span><br><span class="line"> mFilePathCallback = <span class="keyword">null</span>;</span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<h6 id="2-支持全屏视频播放"><a href="#2-支持全屏视频播放" class="headerlink" title="2.支持全屏视频播放"></a>2.支持全屏视频播放</h6><p>设置webview视频未播放时默认显示占位图<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="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> Bitmap <span class="title">getDefaultVideoPoster</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">if</span>(getActivity() == <span class="keyword">null</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="keyword">return</span> BitmapFactory.decodeResource(getActivity().getApplicationContext().getResources(),</span><br><span class="line"> R.drawable.video_poster);</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<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><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="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onShowCustomView</span><span class="params">(View view,</span><br><span class="line"> WebChromeClient.CustomViewCallback callback)</span> </span>{</span><br><span class="line"> <span class="comment">// if a view already exists then immediately terminate the new one</span></span><br><span class="line"> <span class="keyword">if</span> (mCustomView != <span class="keyword">null</span>) {</span><br><span class="line"> onHideCustomView();</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">// 1. Stash the current state</span></span><br><span class="line"> mCustomView = view;</span><br><span class="line"> mOriginalSystemUiVisibility = getActivity().getWindow().getDecorView().getSystemUiVisibility();</span><br><span class="line"> mOriginalOrientation = getActivity().getRequestedOrientation();</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 2. Stash the custom view callback</span></span><br><span class="line"> mCustomViewCallback = callback;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 3. Add the custom view to the view hierarchy</span></span><br><span class="line"> FrameLayout decor = (FrameLayout) getActivity().getWindow().getDecorView();</span><br><span class="line"> decor.addView(mCustomView, <span class="keyword">new</span> FrameLayout.LayoutParams(</span><br><span class="line"> ViewGroup.LayoutParams.MATCH_PARENT,</span><br><span class="line"> ViewGroup.LayoutParams.MATCH_PARENT));</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> <span class="comment">// 4. Change the state of the window</span></span><br><span class="line"> getActivity().getWindow().getDecorView().setSystemUiVisibility(</span><br><span class="line"> View.SYSTEM_UI_FLAG_LAYOUT_STABLE |</span><br><span class="line"> View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |</span><br><span class="line"> View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |</span><br><span class="line"> View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |</span><br><span class="line"> View.SYSTEM_UI_FLAG_FULLSCREEN |</span><br><span class="line"> View.SYSTEM_UI_FLAG_IMMERSIVE);</span><br><span class="line"> getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<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><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="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onHideCustomView</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="comment">// 1. Remove the custom view</span></span><br><span class="line"> FrameLayout decor = (FrameLayout) getActivity().getWindow().getDecorView();</span><br><span class="line"> decor.removeView(mCustomView);</span><br><span class="line"> mCustomView = <span class="keyword">null</span>;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 2. Restore the state to it's original form</span></span><br><span class="line"> getActivity().getWindow().getDecorView()</span><br><span class="line"> .setSystemUiVisibility(mOriginalSystemUiVisibility);</span><br><span class="line"> getActivity().setRequestedOrientation(mOriginalOrientation);</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 3. Call the custom view callback</span></span><br><span class="line"> mCustomViewCallback.onCustomViewHidden();</span><br><span class="line"> mCustomViewCallback = <span class="keyword">null</span>;</span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>具体实例可以参照 GoogleChrome高级使用实例<br>[<a href="https://github.com/GoogleChrome/chromium-webview-samples" target="_blank" rel="external">https://github.com/GoogleChrome/chromium-webview-samples</a>]</p>
<p>下篇将讲解WebView优化以及在开发过程中常遇到的问题</p>
]]></content>
<summary type="html">
<p>在WebView的开发过程中当你需要使用到一些高级功能可以通过设置WebChromeClient从而来辅助WebView处理 JavaScript 的对话框、网站图标、网站title、加载进度等。</p>
<h5 id="WebChromeClient常用的API方法"><a href="#WebChromeClient常用的API方法" class="headerlink" title="WebChromeClient常用的API方法"></a>WebChromeClient常用的API方法</h5><h6 id="1-通知应用程序当前网页加载的进度"><a href="#1-通知应用程序当前网页加载的进度" class="headerlink" title="1.通知应用程序当前网页加载的进度"></a>1.通知应用程序当前网页加载的进度</h6>
</summary>
<category term="开发小记" scheme="http://yangjingxuan.space/categories/%E5%BC%80%E5%8F%91%E5%B0%8F%E8%AE%B0/"/>
</entry>
<entry>
<title>Android WebView 项目使用总结</title>
<link href="http://yangjingxuan.space/2016/04/29/Android%20WebView%20%E9%A1%B9%E7%9B%AE%E4%BD%BF%E7%94%A8%E6%80%BB%E7%BB%93/"/>
<id>http://yangjingxuan.space/2016/04/29/Android WebView 项目使用总结/</id>
<published>2016-04-29T10:43:29.000Z</published>
<updated>2016-09-21T03:13:01.000Z</updated>
<content type="html"><![CDATA[<p>由于前段时间的项目对WebView的使用较多,因此总结一下项目中WebView的使用使用过程,以及一些值得注意的地方。</p>
<p>WebView 在大部分的WebApp中使用相当广泛,处理好WebView也是一个WebApp的关键</p>
<p>目前的WebView是基于webkit 内核浏览器并且封装在android 的sdk 当中,并且WebView包括以下几个功能</p>
<ul>
<li>1.加载网站url和加载本地html页面</li>
<li>2.可以与JavaScript代码进行交互</li>
<li>3.webview控件可以高度进行定制</li>
</ul>
<a id="more"></a>
<h4 id="在WebView使用过程中应当注意一下几点"><a href="#在WebView使用过程中应当注意一下几点" class="headerlink" title="在WebView使用过程中应当注意一下几点"></a>在WebView使用过程中应当注意一下几点</h4><h5 id="1-在AndroidManifest-xml-中添加网络访问权限"><a href="#1-在AndroidManifest-xml-中添加网络访问权限" class="headerlink" title="1. 在AndroidManifest.xml 中添加网络访问权限"></a>1. 在AndroidManifest.xml 中添加网络访问权限</h5><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-permission android:name=<span class="string">"android.permission.INTERNET"</span> /></span><br></pre></td></tr></table></figure>
<h5 id="2-在WebView中有一个辅助类WebSettings,通过他管理WebView的一些状态以及插件"><a href="#2-在WebView中有一个辅助类WebSettings,通过他管理WebView的一些状态以及插件" class="headerlink" title="2. 在WebView中有一个辅助类WebSettings,通过他管理WebView的一些状态以及插件"></a>2. 在WebView中有一个辅助类WebSettings,通过他管理WebView的一些状态以及插件</h5><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="comment">// webview启用javascript支持 用于访问页面中的javascript</span></span><br><span class="line">webSettings.setJavaScriptEnabled(<span class="keyword">true</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">//设置WebView缓存模式 默认断网情况下不缓存</span></span><br><span class="line">webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);</span><br><span class="line"></span><br><span class="line"><span class="comment">//断网情况下加载本地缓存</span></span><br><span class="line">webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);}</span><br><span class="line"></span><br><span class="line"><span class="comment">//让WebView支持DOM storage API</span></span><br><span class="line">webSettings.setDomStorageEnabled(<span class="keyword">true</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">//让WebView支持缩放</span></span><br><span class="line">webSettings.setSupportZoom(<span class="keyword">true</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">//启用WebView内置缩放功能</span></span><br><span class="line">webSettings.setBuiltInZoomControls(<span class="keyword">true</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">//让WebView支持可任意比例缩放</span></span><br><span class="line">webSettings.setUseWideViewPort(<span class="keyword">true</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">//让WebView支持播放插件</span></span><br><span class="line">webSettings.setPluginState(WebSettings.PluginState.ON);</span><br><span class="line"></span><br><span class="line"><span class="comment">//设置WebView使用内置缩放机制时,是否展现在屏幕缩放控件上</span></span><br><span class="line">webSettings.setDisplayZoomControls(<span class="keyword">false</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">//设置在WebView内部是否允许访问文件</span></span><br><span class="line">webSettings.setAllowFileAccess(<span class="keyword">true</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">//设置WebView的访问UserAgent</span></span><br><span class="line">webSettings.setUserAgentString(WebViewUtil.getUserAgent(getActivity(), webSettings));</span><br><span class="line"></span><br><span class="line"><span class="comment">//设置脚本是否允许自动打开弹窗</span></span><br><span class="line">webSettings.setJavaScriptCanOpenWindowsAutomatically(<span class="keyword">true</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 加快HTML网页加载完成速度 </span></span><br><span class="line"><span class="keyword">if</span> (Build.VERSION.SDK_INT >= <span class="number">19</span>) { </span><br><span class="line"> settings.setLoadsImagesAutomatically(<span class="keyword">true</span>);</span><br><span class="line">} <span class="keyword">else</span> {</span><br><span class="line"> settings.setLoadsImagesAutomatically(<span class="keyword">false</span>); </span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 开启Application H5 Caches 功能 </span></span><br><span class="line">settings.setAppCacheEnabled(<span class="keyword">true</span>); </span><br><span class="line"></span><br><span class="line"><span class="comment">// 设置编码格式</span></span><br><span class="line">settings.setDefaultTextEncodingName(<span class="string">"utf-8"</span>);</span><br></pre></td></tr></table></figure>
<h5 id="3-当页面需要调用我们一些原生native的功能时候,可以通过我们自定义的JS接口去实现"><a href="#3-当页面需要调用我们一些原生native的功能时候,可以通过我们自定义的JS接口去实现" class="headerlink" title="3.当页面需要调用我们一些原生native的功能时候,可以通过我们自定义的JS接口去实现"></a>3.当页面需要调用我们一些原生native的功能时候,可以通过我们自定义的JS接口去实现</h5><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><br><span class="line"><span class="comment">//设置WebView JavaScript接口可以供页面JS调用</span></span><br><span class="line">mWebView.addJavascriptInterface(<span class="keyword">new</span> JsInterface(), AppUtil.KEY_JS_INTERFACE_NAME);</span><br></pre></td></tr></table></figure>
<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><span class="line">12</span><br></pre></td><td class="code"><pre><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">JsInterface</span> </span>{ </span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">JsInterface</span><span class="params">()</span> </span>{ </span><br><span class="line"> <span class="meta">@JavascriptInterface</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">showToast</span><span class="params">(String msg, <span class="keyword">int</span> delayType)</span> </span>{ </span><br><span class="line"> Message message = <span class="keyword">new</span> Message();</span><br><span class="line"> message.what = SHOW_TOAST;</span><br><span class="line"> message.arg1 = delayType;</span><br><span class="line"> message.obj = msg;mHandler.sendMessage(message);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<h5 id="4-设定WebViewClient和WebChromeClient实现WebView更多功能"><a href="#4-设定WebViewClient和WebChromeClient实现WebView更多功能" class="headerlink" title="4.设定WebViewClient和WebChromeClient实现WebView更多功能"></a>4.设定WebViewClient和WebChromeClient实现WebView更多功能</h5><p>通过设置WebViewClient获取页面标题与页面中连接跳转的处理</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></pre></td><td class="code"><pre><span class="line">mWebView.setWebViewClient(<span class="keyword">new</span> WebViewClient() {</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">onPageFinished</span><span class="params">(WebView view, String url)</span> </span>{</span><br><span class="line"> <span class="comment">//可以获取到WebView的标题Title</span></span><br><span class="line"> setTitle(view.getTitle());</span><br><span class="line"> <span class="keyword">super</span>.onPageFinished(view, url);</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">shouldOverrideUrlLoading</span><span class="params">(WebView view, String url)</span> </span>{</span><br><span class="line"> <span class="comment">//WebVeiw中连接跳转进行处理跳转到新的Activity</span></span><br><span class="line"> <span class="keyword">if</span> (WebIntentUtil.isDetailsPage(url)) {</span><br><span class="line"> Intent intent = <span class="keyword">new</span> Intent(EmbeddedBrowserActivity.<span class="keyword">this</span>, DetailsActivity.class);</span><br><span class="line"> intent.putExtra(BbsServerUtil.KEY_URL, url);</span><br><span class="line"> startActivity(intent);</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">super</span>.shouldOverrideUrlLoading(view, url);</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><p>由于WebChromeClient的功能较多,所以分为两部分<br>将一起在下篇与WebView的WebChromeClient一起讲解<br><a href="http://yangjingxuan.github.io/2016/05/17/WebChromeClient%E5%B8%B8%E7%94%A8API%E4%B8%8E%E5%8A%9F%E8%83%BD%E4%BD%BF%E7%94%A8%E8%AF%A6%E8%A7%A3/#more" target="_blank" rel="external">WebChromeClient常用API与功能使用详解</a></p>
]]></content>
<summary type="html">
<p>由于前段时间的项目对WebView的使用较多,因此总结一下项目中WebView的使用使用过程,以及一些值得注意的地方。</p>
<p>WebView 在大部分的WebApp中使用相当广泛,处理好WebView也是一个WebApp的关键</p>
<p>目前的WebView是基于webkit 内核浏览器并且封装在android 的sdk 当中,并且WebView包括以下几个功能</p>
<ul>
<li>1.加载网站url和加载本地html页面</li>
<li>2.可以与JavaScript代码进行交互</li>
<li>3.webview控件可以高度进行定制</li>
</ul>
</summary>
<category term="开发小记" scheme="http://yangjingxuan.space/categories/%E5%BC%80%E5%8F%91%E5%B0%8F%E8%AE%B0/"/>
</entry>
<entry>
<title>Android开发中Git-Flow的运用</title>
<link href="http://yangjingxuan.space/2016/04/21/Android%E5%BC%80%E5%8F%91%E4%B8%ADGit-Flow%E7%9A%84%E8%BF%90%E7%94%A8/"/>
<id>http://yangjingxuan.space/2016/04/21/Android开发中Git-Flow的运用/</id>
<published>2016-04-21T07:37:24.000Z</published>
<updated>2016-08-23T05:48:25.000Z</updated>
<content type="html"><![CDATA[<p>Android开发过程中运用好Git工具能让团队的效率更进一步提升<br>Git-Flow是一套基于Git的扩展,通过分支模型对Git进行的一套更高层的操作。Git-Flow的运用可以使版本的迭代与演化过程更加清晰,同时运用的分支功能更加明确,主干分支更清晰。<br><a id="more"></a></p>
<h3 id="Git-Flow分支"><a href="#Git-Flow分支" class="headerlink" title="Git-Flow分支"></a>Git-Flow分支</h3><p><img src="http://i3.piimg.com/110e12cc631f96b3.png" alt="5大分支"></p>
<ul>
<li>主分支:master <ul>
<li>只有一个主分支,所有的正式版本都应该在这个主分支上发布</li>
</ul>
</li>
<li>开发分支: develop <ul>
<li>日常的开发工作都在这条开发分支上进行</li>
</ul>
</li>
<li>版本应急修复分支 :hotfix <ul>
<li>临时性分支:版本在上线的时候遇到紧急bug需要修复而开的分支,该分支由master分出完成后合入master与develop</li>
</ul>
</li>
<li>版本上线前预发布分支: release <ul>
<li>临时性分支:在开发分支即将合入master分支前,需要测试进行版本测试,该分支由develop分出完成后合入master与develop</li>
</ul>
</li>
<li>新功能开发分支: feature <ul>
<li>临时性分支:为了开发某一个特点功能的分支,由develop分出开发完成后合入</li>
</ul>
</li>
</ul>
<p>Git分支上只有master与develop保持常有,其余分支均在完成自身功能后及时删除</p>
<h3 id="常用命令"><a href="#常用命令" class="headerlink" title="常用命令"></a>常用命令</h3><p>远程代码库拉取<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git <span class="built_in">clone</span> <span class="comment">#远程代码仓库</span></span><br></pre></td></tr></table></figure></p>
<p>查看代码分支<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git branch <span class="_">-a</span></span><br></pre></td></tr></table></figure></p>
<p>创建develop分支<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"> git checkout -b develop master</span><br></pre></td></tr></table></figure></p>
<p>切换分支<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git checkout develop</span><br></pre></td></tr></table></figure></p>
<p>分支合并<br><figure class="highlight bash"><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">#切换master分支</span></span><br><span class="line">git checkout master</span><br><span class="line"><span class="comment">#对develop分支进行合并</span></span><br><span class="line"><span class="comment">#快进式合并</span></span><br><span class="line">git merge develop</span><br><span class="line"><span class="comment">#非快进式合并</span></span><br><span class="line">git merge --no-ff develop</span><br></pre></td></tr></table></figure></p>
<p>这里说明一下 合并方式有两种</p>
<ul>
<li>快进式合并:<br>由master分支直接指向develop分支,其中不会保留合并过程的开发记录</li>
<li>非快进式合并:<br>使用 <code>--no-ff</code> 参数git会在master分支提交一个commit记录,并保留方便后续查看<br><img src="http://i3.piimg.com/432b26a4ba9b48f1.png" alt="两种合并方式"></li>
</ul>
<p>查看当前代码库状态,日志<br><figure class="highlight bash"><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">git status</span><br><span class="line"><span class="comment">#代码库日志</span></span><br><span class="line">git <span class="built_in">log</span></span><br></pre></td></tr></table></figure></p>
<p>代码提交<br><figure class="highlight bash"><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">git add .</span><br><span class="line"><span class="comment">#代码提交</span></span><br><span class="line">git commit -am <span class="string">"#提交内容"</span></span><br></pre></td></tr></table></figure></p>
<h3 id="开发工具的运用(Source-Tree)"><a href="#开发工具的运用(Source-Tree)" class="headerlink" title="开发工具的运用(Source Tree)"></a>开发工具的运用(Source Tree)</h3><p>作为Git最实用的开发工具Source Tree拥有便捷的可视化操作<br><img src="http://i3.piimg.com/020cc40596ecdc17.png" alt="sourceTree 可视化操作"><br>只需要鼠标点击就能够完成以上的一系列操作,还有标签等让Git操作更加直观<br><a href="https://www.sourcetreeapp.com/" target="_blank" rel="external">SourceTree下载</a></p>
]]></content>
<summary type="html">
<p>Android开发过程中运用好Git工具能让团队的效率更进一步提升<br>Git-Flow是一套基于Git的扩展,通过分支模型对Git进行的一套更高层的操作。Git-Flow的运用可以使版本的迭代与演化过程更加清晰,同时运用的分支功能更加明确,主干分支更清晰。<br>
</summary>
<category term="开发小记" scheme="http://yangjingxuan.space/categories/%E5%BC%80%E5%8F%91%E5%B0%8F%E8%AE%B0/"/>
</entry>
<entry>
<title>Android项目中值得注意的编码规范(一)</title>
<link href="http://yangjingxuan.space/2016/04/13/Android%E9%A1%B9%E7%9B%AE%E4%B8%AD%E5%80%BC%E5%BE%97%E6%B3%A8%E6%84%8F%E7%9A%84%E7%BC%96%E7%A0%81%E8%A7%84%E8%8C%83%EF%BC%88%E4%B8%80%EF%BC%89/"/>
<id>http://yangjingxuan.space/2016/04/13/Android项目中值得注意的编码规范(一)/</id>
<published>2016-04-13T12:02:49.000Z</published>
<updated>2016-09-21T03:10:21.000Z</updated>
<content type="html"><![CDATA[<p>目前开发Android的主流语言为Java,本文为作者针对Java开发语言以及在开发Android项目过程中碰到的一些编码规范问题做出以下整理。</p>
<h3 id="1-命名规范"><a href="#1-命名规范" class="headerlink" title="1.命名规范"></a>1.命名规范</h3><p>Android开发的过程中好的命名规范显得尤为重要,好的包命名规范可以使项目代码样式统一,使程序有良好的可读性</p>
<a id="more"></a>
<h4 id="1-类命名"><a href="#1-类命名" class="headerlink" title="1.类命名"></a>1.类命名</h4><p> 类名(首单词字母大写)</p>
<h5 id="1-activity类"><a href="#1-activity类" class="headerlink" title="1.activity类"></a>1.activity类</h5><p> 命名以Activity为后缀</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"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">YunmaiActivity</span> <span class="keyword">extends</span> <span class="title">DeviceBaseActivity</span></span></span><br></pre></td></tr></table></figure>
<h5 id="2-fragment类"><a href="#2-fragment类" class="headerlink" title="2.fragment类"></a>2.fragment类</h5><p>命名以Fragment为后缀</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"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">HomeFragment</span> <span class="keyword">extends</span> <span class="title">BaseSupportFragment</span></span></span><br></pre></td></tr></table></figure>
<h5 id="3-service类"><a href="#3-service类" class="headerlink" title="3.service类"></a>3.service类</h5><p>命名以Service为后缀</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"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">BleGattService</span></span></span><br></pre></td></tr></table></figure>
<h5 id="4-adapter类"><a href="#4-adapter类" class="headerlink" title="4.adapter类"></a>4.adapter类</h5><p>命名以Adapter为后缀</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"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">AirSelectAdapter</span> <span class="keyword">extends</span> <span class="title">BaseAdapter</span></span></span><br></pre></td></tr></table></figure>
<h5 id="5-接口实现类"><a href="#5-接口实现类" class="headerlink" title="5.接口实现类"></a>5.接口实现类</h5><p>命名以Impl为后缀</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"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">YunmaiServiceImpl</span> <span class="keyword">implements</span> <span class="title">YunmaiService</span></span></span><br></pre></td></tr></table></figure>
<h5 id="6-工具类"><a href="#6-工具类" class="headerlink" title="6.工具类"></a>6.工具类</h5><p>命名以Util为后缀</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"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">AirBoxUtil</span></span></span><br></pre></td></tr></table></figure>
<h4 id="2-常量命名"><a href="#2-常量命名" class="headerlink" title="2.常量命名"></a>2.常量命名</h4><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"><span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">int</span> SHOW_POPUP_WINDOW = <span class="number">0x1000</span>;</span><br><span class="line"><span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">int</span> DISMISS_LOADING_VIEW = <span class="number">0x1100</span>;</span><br><span class="line"><span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">int</span> SHOW_LOADING_FAIL_VIEW = <span class="number">0x1110</span>;</span><br></pre></td></tr></table></figure>
<h4 id="3-方法命名"><a href="#3-方法命名" class="headerlink" title="3.方法命名"></a>3.方法命名</h4><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><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> ActionBar <span class="title">getActivityActionBar</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> mActionBar;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h4 id="4-变量名"><a href="#4-变量名" class="headerlink" title="4. 变量名"></a>4. 变量名</h4><p>全局变量(首字母以小写m开头)<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">mDeviceName</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></pre></td><td class="code"><pre><span class="line">name</span><br></pre></td></tr></table></figure></p>
<h3 id="2-控件缩写"><a href="#2-控件缩写" class="headerlink" title="2.控件缩写"></a>2.控件缩写</h3><p>在代码中使用到的控件应当遵守以下规范</p>
<table>
<thead>
<tr>
<th style="text-align:center">控件</th>
<th style="text-align:center">缩写</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:center">TextView</td>
<td style="text-align:center">Txt</td>
</tr>
<tr>
<td style="text-align:center">EditText</td>
<td style="text-align:center">Edt</td>
</tr>
<tr>
<td style="text-align:center">Button</td>
<td style="text-align:center">Btn</td>
</tr>
<tr>
<td style="text-align:center">ImageButton</td>
<td style="text-align:center">Ibtn</td>
</tr>
<tr>
<td style="text-align:center">ImageView</td>
<td style="text-align:center">Img</td>
</tr>
<tr>
<td style="text-align:center">ListView</td>
<td style="text-align:center">List</td>
</tr>
<tr>
<td style="text-align:center">RadioGroup</td>
<td style="text-align:center">Group</td>
</tr>
<tr>
<td style="text-align:center">RadioButton</td>
<td style="text-align:center">Rbtn</td>
</tr>
<tr>
<td style="text-align:center">ProgressBar</td>
<td style="text-align:center">Progress</td>
</tr>
<tr>
<td style="text-align:center">SeekBar</td>
<td style="text-align:center">Seek</td>
</tr>
<tr>
<td style="text-align:center">CheckBox</td>
<td style="text-align:center">Chk</td>
</tr>
<tr>
<td style="text-align:center">Spinner</td>
<td style="text-align:center">Spinner</td>
</tr>
<tr>
<td style="text-align:center">TableLayout</td>
<td style="text-align:center">Table</td>
</tr>
<tr>
<td style="text-align:center">TableRow</td>
<td style="text-align:center">Row</td>
</tr>
<tr>
<td style="text-align:center">LinearLayout</td>
<td style="text-align:center">Llayout</td>
</tr>
<tr>
<td style="text-align:center">RelativeLayout</td>
<td style="text-align:center">Rlayout</td>
</tr>
<tr>
<td style="text-align:center">ScrollView</td>
<td style="text-align:center">Scroll</td>
</tr>
<tr>
<td style="text-align:center">SearchView</td>
<td style="text-align:center">Search</td>
</tr>
<tr>
<td style="text-align:center">TabHost</td>
<td style="text-align:center">Host</td>
</tr>
<tr>
<td style="text-align:center">TabWidget</td>
<td style="text-align:center">Widget</td>
</tr>
</tbody>
</table>
<h3 id="3-布局缩写"><a href="#3-布局缩写" class="headerlink" title="3.布局缩写"></a>3.布局缩写</h3><p>布局的xml文件应该遵循如下规范</p>
<table>
<thead>
<tr>
<th style="text-align:center">布局</th>
<th style="text-align:center">命名</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:center">Activity</td>
<td style="text-align:center">以activity_</td>
</tr>
<tr>
<td style="text-align:center">Fragment</td>
<td style="text-align:center">以fragment_</td>
</tr>
<tr>
<td style="text-align:center">Dialog</td>
<td style="text-align:center">以dialog_</td>
</tr>
<tr>
<td style="text-align:center">ListView的item</td>
<td style="text-align:center">以item<em>list</em></td>
</tr>
<tr>
<td style="text-align:center">GridView的item</td>
<td style="text-align:center">以item_grid</td>
</tr>
<tr>
<td style="text-align:center">ListView的HeaderView</td>
<td style="text-align:center">以header_list</td>
</tr>
<tr>
<td style="text-align:center">ListView的FooterView</td>
<td style="text-align:center">以footer_list</td>
</tr>
</tbody>
</table>
]]></content>
<summary type="html">
<p>目前开发Android的主流语言为Java,本文为作者针对Java开发语言以及在开发Android项目过程中碰到的一些编码规范问题做出以下整理。</p>
<h3 id="1-命名规范"><a href="#1-命名规范" class="headerlink" title="1.命名规范"></a>1.命名规范</h3><p>Android开发的过程中好的命名规范显得尤为重要,好的包命名规范可以使项目代码样式统一,使程序有良好的可读性</p>
</summary>
<category term="开发小记" scheme="http://yangjingxuan.space/categories/%E5%BC%80%E5%8F%91%E5%B0%8F%E8%AE%B0/"/>
</entry>
<entry>
<title>做一个“懒惰”又有效率的Android开发者</title>
<link href="http://yangjingxuan.space/2015/04/29/%E5%81%9A%E4%B8%80%E4%B8%AA%E2%80%9C%E6%87%92%E6%83%B0%E2%80%9D%E5%8F%88%E6%9C%89%E6%95%88%E7%8E%87%E7%9A%84Android%E5%BC%80%E5%8F%91%E8%80%85/"/>
<id>http://yangjingxuan.space/2015/04/29/做一个“懒惰”又有效率的Android开发者/</id>
<published>2015-04-29T09:08:00.000Z</published>
<updated>2017-03-29T02:16:20.000Z</updated>
<content type="html"><![CDATA[<p>在Android开发过程中你可能会遇到那些繁琐的重复性劳动工作,怎样减少这类重复性劳动,下面就介绍一些实用的开发小工具来提升开发过程中的效率。<a id="more"></a><br></p><h4>1.TinyPNG</h4><div class="image-package"><img src="http://obr1dwgsb.bkt.clouddn.com/1.png" data-original-src="http://upload-images.jianshu.io/upload_images/99120-296876da316e2f2e.png" data-image-slug="296876da316e2f2e" data-width="2118" data-height="402"><br><div class="image-caption"><a href="https://tinypng.com/" target="_blank" rel="external">https://tinypng.com/</a></div></div><p>当你发现整个程序的App包越来越大的时候,程序中包含的图片资源越来越多,那么你应该考虑一下优化或压缩一下程序中所使用的图片资源。TinyPNG正是一款可以极大程度压缩png图片大小而又不会让图片质量严重损耗的小工具。</p><div class="image-package"><img src="http://obr1dwgsb.bkt.clouddn.com/2.png" data-original-src="http://upload-images.jianshu.io/upload_images/99120-2220aeabe7090d55.png" data-image-slug="2220aeabe7090d55" data-width="1194" data-height="488"><br><div class="image-caption"></div></div><p><br></p><h4>2.Android Layout Finder</h4><div class="image-package"><img src="http://obr1dwgsb.bkt.clouddn.com/3.png" data-original-src="http://upload-images.jianshu.io/upload_images/99120-f92ad9b64ca5318c.png" data-image-slug="f92ad9b64ca5318c" data-width="1896" data-height="1504"><br><div class="image-caption"><a href="https://www.buzzingandroid.com/tools/android-layout-finder/" target="_blank" rel="external">https://www.buzzingandroid.com/tools/android-layout-finder/</a></div></div><p>你还在为查找Android资源id,findViewById而苦恼不已? 那么现在你可以试试这款Android Layout Finder 小工具。 在你写完Activity或Fragment布局文件后,你可以将这些布局代码黏贴到 Android Layout Finder 上,选择你需要用到的资源,这款工具能通过布局文件中定义好的资源id,统一生成findView java代码。</p><p><br></p><h4>3.Android Asset Studio</h4><div class="image-package"><img src="http://obr1dwgsb.bkt.clouddn.com/4.png" data-original-src="http://upload-images.jianshu.io/upload_images/99120-791e8a6b0ab5a4a3.png" data-image-slug="791e8a6b0ab5a4a3" data-width="1528" data-height="1040"><br><div class="image-caption"><a href="http://romannurik.github.io/AndroidAssetStudio/" target="_blank" rel="external">http://romannurik.github.io/AndroidAssetStudio/</a></div></div><p>图标生成器,这个小工具可以帮助你生成一些图标,包括App主程序图标,ActionBar的Tab标签图标等。在你没有UI经验绘制和美化图标时,只需要一张合适的图片,这款工具就能让你选择生成各式各样的图标,简单粗暴。</p><p><br></p><h4>4.Android Pixels</h4><div class="image-package"><img src="http://obr1dwgsb.bkt.clouddn.com/5.png" data-original-src="http://upload-images.jianshu.io/upload_images/99120-63bef314a455743f.png" data-image-slug="63bef314a455743f" data-width="1166" data-height="1114"><br><div class="image-caption"><a href="http://androidpixels.net/" target="_blank" rel="external">http://androidpixels.net/</a></div></div><p>Android分辨率换算工具,输入其中一个像素来计算其他分辨率下的图片像素大小,适合不同分辨率下图片资源大小的调整。</p><p><br></p><h4>5.Android Button Maker</h4><div class="image-package"><img src="http://obr1dwgsb.bkt.clouddn.com/6.png" data-original-src="http://upload-images.jianshu.io/upload_images/99120-5caf3c4ca4dcf1e7.png" data-image-slug="5caf3c4ca4dcf1e7" data-width="2040" data-height="892"><br><div class="image-caption"><a href="http://angrytools.com/android/button/" target="_blank" rel="external">http://angrytools.com/android/button/</a></div></div><p>当你还在为 App中程序样式困扰时,Android Button Maker这款工具能够帮你生成Button的样式布局代码,简化了大量编写代码的工作。</p><p><br></p><h4>6.JSONLint</h4><div class="image-package"><img src="http://obr1dwgsb.bkt.clouddn.com/7.png" data-original-src="http://upload-images.jianshu.io/upload_images/99120-5d343baca04e8772.png" data-image-slug="5d343baca04e8772" data-width="1138" data-height="268"><br><div class="image-caption"><a href="http://jsonlint.com/" target="_blank" rel="external">http://jsonlint.com/</a></div></div><p>Json格式化工具,这款小工具能够将常常的一整串Json数据格式化成更加直观的Json数据,让你更清晰的校对Json字符串是否正确。</p><br> <br> <br> <br> <br><p></p>
]]></content>
<summary type="html">
<p>在Android开发过程中你可能会遇到那些繁琐的重复性劳动工作,怎样减少这类重复性劳动,下面就介绍一些实用的开发小工具来提升开发过程中的效率。
</summary>
<category term="开发工具" scheme="http://yangjingxuan.space/categories/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/"/>
</entry>
<entry>
<title>Android-Wear与Apple-Watch智能手表上都有哪些优秀的App</title>
<link href="http://yangjingxuan.space/2015/04/01/Android-Wear%E4%B8%8EApple-Watch%E6%99%BA%E8%83%BD%E6%89%8B%E8%A1%A8%E4%B8%8A%E9%83%BD%E6%9C%89%E5%93%AA%E4%BA%9B%E4%BC%98%E7%A7%80%E7%9A%84App/"/>
<id>http://yangjingxuan.space/2015/04/01/Android-Wear与Apple-Watch智能手表上都有哪些优秀的App/</id>
<published>2015-04-01T04:50:00.000Z</published>
<updated>2017-03-29T02:23:06.000Z</updated>
<content type="html"><![CDATA[<p>Apple Watch在4月28号将在中国地区正式首发,在Apple Watch发售之际,让我们来盘点一下Android Wear与即将上市的Apple Watch上有哪些优秀的Apps值得我们体验。<a id="more"></a><br><br></p><p><b>1.</b><b>效率类软件</b><a href="" target="_blank"><b></b></a></p><p>Android Wear</p><p><b><a href="https://play.google.com/store/apps/details?id=com.wunderkinder.wunderlistandroidedu" target="_blank">Wunderlist高效云端同步Todo List神器</a></b><b></b></p><p>Wunderlist可以用来记录一些行程,记事提醒,工作安排,任务管理,GTD等工作,在Android Watch上Wunderlist将会为你提供贴身的提醒功能,为你提供代办事件提醒,为你更好的规划工作安排与学习计划。</p><p><br></p><div class="image-package"><img src="http://obr1dwgsb.bkt.clouddn.com/1.jpg" data-original-src="http://upload-images.jianshu.io/upload_images/99120-df5bd12e40dbeb3f.jpg" data-image-slug="df5bd12e40dbeb3f" data-width="480" data-height="479"><br><div class="image-caption"></div></div><p>Apple Watch</p><p><b><a href="http://www.betterworks.com/" target="_blank">BetterWorks实时显示最新工作进展</a></b><b></b></p><p>BetterWorks是一款办公利器,当你们忙碌在工作中无暇顾及其他事情时,BetterWorks让你只需在手表滑动就能了解工作项目的最新进展,员工能通过它快速了解最新的工作内容,工作目标,并查看其他同事的工作进度。</p><p><br></p><div class="image-package"><img src="http://obr1dwgsb.bkt.clouddn.com/2.jpg" data-original-src="http://upload-images.jianshu.io/upload_images/99120-9b2b4c95cbae92a7.jpg" data-image-slug="9b2b4c95cbae92a7" data-width="469" data-height="433"><br><div class="image-caption"></div></div><p>2.社交类软件</p><p><b></b></p><p>Android Wear</p><p><b><a href="https://play.google.com/store/apps/details?id=com.tencent.mm" target="_blank">WeChat Watch手表上的微信消息通知回复利器</a></b><b></b></p><p>WeChat Watch包括查看微信上的消息通知,并且还能够通过语音快速回复对方消息,真是方便省事的微信发送与接收工具。</p><p><br></p><div class="image-package"><img src="http://obr1dwgsb.bkt.clouddn.com/3.jpg" data-original-src="http://upload-images.jianshu.io/upload_images/99120-f652394f59ae2a55.jpg" data-image-slug="f652394f59ae2a55" data-width="469" data-height="464"><br><div class="image-caption"></div></div><p>Apple Watch</p><p><b><a href="https://itunes.apple.com/tr/app/wechat/id414478124?mt=8" target="_blank">WeChat Watch的Apple Watch版本</a></b><b></b></p><p><b><br></b></p><div class="image-package"><img src="http://obr1dwgsb.bkt.clouddn.com/4.jpg" data-original-src="http://upload-images.jianshu.io/upload_images/99120-fb5b6340785621b0.jpg" data-image-slug="fb5b6340785621b0" data-width="402" data-height="290"><br><div class="image-caption"></div></div><p>3.健康类软件</p><p><b></b></p><p>Android Watch</p><p><b><a href="https://play.google.com/store/apps/details?id=com.google.android.apps.fitness" target="_blank">GoogleKit优秀简约的记步与心率检测软件</a></b><b></b></p><p>GoogleKit谷歌健身是谷歌内置在Android Wear上的一款内置记步与心率检测工具,只需要你随身携带Watch就能了解你的步行运动情况,同时点击心率检测Heart rate就能检测你当前的心率状况。</p><p><br></p><div class="image-package"><img src="http://obr1dwgsb.bkt.clouddn.com/5.jpg" data-original-src="http://upload-images.jianshu.io/upload_images/99120-3c53de3d5ef5f581.jpg" data-image-slug="3c53de3d5ef5f581" data-width="469" data-height="461"><br><div class="image-caption"></div></div><p>Apple Watch</p><p><b><a href="https://itunes.apple.com/us/app/nike+-running/id387771637?mt=8" target="_blank">Nike+ Running耐克的记步工具,记录你最新的运动信息</a></b><b></b></p><p>Nike+ Running能够追踪你的跑步数据并帮助你达成跑步目标,让你时刻把握好正确的方向,以准确的数据记录你的距离,速度与跑步时间。</p><p><br></p><div class="image-package"><img src="http://obr1dwgsb.bkt.clouddn.com/6.jpg" data-original-src="http://upload-images.jianshu.io/upload_images/99120-18c2ebe0665b6448.jpg" data-image-slug="18c2ebe0665b6448" data-width="403" data-height="398"><br><div class="image-caption"></div></div><p>4.音乐娱乐类软件</p><p><b></b></p><p>Android Wears</p><p><b><a href="https://play.google.com/store/apps/details?id=com.google.android.music" target="_blank">Google Play Music极简的设计与丰富的音乐库</a></b><b></b></p><p>Google Play Music是谷歌推出的自家的在线音乐播放器,通过Android Watch内置的Play Music可以通过手表播放你手机上Google Play Music的音乐,拥有最新最全的音乐库,用户可以付费购买音乐并试听。</p><p>(大部分音乐提供试听,需要用户购买后才能听完整音乐)</p><p><br></p><div class="image-package"><img src="http://obr1dwgsb.bkt.clouddn.com/7.jpg" data-original-src="http://upload-images.jianshu.io/upload_images/99120-024af876c445725e.jpg" data-image-slug="024af876c445725e" data-width="425" data-height="424"><br><div class="image-caption"></div></div><p>Apple Watch</p><p><b><a href="http://www.openplanetsoftware.com/highnote/" target="_blank">Highnote强大的音乐播放器,让你自由调节音乐节奏与声调</a></b><b></b></p><p>Highnote是一款专门为音乐人与舞蹈家设计的软件,它的重点在于用户可以调节音乐播放节奏,让你的演奏或舞蹈更随心所欲,是一个适合困难独奏与掌握棘手舞蹈动作的平台。</p><p><br></p><div class="image-package"><img src="http://obr1dwgsb.bkt.clouddn.com/8.jpg" data-original-src="http://upload-images.jianshu.io/upload_images/99120-f5c6b8be1773befd.jpg" data-image-slug="f5c6b8be1773befd" data-width="407" data-height="382"><br><div class="image-caption"></div></div><br> <br> <br> <br> <br><p></p>
]]></content>
<summary type="html">
<p>Apple Watch在4月28号将在中国地区正式首发,在Apple Watch发售之际,让我们来盘点一下Android Wear与即将上市的Apple Watch上有哪些优秀的Apps值得我们体验。
</summary>
<category term="日常小记" scheme="http://yangjingxuan.space/categories/%E6%97%A5%E5%B8%B8%E5%B0%8F%E8%AE%B0/"/>
</entry>
<entry>
<title>手机太慢太卡?三步教你优化手机性能</title>
<link href="http://yangjingxuan.space/2015/03/24/%E6%89%8B%E6%9C%BA%E5%A4%AA%E6%85%A2%E5%A4%AA%E5%8D%A1%EF%BC%9F%E4%B8%89%E6%AD%A5%E6%95%99%E4%BD%A0%E4%BC%98%E5%8C%96%E6%89%8B%E6%9C%BA%E6%80%A7%E8%83%BD/"/>
<id>http://yangjingxuan.space/2015/03/24/手机太慢太卡?三步教你优化手机性能/</id>
<published>2015-03-24T05:59:00.000Z</published>
<updated>2016-09-21T03:08:41.000Z</updated>
<content type="html"><![CDATA[<p>众所周知,当安卓手机使用一段时间后,随着各类应用程序的不断增多,手机也会随之变卡。</p>
<p>其中伴随着各类应用程序消耗内存与各种程序不断启动的后台服务,都会造成手机系统变慢,变卡。如何让你的安卓手机不再卡顿,恢复同第一次出厂般的流畅顺滑?</p>
<h4 id="下面,就由我来介绍几款优化软件,让你的手机不再卡顿,变慢。"><a href="#下面,就由我来介绍几款优化软件,让你的手机不再卡顿,变慢。" class="headerlink" title="下面,就由我来介绍几款优化软件,让你的手机不再卡顿,变慢。"></a>下面,就由我来介绍几款优化软件,让你的手机不再卡顿,变慢。</h4><p>在这之前你的手机需要获得root权限,这意味着你可以得到更多的权限对你的手机进行操作,同时你也将拥有可以授予软件root的权限。</p>
<p>当你获得root权限之后,可以开始以下的剁手折腾操作了。<br><a id="more"></a></p>
<h4 id="1-安装Xposed框架"><a href="#1-安装Xposed框架" class="headerlink" title="1.安装Xposed框架"></a>1.<a href="http://app.flyme.cn/apps/public/detail?package_name=de.robv.android.xposed.installer" target="_blank" rel="external">安装Xposed框架</a></h4><p>Xposed框架是一款可以在无需修改应用程序的基础上影响应用程序运行的软件框架</p>
<p>安装完Xposed框架后,在框架的基础上你可以安装各类模块服务(包括以下我要推荐的这两款必备神器(Greenify,BootManager等等)这个有点类似于IOS越狱过后的Cydia。</p>
<p><img src="http://obr1dwgsb.bkt.clouddn.com/%E4%B8%8B%E8%BD%BD.jpeg" alt="Xposed框架"></p>
<h4 id="2-安装Greenify"><a href="#2-安装Greenify" class="headerlink" title="2.安装Greenify"></a>2.<a href="http://app.flyme.cn/apps/public/detail?package_name=com.oasisfeng.greenify" target="_blank" rel="external">安装Greenify</a></h4><p>中文有个很形象的名字–绿色守护,如同他的icon一样,轻如一片叶子般守护着你的手机。</p>
<p>在选择更多应用中,添加你需要休眠的应用程序,并在试验性特性中选择工作模式为高效模式,并勾选上下方需要XPOSED的三个选项。</p>
<p>当你开启自动休眠后,它将为你自动休眠无需使用的应用程序,切断程序进程,停止程序的各种后台服务。</p>
<p><img src="http://obr1dwgsb.bkt.clouddn.com/%E4%B8%8B%E8%BD%BD%20%281%29.jpeg" alt="Greenify"></p>
<h4 id="3-安装BootManager启动管理器"><a href="#3-安装BootManager启动管理器" class="headerlink" title="3.安装BootManager启动管理器"></a>3.<a href="http://app.flyme.cn/apps/public/detail?package_name=de.defim.apk.bootmanager" target="_blank" rel="external">安装BootManager启动管理器</a></h4><p>安装完成之后选中无需要开机启动的软件。在你手机开机时,这些软件将被禁止启动,减少不必要程序占据后台的资源。</p>
<p><img src="http://obr1dwgsb.bkt.clouddn.com/%E4%B8%8B%E8%BD%BD%20%282%29.jpeg" alt="BootManager启动管理器"></p>
<p>通过以上的这三步操作后,你的手机与之前相比已经有了很大的提升,包括流畅性与电池续航能力。最后提醒一下大家,手机Root后有风险,还需谨慎操作!</p>
]]></content>
<summary type="html">
<p>众所周知,当安卓手机使用一段时间后,随着各类应用程序的不断增多,手机也会随之变卡。</p>
<p>其中伴随着各类应用程序消耗内存与各种程序不断启动的后台服务,都会造成手机系统变慢,变卡。如何让你的安卓手机不再卡顿,恢复同第一次出厂般的流畅顺滑?</p>
<h4 id="下面,就由我来介绍几款优化软件,让你的手机不再卡顿,变慢。"><a href="#下面,就由我来介绍几款优化软件,让你的手机不再卡顿,变慢。" class="headerlink" title="下面,就由我来介绍几款优化软件,让你的手机不再卡顿,变慢。"></a>下面,就由我来介绍几款优化软件,让你的手机不再卡顿,变慢。</h4><p>在这之前你的手机需要获得root权限,这意味着你可以得到更多的权限对你的手机进行操作,同时你也将拥有可以授予软件root的权限。</p>
<p>当你获得root权限之后,可以开始以下的剁手折腾操作了。<br>
</summary>
<category term="日常小记" scheme="http://yangjingxuan.space/categories/%E6%97%A5%E5%B8%B8%E5%B0%8F%E8%AE%B0/"/>
</entry>
</feed>