-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathatom.xml
More file actions
644 lines (430 loc) · 193 KB
/
Copy pathatom.xml
File metadata and controls
644 lines (430 loc) · 193 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
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
635
636
637
638
639
640
641
642
643
644
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>网记本</title>
<subtitle>网络记事本-huangguangzhi</subtitle>
<link href="/atom.xml" rel="self"/>
<link href="https://inote.fun/"/>
<updated>2020-03-29T06:13:01.027Z</updated>
<id>https://inote.fun/</id>
<author>
<name>网记本</name>
</author>
<generator uri="http://hexo.io/">Hexo</generator>
<entry>
<title>美股熔断与美联储救市</title>
<link href="https://inote.fun/2020/03/29/%E7%BE%8E%E8%82%A1%E7%86%94%E6%96%AD%E4%B8%8E%E7%BE%8E%E8%81%94%E5%82%A8%E6%95%91%E5%B8%82/"/>
<id>https://inote.fun/2020/03/29/美股熔断与美联储救市/</id>
<published>2020-03-29T05:06:30.000Z</published>
<updated>2020-03-29T06:13:01.027Z</updated>
<content type="html"><![CDATA[<h1 id="美股熔断与美联储救市"><a href="#美股熔断与美联储救市" class="headerlink" title="美股熔断与美联储救市"></a>美股熔断与美联储救市</h1><h5 id="美股熔断"><a href="#美股熔断" class="headerlink" title="美股熔断"></a>美股熔断</h5><p>“神奇的2020,我们和股神一起见证历史。 ”</p><p>3月18日,美股因标普500指数盘中跌超7%,再次触发熔断机制,暂停交易15分钟,为美股史上第五次熔断,10天内第四次熔断。</p><p>本想来股市挣点钱,你却让我来见证历史!!!</p><p><img src="/images/gupiao_jianzhenglishi.png" alt="见证历史"></p><a id="more"></a><h6 id="美股熔断机制"><a href="#美股熔断机制" class="headerlink" title="美股熔断机制"></a>美股熔断机制</h6><p>1988年10月19日,美国商品期货交易委员会与证券交易委员会批准了纽约股票交易所和芝加哥商业交易所的熔断机制。此后,熔断机制一直持续至今。</p><p>最开始美国熔断机制的基准指数是道琼斯工业指数,后来修改为标准普尔500指数。</p><p>在美股交易时段,熔断机制可以分为三级。一级市场熔断,是指市场下跌达到7%;二级市场熔断,是指市场下跌达到13%;三级市场熔断,是指市场下跌达到20%。</p><h6 id="美股熔断历史"><a href="#美股熔断历史" class="headerlink" title="美股熔断历史"></a>美股熔断历史</h6><p>1987年10月19日 (星期一),道琼斯工业平均指数大幅下跌508点 (逾 20%)。因为没有熔断机制的保护,许多人损失惨重,这天被股民称作:黑色星期一。</p><p>第一次:1997年10月27日,当时道琼斯工业指数暴跌7.18%。这一天,也是熔断机制在1988年引入之后第一次被触发。</p><p>第二次:2020年3月9日,纽约股市开盘出现暴跌,随后跌幅达到7%上限,触发熔断机制。</p><p>第三次:2020年3月12日,标普500指数跌幅扩大至7%,再次触发熔断,美股暂停交易15分钟。</p><p>第四次:2020年3月16日,美国三大股指开盘暴跌,标普500指数跌逾7%,触发熔断机制,停盘15分钟。</p><p>第五次:2020年3月18日,纽约股市三大股指早盘大幅低开,午间跌幅扩大并再度触发熔断机制。</p><p><img src="/images/gupiao_rongduan.png" alt="美股熔断"></p><p><img src="/images/gupiao_shangzheng.png" alt="上证指数"></p><h5 id="美联储救市"><a href="#美联储救市" class="headerlink" title="美联储救市"></a>美联储救市</h5><p>市场充斥的股市灾难发生主要原因三个:1.新冠疫情全球爆发,2. 沙特与俄罗斯石油战,石油价暴跌,3.美股股市虚高。</p><p>从这方面看,国内2015年开始的去扛杆,还是有先见之明吧。</p><p>3月23日美联储宣布无限量QE:</p><p>美联储将开始“不设上限”地购买美国国债和机构抵押贷款支持证券(MBS),目的是支持市场运行通畅,以及把货币政策有效地传导至更广泛的金融系统和经济体。</p><p>QE政策,白宫很喜欢、华尔街很喜欢、有钱人很喜欢、全世界都很喜欢。</p><p>因为QE能在账面上稳住经济数据、能给华尔街提供宽松的环境、能为有钱人创造政策套利空间、能让全世界各国都继续沐浴在泡沫中.</p><p><img src="/images/gupiao_baoweier.png" alt="美联储"></p><h5 id="未来股市怎么走"><a href="#未来股市怎么走" class="headerlink" title="未来股市怎么走"></a>未来股市怎么走</h5><p>美联储无限量QE治标不治本,问题的核心还是全球疫情的爆发能否及时控制住,对未来实体经济的影响力有多大,这才是问题的核心。</p><p>当然未来还是稳定上升的 行情。但是至于 在低位区震荡多久,是否会再次突破指数底位都是未知数。</p><p>股市有风险,入市需谨慎。新手死于追高 老手死于抄底 高手死于杠杆。尤其不确定因素较多的时候,千万不要加杠杆。合理价位建仓,逐步高抛低吸,手里拿牌不离开牌桌就好,因为未来还是做多中国的,也只能做多中国。 </p>]]></content>
<summary type="html">
<h1 id="美股熔断与美联储救市"><a href="#美股熔断与美联储救市" class="headerlink" title="美股熔断与美联储救市"></a>美股熔断与美联储救市</h1><h5 id="美股熔断"><a href="#美股熔断" class="headerlink" title="美股熔断"></a>美股熔断</h5><p>“神奇的2020,我们和股神一起见证历史。 ”</p>
<p>3月18日,美股因标普500指数盘中跌超7%,再次触发熔断机制,暂停交易15分钟,为美股史上第五次熔断,10天内第四次熔断。</p>
<p>本想来股市挣点钱,你却让我来见证历史!!!</p>
<p><img src="/images/gupiao_jianzhenglishi.png" alt="见证历史"></p>
</summary>
<category term="心情" scheme="https://inote.fun/categories/%E5%BF%83%E6%83%85/"/>
<category term="股票" scheme="https://inote.fun/tags/%E8%82%A1%E7%A5%A8/"/>
</entry>
<entry>
<title>Android O service保活方案(startForeground&notification)</title>
<link href="https://inote.fun/2020/02/21/Android-8-servicee%E4%BF%9D%E6%B4%BB%E5%AE%9E%E7%8E%B0/"/>
<id>https://inote.fun/2020/02/21/Android-8-servicee保活实现/</id>
<published>2020-02-21T08:00:30.000Z</published>
<updated>2020-02-21T09:55:28.510Z</updated>
<content type="html"><![CDATA[<h1 id="Android-O-service保活方案(startForeground-amp-notification)"><a href="#Android-O-service保活方案(startForeground-amp-notification)" class="headerlink" title="Android O service保活方案(startForeground & notification)"></a>Android O service保活方案(startForeground & notification)</h1><h3 id="一-问题"><a href="#一-问题" class="headerlink" title="一.问题"></a>一.问题</h3><h4 id="问题:从android-O版本开始,google为了控制资源使用,对service后台服务做了限制。"><a href="#问题:从android-O版本开始,google为了控制资源使用,对service后台服务做了限制。" class="headerlink" title="问题:从android O版本开始,google为了控制资源使用,对service后台服务做了限制。"></a>问题:从android O版本开始,google为了控制资源使用,对service后台服务做了限制。</h4><a id="more"></a> <h5 id="1-第一个问题:后台service只能存活几分钟。"><a href="#1-第一个问题:后台service只能存活几分钟。" class="headerlink" title="1. 第一个问题:后台service只能存活几分钟。"></a>1. 第一个问题:后台service只能存活几分钟。</h5><p> 现象就是,service启动后,应用退到后台运行,大概过几分钟service就会停止。堆栈信息:<br> <code>ActivityManager: Stopping service due to app idle: xxxxService.</code></p><p> <strong>分析源码:</strong></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><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">// UID is now in the background (and not on the temp whitelist). Was it</span><br><span class="line">// previously in the foreground (or on the temp whitelist)?</span><br><span class="line">if (!ActivityManager.isProcStateBackground(uidRec.setProcState)</span><br><span class="line">|| uidRec.setWhitelist) {</span><br><span class="line">uidRec.lastBackgroundTime = nowElapsed;</span><br><span class="line">if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {</span><br><span class="line">// Note: the background settle time is in elapsed realtime, while</span><br><span class="line">// the handler time base is uptime. All this means is that we may</span><br><span class="line">// stop background uids later than we had intended, but that only</span><br><span class="line">// happens because the device was sleeping so we are okay anyway.</span><br><span class="line">mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,</span><br><span class="line">mConstants.BACKGROUND_SETTLE_TIME);</span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure><blockquote><p>如何是后台service并且不再白名单内,会发送一个延迟消息,延迟时间是BACKGROUND_SETTLE_TIME。</p></blockquote><figure class="highlight plain"><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">public long BACKGROUND_SETTLE_TIME = DEFAULT_BACKGROUND_SETTLE_TIME;</span><br><span class="line">private static final long DEFAULT_BACKGROUND_SETTLE_TIME = 60*1000;</span><br></pre></td></tr></table></figure><p>延迟时间大概是<strong>1分钟</strong>。</p><p>也就是:<strong>8.0及以上版本手机中有一个机制,app退到后台后1分钟后会清理不再白名单中的后台service.</strong></p><hr><h5 id="2-第二个问题:后台应用不能通过startService启动服务。"><a href="#2-第二个问题:后台应用不能通过startService启动服务。" class="headerlink" title="2.第二个问题:后台应用不能通过startService启动服务。"></a>2.第二个问题:后台应用不能通过startService启动服务。</h5><p>抛出的异常信息:<code>Not allowed to start service Intent XXX : app is in background uid UidRecord</code></p><p> *<em>分析源码: *</em></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><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><!--检测当前app是否允许后台启动--></span><br><span class="line"> final int allowed = mAm.getAppStartModeLocked(r.appInfo.uid, r.packageName,</span><br><span class="line"> r.appInfo.targetSdkVersion, callingPid, false, false, forcedStandby);</span><br><span class="line"> <!--如果不允许 Background start not allowed--></span><br><span class="line"> if (allowed != ActivityManager.APP_START_MODE_NORMAL) {</span><br><span class="line"> ...</span><br><span class="line"> <!--返回 ? 告诉客户端现在处于后台启动状态,禁止你--></span><br><span class="line"> return new ComponentName("?", "app is in background uid " + uidRec);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <!--返回值是?的情况下就是后台启动service的异常--></span><br><span class="line"> if (cn.getPackageName().equals("?")) {</span><br><span class="line">throw new IllegalStateException(</span><br><span class="line">"Not allowed to start service " + service + ": " + cn.getClassName());</span><br><span class="line">}</span><br></pre></td></tr></table></figure><hr><h3 id="二-解决方案-startForeground-amp-notification-:"><a href="#二-解决方案-startForeground-amp-notification-:" class="headerlink" title="二.解决方案(startForeground & notification):"></a>二.解决方案(startForeground & notification):</h3><p>回收优先级:前台进程<可视进程<服务进程<后台进程<内容供应根节点<空进程</p><p>开启前台Service,会在通知栏显示<br>通过<strong>notification</strong>方式 如音乐播放</p><p><strong>kotlin代码片段:</strong></p><blockquote><p>启动/停止服务</p></blockquote><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><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">if (!CallingStateListener.isCallingStateListener()) {</span><br><span class="line"> if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {</span><br><span class="line"> startForegroundService(Intent(this, CallingStateListener::class.java))</span><br><span class="line"> } else {</span><br><span class="line"> startService(Intent(this, CallingStateListener::class.java))</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"> if (CallingStateListener.isCallingStateListener()) {</span><br><span class="line"> stopService(Intent(this, CallingStateListener::class.java))</span><br><span class="line"> }</span><br></pre></td></tr></table></figure><blockquote><p>service 类</p></blockquote><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br></pre></td><td class="code"><pre><span class="line">class CallingStateListener : Service() {</span><br><span class="line"> private val TAG = "CallingStateListener"</span><br><span class="line"> private var phoneStateListener: PhoneStateListener? = null</span><br><span class="line"> private var telephonyManager: TelephonyManager? = null</span><br><span class="line"> private val notificationId = "callingChannelId"</span><br><span class="line"> private val notificationName = "callingChannelName"</span><br><span class="line"></span><br><span class="line"> override fun onCreate() {</span><br><span class="line"> super.onCreate()</span><br><span class="line"></span><br><span class="line"> initCallingStateListener()</span><br><span class="line"></span><br><span class="line"> val notificationManager =</span><br><span class="line"> getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager</span><br><span class="line"> //创建NotificationChannel</span><br><span class="line"> if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {</span><br><span class="line"> val channel = NotificationChannel(</span><br><span class="line"> notificationId,</span><br><span class="line"> notificationName,</span><br><span class="line"> NotificationManager.IMPORTANCE_HIGH</span><br><span class="line"> )</span><br><span class="line"> notificationManager.createNotificationChannel(channel)</span><br><span class="line"> }</span><br><span class="line"> startForeground(1, getNotification())</span><br><span class="line"></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> override fun onBind(intent: Intent?): IBinder? {</span><br><span class="line"> return null</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> private fun initCallingStateListener() {</span><br><span class="line"></span><br><span class="line"> phoneStateListener = object : PhoneStateListener() {</span><br><span class="line"> @SuppressLint("MissingPermission")</span><br><span class="line"> override fun onCallStateChanged(state: Int, incomingNumber: String) {</span><br><span class="line"> super.onCallStateChanged(state, incomingNumber)</span><br><span class="line"></span><br><span class="line"> when (state) {</span><br><span class="line"> TelephonyManager.CALL_STATE_IDLE // 待机,即无电话时,挂断时触发</span><br><span class="line"> -> {</span><br><span class="line"> Log.i(TAG, "callingState:挂断,对方手机号$incomingNumber")</span><br><span class="line"> </span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> TelephonyManager.CALL_STATE_RINGING // 响铃,来电时触发</span><br><span class="line"> -> {</span><br><span class="line"> Log.i(TAG, "callingState:来电,对方手机号$incomingNumber")</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> TelephonyManager.CALL_STATE_OFFHOOK // 摘机,接听或打电话时触发</span><br><span class="line"> -> {</span><br><span class="line"> Log.i(TAG, "callingState:拨打电话,对方手机号$incomingNumber")</span><br><span class="line"></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> else -> {</span><br><span class="line"> Log.i(TAG, "callingState:其他")</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"> // 设置来电监听器</span><br><span class="line"> telephonyManager = getSystemService(TELEPHONY_SERVICE) as TelephonyManager?</span><br><span class="line"> telephonyManager?.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE)</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> private fun getNotification(): Notification {</span><br><span class="line"> val builder = Notification.Builder(this)</span><br><span class="line"> .setSmallIcon(R.mipmap.ic_launcher)</span><br><span class="line"> .setContentTitle("通话服务")</span><br><span class="line"> .setContentText("服务正在运行")</span><br><span class="line"> //设置Notification的ChannelID,否则不能正常显示</span><br><span class="line"> if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {</span><br><span class="line"> builder.setChannelId(notificationId)</span><br><span class="line"> }</span><br><span class="line"> return builder.build()</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> override fun onDestroy() {</span><br><span class="line"> stopForeground(true)</span><br><span class="line"> super.onDestroy()</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> companion object {</span><br><span class="line"> fun isCallingStateListener() =</span><br><span class="line"> ServiceUtils.isServiceRunning(CallingStateListener::class.java)</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h1 id="Android-O-service保活方案(startForeground-amp-notification)"><a href="#Android-O-service保活方案(startForeground-amp-notification)" class="headerlink" title="Android O service保活方案(startForeground &amp; notification)"></a>Android O service保活方案(startForeground &amp; notification)</h1><h3 id="一-问题"><a href="#一-问题" class="headerlink" title="一.问题"></a>一.问题</h3><h4 id="问题:从android-O版本开始,google为了控制资源使用,对service后台服务做了限制。"><a href="#问题:从android-O版本开始,google为了控制资源使用,对service后台服务做了限制。" class="headerlink" title="问题:从android O版本开始,google为了控制资源使用,对service后台服务做了限制。"></a>问题:从android O版本开始,google为了控制资源使用,对service后台服务做了限制。</h4>
</summary>
<category term="Android" scheme="https://inote.fun/categories/Android/"/>
<category term="service保活" scheme="https://inote.fun/tags/service%E4%BF%9D%E6%B4%BB/"/>
</entry>
<entry>
<title>2020开年的一些感想</title>
<link href="https://inote.fun/2020/02/10/2020%E5%BC%80%E5%B9%B4%E7%9A%84%E4%B8%80%E4%BA%9B%E6%84%9F%E6%83%B3/"/>
<id>https://inote.fun/2020/02/10/2020开年的一些感想/</id>
<published>2020-02-10T01:02:46.000Z</published>
<updated>2020-02-10T03:21:52.190Z</updated>
<content type="html"><![CDATA[<h1 id="2020开年的一些感想"><a href="#2020开年的一些感想" class="headerlink" title="2020开年的一些感想"></a>2020开年的一些感想</h1><h5 id="远程在家办公"><a href="#远程在家办公" class="headerlink" title="远程在家办公"></a>远程在家办公</h5><p>今天2020年春节过后开工了。远程在家办公。</p><p>因为疫情爆发,2020年开工一延再延,原本1月31日上班,国家延迟到2月3日。最后又延迟到2月10日。一直拖着也不是办法,因为软件开发工作,远程办公还是能实现的。公司业务基本也能靠远程来处理。<br>2月7日回南京后,在南京还要隔离14天才能去公司现场办公。</p><p>这次疫情是灾难也是机遇,也许是未来远程办公的一个契机。对之前996行业诟病可能是一种解决办法吧,希望不是一个工作生活混乱节奏的开始。</p><a id="more"></a><p><img src="/images/2020kainian_1.jpg" alt="鼠年大吉"></p><h5 id="武汉肺炎疫情爆发"><a href="#武汉肺炎疫情爆发" class="headerlink" title="武汉肺炎疫情爆发"></a>武汉肺炎疫情爆发</h5><p>从节前开始,真正引起大众关注应该是1月23日,武汉封城开始。人们才真正意识到事情的严重性,今年是过年都取消了串门拜年活动。大年30晚上就有一大批救援医疗队前往武汉支援。瞬间口罩各大药店超时都断供了。</p><p>过年在家基本闭门不出,自我封闭。随着原本1月31日的开工日期的到来,疫情态势越来越严重,假期延长,囧妈抖音免费上映。也许这次灾难,是抖音的一个机遇。同样2014年的sara,对于电商。</p><p>从1月23到2月5日 第一个疫情潜伏期过去,态势并没有下降,假期再次延长。</p><p>这次灾难对于互联网行业来说可能是一个契机,但是对于实体经济,餐饮行业无疑是灭顶之灾,没坚持几天传出西贝的窘境。</p><p>节后疫情大爆发后,各个村都开始封路,宣传。越来越重视了。大家都在愁怎么回到自己工作所在地上班。我安心的在家自我封闭呆到了2月7日。公司是定在2月10日上班,我知道不可能在延期了,不然公司今年很多事情都要延期,无法开展开来。</p><p>伴随着无锡,南通禁止湖北,浙江,河南,安徽的人员进入,怀着忐忑的心自驾回到了南京。沿途量体温,查身份证。回到南京后,物业报道登记,继续自我隔离14天。</p><p>南京企业2月10日复工是要申请的,只有在南京呆够14天隔离期员工才能复工。我前天才回南京,只能在家远程办公了。</p><p>希望这次疫情尽快过去,对于所有企业和个人来说也是一次很好的审视。</p><p><img src="/images/2020kainian_2.png" alt="武汉肺炎疫情"></p><h5 id="印度APT攻击"><a href="#印度APT攻击" class="headerlink" title="印度APT攻击"></a>印度APT攻击</h5><p>2月5日,一篇名为《印度APT组织趁火打劫对我国医疗机构发起定向攻击!丧尽天良!》在社交媒体上广泛流传。文章提到,360安全大脑近日捕获了一例利用新冠肺炎疫情相关题材投递的攻击案例,攻击者利用肺炎疫情题材作为诱饵文档,对抗击疫情的医疗工作领域发动APT攻击。随后,他们发现发动APT攻击的组织隶属于印度黑客组织。(注:APT全称为Advanced Persistent Threat,中文为高级持续性威胁,指隐匿而持久的电脑入侵过程,通常由某些人员精心策划,针对特定的目标。)</p><p>中国红客联盟回应:微不足道。不用恐慌,小题大做。</p><p>正好也发现了一个好网的网站卡巴斯基网络威胁实时地图.具体也不是很清楚,地图大概显示了当前全球文件攻击的统计数量以及何种攻击方式。</p><p><a href="https://cybermap.kaspersky.com/cn/" target="_blank" rel="noopener">https://cybermap.kaspersky.com/cn/</a></p><p><img src="/images/2020kainian_3.png" alt="黑客攻击实时地图"></p>]]></content>
<summary type="html">
<h1 id="2020开年的一些感想"><a href="#2020开年的一些感想" class="headerlink" title="2020开年的一些感想"></a>2020开年的一些感想</h1><h5 id="远程在家办公"><a href="#远程在家办公" class="headerlink" title="远程在家办公"></a>远程在家办公</h5><p>今天2020年春节过后开工了。远程在家办公。</p>
<p>因为疫情爆发,2020年开工一延再延,原本1月31日上班,国家延迟到2月3日。最后又延迟到2月10日。一直拖着也不是办法,因为软件开发工作,远程办公还是能实现的。公司业务基本也能靠远程来处理。<br>2月7日回南京后,在南京还要隔离14天才能去公司现场办公。</p>
<p>这次疫情是灾难也是机遇,也许是未来远程办公的一个契机。对之前996行业诟病可能是一种解决办法吧,希望不是一个工作生活混乱节奏的开始。</p>
</summary>
<category term="心情" scheme="https://inote.fun/categories/%E5%BF%83%E6%83%85/"/>
<category term="职业生涯" scheme="https://inote.fun/tags/%E8%81%8C%E4%B8%9A%E7%94%9F%E6%B6%AF/"/>
</entry>
<entry>
<title>踩坑:极光推送JPush自定义提示音</title>
<link href="https://inote.fun/2019/11/14/%E8%B8%A9%E5%9D%91-%E6%9E%81%E5%85%89%E6%8E%A8%E9%80%81JPush%E8%87%AA%E5%AE%9A%E4%B9%89%E6%8F%90%E7%A4%BA%E9%9F%B3/"/>
<id>https://inote.fun/2019/11/14/踩坑-极光推送JPush自定义提示音/</id>
<published>2019-11-14T01:31:05.000Z</published>
<updated>2019-11-15T13:01:16.787Z</updated>
<content type="html"><![CDATA[<h5 id="使用"><a href="#使用" class="headerlink" title="使用"></a>使用</h5><p><a href="http://docs.jiguang.cn/jpush/client/Android/android_3m/" target="_blank" rel="noopener">3 分钟快速使用 JPush Android Demo</a></p><p><a href="https://www.jiguang.cn/jpush2/#/app/d56d184d10358b1a12fd7d7d/push_form/custom" target="_blank" rel="noopener">选择应用,发送自定义消息</a></p><p>项目引入JPush:</p><figure class="highlight plain"><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">api 'cn.jiguang.sdk:jpush:3.3.4'</span><br><span class="line">api 'cn.jiguang.sdk:jcore:2.1.2'</span><br></pre></td></tr></table></figure><a id="more"></a><h5 id="8-0自定义消息通知栏适配"><a href="#8-0自定义消息通知栏适配" class="headerlink" title="8.0自定义消息通知栏适配"></a>8.0自定义消息通知栏适配</h5><h6 id="创建通知渠道"><a href="#创建通知渠道" class="headerlink" title="创建通知渠道"></a>创建通知渠道</h6><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><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></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {</span><br><span class="line"> NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);</span><br><span class="line"> // 通知渠道的id 这个地方只要一直即可</span><br><span class="line"> String id = "111111";</span><br><span class="line"> // 用户可以看到的通知渠道的名字.</span><br><span class="line"> CharSequence name = "notification channel";</span><br><span class="line"> // 用户可以看到的通知渠道的描述</span><br><span class="line"> String description = "notification description";</span><br><span class="line"> int importance = NotificationManager.IMPORTANCE_HIGH;</span><br><span class="line"> NotificationChannel mChannel = new NotificationChannel(id, name, importance);</span><br><span class="line"> // 配置通知渠道的属性</span><br><span class="line"> mChannel.setDescription(description);</span><br><span class="line"> // 设置通知出现时的闪灯(如果 android 设备支持的话)</span><br><span class="line"> mChannel.enableLights(true);</span><br><span class="line"> mChannel.setLightColor(Color.RED);</span><br><span class="line"> // 自定义声音</span><br><span class="line"> mChannel.setSound(Uri.parse("android.resource://" + context.getPackageName() + "/raw/msg_sound"),null);</span><br><span class="line"> // 设置通知出现时的震动(如果 android 设备支持的话)</span><br><span class="line"> mChannel.enableVibration(true);</span><br><span class="line"> mChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});</span><br><span class="line"> //最后在notificationmanager中创建该通知渠道</span><br><span class="line"> mNotificationManager.createNotificationChannel(mChannel);</span><br><span class="line"> }</span><br></pre></td></tr></table></figure><h5 id="踩坑:设置对应渠道的setSound-无效"><a href="#踩坑:设置对应渠道的setSound-无效" class="headerlink" title="踩坑:设置对应渠道的setSound() 无效"></a>踩坑:设置对应渠道的setSound() 无效</h5><p>** 重点 **:渠道创建后不可修改,只能删掉deleteNotificationChannel(String channelId),重新创建createNotificationChannel。</p><figure class="highlight plain"><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><br><span class="line">mChannel.setSound(Uri.parse("android.resource://" + context.getPackageName() + "/raw/msg_sound"),null);</span><br></pre></td></tr></table></figure><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><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line"> * Sets the sound that should be played for notifications posted to this channel and its</span><br><span class="line"> * audio attributes. Notification channels with an {@link #getImportance() importance} of at</span><br><span class="line"> * least {@link NotificationManager#IMPORTANCE_DEFAULT} should have a sound.</span><br><span class="line"> *</span><br><span class="line"> * Only modifiable before the channel is submitted to</span><br><span class="line"> * {@link NotificationManager#createNotificationChannel(NotificationChannel)}.</span><br><span class="line"> */</span><br><span class="line"> /**</span><br><span class="line"> * 翻译:设置发送到此channel的通知notifications播放的声音及其音频属性。只有在channel提交到之前才可修改</span><br><span class="line"> */</span><br><span class="line"> public void setSound(Uri sound, AudioAttributes audioAttributes) {</span><br><span class="line"> this.mSound = sound;</span><br><span class="line"> this.mAudioAttributes = audioAttributes;</span><br><span class="line"> }</span><br></pre></td></tr></table></figure><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><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><br><span class="line">@Override</span><br><span class="line"> public void onReceive(Context context, Intent intent) {</span><br><span class="line"> try {</span><br><span class="line"> Bundle bundle = intent.getExtras();</span><br><span class="line"> Logger.d(TAG, "[MyReceiver] onReceive - " + intent.getAction() + ", extras: " + printBundle(bundle));</span><br><span class="line"></span><br><span class="line"> if (JPushInterface.ACTION_REGISTRATION_ID.equals(intent.getAction())) {</span><br><span class="line"> String regId = bundle.getString(JPushInterface.EXTRA_REGISTRATION_ID);</span><br><span class="line"> Logger.d(TAG, "[MyReceiver] 接收Registration Id : " + regId);</span><br><span class="line"> //send the Registration Id to your server...</span><br><span class="line"></span><br><span class="line"> } else if (JPushInterface.ACTION_MESSAGE_RECEIVED.equals(intent.getAction())) {</span><br><span class="line"> Logger.d(TAG, "[MyReceiver] 接收到推送下来的自定义消息: " + bundle.getString(JPushInterface.EXTRA_MESSAGE));</span><br><span class="line"> processCustomMessage(context, bundle);</span><br><span class="line"></span><br><span class="line"> } else if (JPushInterface.ACTION_NOTIFICATION_RECEIVED.equals(intent.getAction())) {</span><br><span class="line"> Logger.d(TAG, "[MyReceiver] 接收到推送下来的通知");</span><br><span class="line"> int notifactionId = bundle.getInt(JPushInterface.EXTRA_NOTIFICATION_ID);</span><br><span class="line"> Logger.d(TAG, "[MyReceiver] 接收到推送下来的通知的ID: " + notifactionId);</span><br><span class="line"></span><br><span class="line"> } else if (JPushInterface.ACTION_NOTIFICATION_OPENED.equals(intent.getAction())) {</span><br><span class="line"> Logger.d(TAG, "[MyReceiver] 用户点击打开了通知");</span><br><span class="line"></span><br><span class="line"> //打开自定义的Activity</span><br><span class="line"> Intent i = new Intent(context, TestActivity.class);</span><br><span class="line"> i.putExtras(bundle);</span><br><span class="line"> //i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);</span><br><span class="line"> i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);</span><br><span class="line"> context.startActivity(i);</span><br><span class="line"></span><br><span class="line"> } else if (JPushInterface.ACTION_RICHPUSH_CALLBACK.equals(intent.getAction())) {</span><br><span class="line"> Logger.d(TAG, "[MyReceiver] 用户收到到RICH PUSH CALLBACK: " + bundle.getString(JPushInterface.EXTRA_EXTRA));</span><br><span class="line"> //在这里根据 JPushInterface.EXTRA_EXTRA 的内容处理代码,比如打开新的Activity, 打开一个网页等..</span><br><span class="line"></span><br><span class="line"> } else if (JPushInterface.ACTION_CONNECTION_CHANGE.equals(intent.getAction())) {</span><br><span class="line"> boolean connected = intent.getBooleanExtra(JPushInterface.EXTRA_CONNECTION_CHANGE, false);</span><br><span class="line"> Logger.w(TAG, "[MyReceiver]" + intent.getAction() + " connected state change to " + connected);</span><br><span class="line"> } else {</span><br><span class="line"> Logger.d(TAG, "[MyReceiver] Unhandled intent - " + intent.getAction());</span><br><span class="line"> }</span><br><span class="line"> } catch (Exception e) {</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>断点调试可知:</p><ul><li>1.推送下来的通知,在进入分支:<code>else if (JPushInterface.ACTION_NOTIFICATION_RECEIVED.equals(intent.getAction())) {...}</code> 之前就已经发布到通知栏,提示的是系统默认的提示音和震动等等操作。</li><li>2.自定义消息,极光推送不做任何处理,自己解析写自己的逻辑。进入分支:<code>else if (JPushInterface.ACTION_MESSAGE_RECEIVED.equals(intent.getAction())) {...}</code></li></ul><p><a href="https://community.jiguang.cn/t/android-push/4057" target="_blank" rel="noopener">android开发push的通知,如何使用自己的提示音?</a></p><p><a href="https://community.jiguang.cn/t/topic/5145/30" target="_blank" rel="noopener">JPush自定义消息-Android</a></p><h6 id="自定义提示音实现方式"><a href="#自定义提示音实现方式" class="headerlink" title="自定义提示音实现方式"></a>自定义提示音实现方式</h6><p> 通知消息不支持自定义声音资源;推送自定义消息,自己在客户端对收到的自定义消息进行展示 239,同时去实现自定义声音。</p><p>附上:</p><ul><li>项目地址:</li></ul><p><a href="https://github.com/FreeFunCode/JPushExample_custon" target="_blank" rel="noopener">JPushExample项目GitHub</a></p><ul><li>项目截图</li></ul><p><img src="/images/%E6%B6%88%E6%81%AF%E9%80%9A%E7%9F%A5.jpg" alt="消息通知"></p><p><img src="/images/%E6%B6%88%E6%81%AF%E9%80%9A%E7%9F%A5%E6%B8%A0%E9%81%93.jpg" alt="消息通知渠道"></p>]]></content>
<summary type="html">
<h5 id="使用"><a href="#使用" class="headerlink" title="使用"></a>使用</h5><p><a href="http://docs.jiguang.cn/jpush/client/Android/android_3m/" target="_blank" rel="noopener">3 分钟快速使用 JPush Android Demo</a></p>
<p><a href="https://www.jiguang.cn/jpush2/#/app/d56d184d10358b1a12fd7d7d/push_form/custom" target="_blank" rel="noopener">选择应用,发送自定义消息</a></p>
<p>项目引入JPush:</p>
<figure class="highlight plain"><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">api &apos;cn.jiguang.sdk:jpush:3.3.4&apos;</span><br><span class="line">api &apos;cn.jiguang.sdk:jcore:2.1.2&apos;</span><br></pre></td></tr></table></figure>
</summary>
<category term="Android" scheme="https://inote.fun/categories/Android/"/>
<category term="知识点" scheme="https://inote.fun/categories/Android/%E7%9F%A5%E8%AF%86%E7%82%B9/"/>
<category term="JPush" scheme="https://inote.fun/tags/JPush/"/>
</entry>
<entry>
<title>初识区块链</title>
<link href="https://inote.fun/2019/11/02/%E5%88%9D%E8%AF%86%E5%8C%BA%E5%9D%97%E9%93%BE/"/>
<id>https://inote.fun/2019/11/02/初识区块链/</id>
<published>2019-11-02T06:19:44.000Z</published>
<updated>2019-11-02T06:24:20.458Z</updated>
<content type="html"><![CDATA[<h1 id="初识区块链"><a href="#初识区块链" class="headerlink" title="初识区块链"></a>初识区块链</h1><p><img src="/images/%E5%8C%BA%E5%9D%97%E9%93%BE1.jpg" alt="区块链"> </p><blockquote><p>中央政治局第十八次集体学习时强调:区块链技术的集成应用在新的技术革新和产业变革中起着重要作用。</p></blockquote><p>近几日,区块链概念股起飞,巨量资金出入,应了雷布斯的那句话“风来了,猪都起飞了”。</p><p>之前对区块链没什么概念,但是,接触过炒虚拟币app,比如也是最近被查封的“趣步”,将虚拟糖果作为货币在市场中,类比如股票进行交易。之前也接过类似的软件需求,其实,虚拟币或者说空气币,每天的价格都是人为的后台设置每天都会递增,这样给用户造成每天都在涨的错觉,这样用户会有早买早升值的心理。运营这种空气币的人,很多都有好几个群,大家一起炒。运营人主要赚第一笔钱,同样群里人基本都知道这就是空气币,他们也是赚刚开始的那一笔钱,当泡沫越来越大,玩的人越来越多,风险就高了。赚钱的那一批人这时候就退场,最后一批入场的人则成为了“韭菜”。</p><p>最近区块链又火了,对于我们普通人来说,是好事。越了解它,它就不会那么神秘。越来越透明,就不会被各种利用区块链发行虚拟货币、炒作空气币,打着区块链旗号非法集资的组织诈骗。</p><a id="more"></a><hr><h5 id="什么是区块链"><a href="#什么是区块链" class="headerlink" title="什么是区块链"></a>什么是区块链</h5><p><img src="/images/%E5%8C%BA%E5%9D%97%E9%93%BE3.jpg" alt="区块链"> </p><blockquote><p>区块链作为比特币背后的技术框架,随着比特币的诞生而出现。</p></blockquote><p>区块链技术是一种整个系统内所有个体都参与记账的方式。系统内所有个体(成员)都有一个在系统内部公开的数据库,我们可以把这个数据库看成是整个区块链的账本。在日常生活中,大部分系统都是中心化的,例如:我们去银行取钱,记账的是银行。我们使用的微信,负责记账的是腾讯。我们使用的支付宝,是阿里在记账。在区块链系统中,系统中的每个个体(成员)都可以有机会参与记账。在一定时间段内如果有数据变化,系统中每个个体(成员)都可以来进行记账,系统会评判这段时间内记账最快最好的个体(成员),让他把记录的内容写到账本,并将这段时间内账本内容对整个系统进行公开,任何个体(成员)都可以随时查看。这样系统中的每个个体(成员)都了一本完整的账本。就这样,区块链技术解决了中介信用问题,这也是区块链的一个重大突破。在区块链之前,比特币可能已经被大家所熟知,比特币是区块链技术的一种实践,区块链不是比特币。</p><p>也就是说,区块链就是这个分布式的数字账本,记录了所有曾经发生,并经过系统一致认可的交易,每一个区块就是一个账本,当然它不仅能记录交易信息。</p><h6 id="区块链的特点:"><a href="#区块链的特点:" class="headerlink" title="区块链的特点:"></a>区块链的特点:</h6><ul><li><strong>去中心化</strong>:由于使用分布式核算和存储,不存在中心化的硬件或管理机构,任意节点的权利和义务都是均等的,系统中的数据块由整个系统中具有维护功能的节点来共同维护。</li><li><strong>开放性</strong>:系统是开放的,除了交易各方的私有信息被加密外,区块链的数据对所有人公开,任何人都可以通过公开的接口查询区块链数据和开发相关应用,因此整个系统信息高度透明。</li><li><strong>自治性</strong>:区块链采用基于协商一致的规范和协议(比如一套公开透明的算法)使得整个系统中的所有节点能够在去信任的环境自由安全的交换数据,使得对“人”的信任改成了对机器的信任,任何人为的干预不起作用。</li><li><strong>不可篡改和加密安全性</strong>:一旦信息经过验证并添加至区块链,就会永久的存储起来,除非能够同时控制住系统中超过51%的节点(少数服从多数),否则单个节点上对数据库的修改是无效的,因此区块链的数据稳定性和可靠性极高。</li><li><strong>匿名性</strong>:由于节点之间的交换遵循固定的算法,其数据交互是无需信任的(区块链中的程序规则会自行判断活动是否有效),因此交易对手无须通过公开身份的方式让对方自己产生信任,对信用的累积非常有帮助。</li></ul><h6 id="区块链的发展历程:"><a href="#区块链的发展历程:" class="headerlink" title="区块链的发展历程:"></a>区块链的发展历程:</h6><ul><li><p>区块链1.0——数字货币</p></li><li><p>区块链2.0——智能合约与金融领域(数字资产)<br>智能合约是以区块链技术为基础,能够自我执行的条约;一旦满足条件,就可以自动触发行为或付款。不久的将来,智能合约将能利用资产GPS数据等实时信息触发事件,比如转移所有权和资金。</p></li><li><p>区块链3.0——泛行业去中心化应用(区块链+)</p></li></ul><h5 id="什么是比特币"><a href="#什么是比特币" class="headerlink" title="什么是比特币"></a>什么是比特币</h5><p><img src="/images/%E5%8C%BA%E5%9D%97%E9%93%BE2.jpg" alt="区块链"> </p><blockquote><p>比特币是区块链的第一个应用,区块链是比特币的底层技术。<br>比特币(bitcoin,简称BTC)的概念最初由中本聪在 2009 年提出,是一种点对点,去中心化的数字资产。比特币是一种P2P 形式的数字加密货币。预计2140年发行完毕,共2100万枚,具有极强的稀缺性。德国为首个认可比特币的国家。</p></blockquote><h6 id="传统货币痛点:"><a href="#传统货币痛点:" class="headerlink" title="传统货币痛点:"></a>传统货币痛点:</h6><p>传统货币还存在一个中心(国家银行、支付宝、微信)体系中,如果发生天灾,例:这些第三方的服务器受到损坏,那我们的记录就会被销毁,交易无法查询、银行关门存在银行里的钱,在特殊时期,会被随时查封、冻结、没收,无法取款存款、或者由于天灾导致货币销毁,无法追回等。同时由国家发行的法定货币存在超印的情况,会引起通货膨胀。</p><p>在2008全球经济危机中,美国政府因为有记账权所以可以无限增发货币。中本聪觉得这样很不靠谱,于是发明创造了一种新型支付体系:发表了《比特币一种点对点的电子现金系统》的论文,描述了全新的电子信息系统—比特币。</p><h6 id="比特币发展"><a href="#比特币发展" class="headerlink" title="比特币发展"></a>比特币发展</h6><p>2008年9月 雷曼兄弟破产倒闭,全球经济危机爆发。<br>2008年11月 中本聪发布比特币代码的先行版本。<br>2009年1月 中本聪挖出了比特币的第一个区块—创世区块(50个比特币)。</p><h6 id="中本聪是谁?"><a href="#中本聪是谁?" class="headerlink" title="中本聪是谁?"></a>中本聪是谁?</h6><p> “中本聪”可能是一个匿名。身份未知。</p><h5 id="未来区块链有哪些应用场景"><a href="#未来区块链有哪些应用场景" class="headerlink" title="未来区块链有哪些应用场景"></a>未来区块链有哪些应用场景</h5><h6 id="数字货币"><a href="#数字货币" class="headerlink" title="数字货币"></a>数字货币</h6><p>在经历了实物、贵金属、纸钞等形态之后,数字货币已经成为数字经济时代的发展方向。相比实体货币,数字货币具有易携带存储、低流通成本、使用便利、易于防伪和管理、打破地域限制,能更好整合等特点。</p><h6 id="金融资产交易结算"><a href="#金融资产交易结算" class="headerlink" title="金融资产交易结算"></a>金融资产交易结算</h6><p>区块链技术天然具有金融属性,它正对金融业产生颠覆式变革。支付结算方面,在区块链分布式账本体系下,市场多个参与者共同维护并实时同步一份“总账”,短短几分钟内就可以完成现在两三天才能完成的支付、清算、结算任务,降低了跨行跨境交易的复杂性和成本。同时,区块链的底层加密技术保证了参与者无法篡改账本,确保交易记录透明安全,监管部门方便地追踪链上交易,快速定位高风险资金流向。</p><h6 id="数字政务"><a href="#数字政务" class="headerlink" title="数字政务"></a>数字政务</h6><p>区块链可以让数据跑起来,大大精简办事流程。区块链的分布式技术可以让政府部门集中到一个链上,所有办事流程交付智能合约,办事人只要在一个部门通过身份认证以及电子签章,智能合约就可以自动处理并流转,顺序完成后续所有审批和签章。区块链发票是国内区块链技术最早落地的应用。税务部门推出区块链电子发票“税链”平台,税务部门、开票方、受票方通过独一无二的数字身份加入“税链”网络,真正实现“交易即开票”“开票即报销”——秒级开票、分钟级报销入账,大幅降低了税收征管成本,有效解决数据篡改、一票多报、偷税漏税等问题。扶贫是区块链技术的另一个落地应用。利用区块链技术的公开透明、可溯源、不可篡改等特性,实现扶贫资金的透明使用、精准投放和高效管理。</p><h6 id="存证防伪"><a href="#存证防伪" class="headerlink" title="存证防伪"></a>存证防伪</h6><p>区块链可以通过哈希时间戳证明某个文件或者数字内容在特定时间的存在,加之其公开、不可篡改、可溯源等特性为司法鉴证、身份证明、产权保护、防伪溯源等提供了完美解决方案。在知识产权领域,通过区块链技术的数字签名和链上存证可以对文字、图片、音频视频等进行确权,通过智能合约创建执行交易,让创作者重掌定价权,实时保全数据形成证据链,同时覆盖确权、交易和维权三大场景。在防伪溯源领域,通过供应链跟踪区块链技术可以被广泛应用于食品医药、农产品、酒类、奢侈品等各领域。</p><h6 id="数据服务"><a href="#数据服务" class="headerlink" title="数据服务"></a>数据服务</h6><p>区块链技术将大大优化现有的大数据应用,在数据流通和共享上发挥巨大作用。未来互联网、人工智能、物联网都将产生海量数据,现有中心化数据存储(计算模式)将面临巨大挑战,基于区块链技术的边缘存储(计算)有望成为未来解决方案。再者,区块链对数据的不可篡改和可追溯机制保证了数据的真实性和高质量,这成为大数据、深度学习、人工智能等一切数据应用的基础。最后,区块链可以在保护数据隐私的前提下实现多方协作的数据计算,有望解决“数据垄断”和“数据孤岛”问题,实现数据流通价值。针对当前的区块链发展阶段,为了满足一般商业用户区块链开发和应用需求,众多传统云服务商开始部署自己的BaaS(“区块链即服务”)解决方案。区块链与云计算的结合将有效降低企业区块链部署成本,推动区块链应用场景落地。未来区块链技术还会在慈善公益、保险、能源、物流、物联网等诸多领域发挥重要作用。</p>]]></content>
<summary type="html">
<h1 id="初识区块链"><a href="#初识区块链" class="headerlink" title="初识区块链"></a>初识区块链</h1><p><img src="/images/%E5%8C%BA%E5%9D%97%E9%93%BE1.jpg" alt="区块链"> </p>
<blockquote>
<p>中央政治局第十八次集体学习时强调:区块链技术的集成应用在新的技术革新和产业变革中起着重要作用。</p>
</blockquote>
<p>近几日,区块链概念股起飞,巨量资金出入,应了雷布斯的那句话“风来了,猪都起飞了”。</p>
<p>之前对区块链没什么概念,但是,接触过炒虚拟币app,比如也是最近被查封的“趣步”,将虚拟糖果作为货币在市场中,类比如股票进行交易。之前也接过类似的软件需求,其实,虚拟币或者说空气币,每天的价格都是人为的后台设置每天都会递增,这样给用户造成每天都在涨的错觉,这样用户会有早买早升值的心理。运营这种空气币的人,很多都有好几个群,大家一起炒。运营人主要赚第一笔钱,同样群里人基本都知道这就是空气币,他们也是赚刚开始的那一笔钱,当泡沫越来越大,玩的人越来越多,风险就高了。赚钱的那一批人这时候就退场,最后一批入场的人则成为了“韭菜”。</p>
<p>最近区块链又火了,对于我们普通人来说,是好事。越了解它,它就不会那么神秘。越来越透明,就不会被各种利用区块链发行虚拟货币、炒作空气币,打着区块链旗号非法集资的组织诈骗。</p>
</summary>
<category term="知识点" scheme="https://inote.fun/categories/%E7%9F%A5%E8%AF%86%E7%82%B9/"/>
<category term="区块链" scheme="https://inote.fun/tags/%E5%8C%BA%E5%9D%97%E9%93%BE/"/>
</entry>
<entry>
<title>Jetpack之Androidx介绍</title>
<link href="https://inote.fun/2019/11/01/Jetpack%E4%B9%8BAndroidx%E4%BB%8B%E7%BB%8D/"/>
<id>https://inote.fun/2019/11/01/Jetpack之Androidx介绍/</id>
<published>2019-11-01T12:41:33.000Z</published>
<updated>2019-11-01T15:28:46.937Z</updated>
<content type="html"><![CDATA[<h1 id="Jetpack之Androidx介绍"><a href="#Jetpack之Androidx介绍" class="headerlink" title="Jetpack之Androidx介绍"></a>Jetpack之Androidx介绍</h1><h4 id="一-由来"><a href="#一-由来" class="headerlink" title="一. 由来"></a>一. 由来</h4><p>在Google I/O 2018上,Android团队宣布了AndroidX。</p><p> AndroidX 是对 android.support.* 包的整理后产物。由于之前的 support 包过于混乱,所以,Google 推出了AndroidX。</p><p>因此,AndroidX本质上其实就是对Android Support Library进行的一次升级。</p><p>自support v7:28开始,大部分support包都会迁移到androidx下。</p><h5 id="android-support-包介绍:"><a href="#android-support-包介绍:" class="headerlink" title="android.support.*包介绍:"></a>android.support.*包介绍:</h5><p>如果在低版本Android平台上开发一个应用程序,而应用程序又想使用高版本才拥有的功能,就需要使用Support库。</p><ul><li><p>Android Support v4: 这个包是为了照顾1.6及更高版本而设计的,这个包是使用最广泛的,eclipse新建工程时,都默认带有了。</p></li><li><p>Android Support v7: 这个包是为了考虑照顾2.1及以上版本而设计的,但不包含更低,故如果不考虑1.6,我们可以采用再加上这个包,另外注意,v7是要依赖v4这个包的,即:两个得同时被包含。</p></li><li><p>Android Support v13 : 这个包的设计是为了android 3.2及更高版本的,一般我们都不常用,平板开发中能用到。</p></li></ul><a id="more"></a><p><img src="/images/androidsupport.jpg" alt="AndroidSupportLibrary"></p><h4 id="二-基本概念"><a href="#二-基本概念" class="headerlink" title="二.基本概念"></a>二.基本概念</h4><p>AndroidX 是 Android 团队用于在 Jetpack 中开发、测试、打包和发布库以及对其进行版本控制的开源项目。</p><p>AndroidX 对原始 Android 支持库进行了重大改进。与支持库一样,AndroidX 与 Android 操作系统分开提供,并与各个 Android 版本向后兼容。AndroidX 完全取代了支持库,不仅提供同等的功能,而且提供了新的库。此外,AndroidX 还包括以下功能:</p><ul><li><p>AndroidX 中的所有软件包都使用一致的命名空间,以字符串 androidx 开头。支持库软件包已映射到对应的 androidx.* 软件包。有关所有旧类到新类以及旧编译工件到新编译工件的完整映射,请参阅软件包重构页面。</p></li><li><p>与支持库不同,AndroidX 软件包会单独维护和更新。androidx 软件包使用严格的语义版本控制,从版本 1.0.0 开始。您可以单独更新项目中的 AndroidX 库。</p></li><li><p>所有新支持库的开发工作都将在 AndroidX 库中进行。这包括维护原始支持库工件和引入新的 Jetpack 组件。</p></li></ul><hr><h4 id="三-使用-AndroidX"><a href="#三-使用-AndroidX" class="headerlink" title="三.使用 AndroidX"></a>三.使用 AndroidX</h4><p>如果要在新项目中使用 AndroidX,则需要将编译 SDK 设置为 Android 9.0(API 级别 28)或更高版本,并在 gradle.properties 文件中将以下两个 Android Gradle 插件标记设置为 true。</p><p><code>android.useAndroidX</code>:如果设置为 true,Android 插件会使用相应的 AndroidX 库,而非支持库。如果未指定,则该标记默认为 false。<br><code>android.enableJetifier</code>:如果设置为 true,Android 插件会重写其二进制文件,自动迁移现有的第三方库以使用 AndroidX。如果未指定,则该标记默认为 false。</p><h5 id="迁移到AndroidX"><a href="#迁移到AndroidX" class="headerlink" title="迁移到AndroidX"></a>迁移到AndroidX</h5><p>AndroidX 会将原始支持库 API 软件包映射到 androidx 命名空间。只有软件包和 Maven 工件名称发生了变化;类、方法和字段名称没有改变。</p><h6 id="使用-Android-Studio-迁移现有项目"><a href="#使用-Android-Studio-迁移现有项目" class="headerlink" title="使用 Android Studio 迁移现有项目"></a>使用 Android Studio 迁移现有项目</h6><p>借助 Android Studio 3.2 及更高版本,您可以通过从菜单栏中依次选择<code>Refactor > Migrate to AndroidX</code>,快速迁移现有项目以使用 AndroidX。</p><p>如果您有任何尚未迁移至 AndroidX 命名空间的 Maven 依赖项,那么当您在<code>gradle.properties</code> 文件中将以下两个标记设置为 true 时,Android Studio 编译系统也会为您迁移这些依赖项:</p><p><code>android.useAndroidX=true</code><br><code>android.enableJetifier=true</code></p><p>要迁移未使用任何第三方库但带有需要转换的依赖项的现有项目,可以将 android.useAndroidX 标记设置为 true,并将 android.enableJetifier 标记设置为 false。</p>]]></content>
<summary type="html">
<h1 id="Jetpack之Androidx介绍"><a href="#Jetpack之Androidx介绍" class="headerlink" title="Jetpack之Androidx介绍"></a>Jetpack之Androidx介绍</h1><h4 id="一-由来"><a href="#一-由来" class="headerlink" title="一. 由来"></a>一. 由来</h4><p>在Google I/O 2018上,Android团队宣布了AndroidX。</p>
<p> AndroidX 是对 android.support.* 包的整理后产物。由于之前的 support 包过于混乱,所以,Google 推出了AndroidX。</p>
<p>因此,AndroidX本质上其实就是对Android Support Library进行的一次升级。</p>
<p>自support v7:28开始,大部分support包都会迁移到androidx下。</p>
<h5 id="android-support-包介绍:"><a href="#android-support-包介绍:" class="headerlink" title="android.support.*包介绍:"></a>android.support.*包介绍:</h5><p>如果在低版本Android平台上开发一个应用程序,而应用程序又想使用高版本才拥有的功能,就需要使用Support库。</p>
<ul>
<li><p>Android Support v4: 这个包是为了照顾1.6及更高版本而设计的,这个包是使用最广泛的,eclipse新建工程时,都默认带有了。</p>
</li>
<li><p>Android Support v7: 这个包是为了考虑照顾2.1及以上版本而设计的,但不包含更低,故如果不考虑1.6,我们可以采用再加上这个包,另外注意,v7是要依赖v4这个包的,即:两个得同时被包含。</p>
</li>
<li><p>Android Support v13 : 这个包的设计是为了android 3.2及更高版本的,一般我们都不常用,平板开发中能用到。</p>
</li>
</ul>
</summary>
<category term="Jetpack" scheme="https://inote.fun/categories/Jetpack/"/>
<category term="Androidx" scheme="https://inote.fun/categories/Jetpack/Androidx/"/>
<category term="Androidx" scheme="https://inote.fun/tags/Androidx/"/>
</entry>
<entry>
<title>Android_Jetpack简介</title>
<link href="https://inote.fun/2019/11/01/Android%E4%B9%8BJetpack%E7%AE%80%E4%BB%8B/"/>
<id>https://inote.fun/2019/11/01/Android之Jetpack简介/</id>
<published>2019-11-01T12:39:40.000Z</published>
<updated>2019-11-01T14:33:51.704Z</updated>
<content type="html"><![CDATA[<h1 id="Android之Jetpack简介"><a href="#Android之Jetpack简介" class="headerlink" title="Android之Jetpack简介"></a>Android之Jetpack简介</h1><blockquote><p> 2017 年的 Google IO 宣布 Kotlin 成为 Android 开发的官方语言。<br> 2018年谷歌I/O 发布了一系列辅助android开发者的实用工具,合称Jetpack,以帮助开发者构建出色的 Android 应用。</p></blockquote><h4 id="一-什么是Jetpack:"><a href="#一-什么是Jetpack:" class="headerlink" title="一.什么是Jetpack:"></a>一.什么是Jetpack:</h4><p> Jetpack 是一套库、工具和指南,可帮助开发者更轻松地编写优质应用。这些组件可帮助您遵循最佳做法、让您摆脱编写样板代码的工作并简化复杂任务,以便您将精力集中放在所需的代码上。<br>换言之,Google利用Jetpack将一些优秀的Android组件库进行了标准化。</p><h4 id="二-作用:"><a href="#二-作用:" class="headerlink" title="二.作用:"></a>二.作用:</h4><p>Android Jetpack 完美兼容 Kotlin 语言,利用 Android KTX 可大幅节省代码量。<br>Jetpack 包含与平台 API 解除捆绑的 androidx.* 软件包库。这意味着,它可以提供向后兼容性,且比 Android 平台的更新频率更高,以此确保您始终可以获取最新且最好的 Jetpack 组件版本。</p><ul><li>加速开发:组件可以单独采用(不过这些组件是为协同工作而构建的),同时利用 Kotlin 语言功能帮助您提高工作效率。</li><li>消除样板代码:Android Jetpack 可管理繁琐的 Activity(如后台任务、导航和生命周期管理)。以便您可以专注于如何让自己的应用出类拔萃。</li><li>构建高质量的强大应用:Jetpack 组件围绕现代化设计实践构建而成,具有向后兼容性,可以减少崩溃和内存泄漏。</li></ul><a id="more"></a><h4 id="三-Jetpack包含那些组件:"><a href="#三-Jetpack包含那些组件:" class="headerlink" title="三.Jetpack包含那些组件:"></a>三.Jetpack包含那些组件:</h4><p> Android Jetpack 组件覆盖以下 4 个方面:基础(Foundation)、架构(Architecture)、行为(Behavior) 、界面(UI)。</p><p><img src="/images/jetpact1.png" alt="jetpact1"></p><h5 id="Foundation"><a href="#Foundation" class="headerlink" title="Foundation"></a>Foundation</h5><p>包含:Android KTX,AppCompat, Auto, 检测, Multidex, 安全, 测试, TV,Wear OS by Google。</p><h6 id="Android-KTX"><a href="#Android-KTX" class="headerlink" title="Android KTX"></a>Android KTX</h6><p>Android KTX 是一组 Kotlin 扩展程序,属于 Android Jetpack 系列。它优化了供 Kotlin 使用的 Jetpack 和 Android 平台 API。Android KTX 旨在让您利用 Kotlin 语言功能(例如扩展函数/属性、lambda、命名参数和参数默认值),以更简洁、更愉悦、更惯用的方式使用 Kotlin 进行 Android 开发。Android KTX 不会向现有的 Android API 添加任何新功能。</p><h6 id="AppCompat"><a href="#AppCompat" class="headerlink" title="AppCompat"></a>AppCompat</h6><p>在较低版本的Android 系统上恰当地降级。AppCompat就是指v7 appcompat库。<br>此库添加了对操作栏用户界面设计模式的支持。这个库包括对Material Design用户界面实现的支持。也就是说,我们可以借助该库,对Material Design有更便捷和兼容性更好的实现。</p><h6 id="Auto"><a href="#Auto" class="headerlink" title="Auto"></a>Auto</h6><p>Android Auto 提供了适用于所有车辆的标准化界面和用户交互模式。作为设计者,您无需担心车辆特有的硬件差异(如屏幕分辨率、软件界面、旋钮和触摸式控件)。</p><h6 id="检测"><a href="#检测" class="headerlink" title="检测"></a>检测</h6><p>快速对基于 Kotlin 或 Java 的代码进行基准化分析。该库会处理预热,衡量代码性能,并将基准化分析结果输出到 Android Studio 控制台。由于这些步骤涉及停用调试功能以获得准确的性能结果,因此您不会将更改提交至源代码控制系统中。</p><h6 id="Multidex"><a href="#Multidex" class="headerlink" title="Multidex"></a>Multidex</h6><p>方法数超过 64K 的应用启用多 dex 文件( 65,536 方法数限制)。</p><h5 id="Architecture"><a href="#Architecture" class="headerlink" title="Architecture"></a>Architecture</h5><p>包含:DataBind, Lifecycles, LiveData, Navigation, Paging, Room, ViewModel, WorkManager.</p><h6 id="DataBind"><a href="#DataBind" class="headerlink" title="DataBind"></a>DataBind</h6><p>可以使用声明性格式(而非程序化地)将布局中的界面组件绑定到应用中的数据源。<br>即:将布局组件与源数据绑定,使源数据变化的同时布局组件及时同步更新。</p><h6 id="Lifecycles"><a href="#Lifecycles" class="headerlink" title="Lifecycles"></a>Lifecycles</h6><p>用来管理和响应 Activity / Fragment 的生命周期的变化,帮助我们编写出更易于组织且通常更加轻量级的代码,让代码变得更易于维护。<br>Lifecycle 是一个类,它持有 Activity / Fragment 生命周期状态的信息,并允许其它对象观察此状态。</p><h6 id="LiveData"><a href="#LiveData" class="headerlink" title="LiveData"></a>LiveData</h6><p>LiveData是一个可观察的数据持有者类。与常规observable不同,LiveData是生命周期感知的。</p><h6 id="Navigation"><a href="#Navigation" class="headerlink" title="Navigation"></a>Navigation</h6><p>是指支持用户导航、进入和退出应用中不同内容片段的交互。Android Jetpack 的导航组件可帮助您实现导航,无论是简单的按钮点击,还是应用栏和抽屉式导航栏等更为复杂的模式,该组件均可应对。导航组件还通过遵循一套既定原则来确保一致且可预测的用户体验。</p><h6 id="Paging"><a href="#Paging" class="headerlink" title="Paging"></a>Paging</h6><p>逐步从您的数据源按需加载信息。<br>分页库。</p><h6 id="Room"><a href="#Room" class="headerlink" title="Room"></a>Room</h6><p>Room是Google为了简化旧式的SqlLite操作专门提供的一个SqlLite的ORM抽象层框架库。</p><h6 id="ViewModel"><a href="#ViewModel" class="headerlink" title="ViewModel"></a>ViewModel</h6><p> 是以生命周期的方式存储与管理UI相关数据。</p><h6 id="WorkManager"><a href="#WorkManager" class="headerlink" title="WorkManager"></a>WorkManager</h6><p>管理一些要在后台工作的任务, – 即使你的应用没启动也能保证任务能被执行。<br>例如:<br>向后端服务发送日志分析<br>定期与服务器同步应用程序数据</p><p><img src="/images/jetpact2.png" alt="jetpact2"></p>]]></content>
<summary type="html">
<h1 id="Android之Jetpack简介"><a href="#Android之Jetpack简介" class="headerlink" title="Android之Jetpack简介"></a>Android之Jetpack简介</h1><blockquote>
<p> 2017 年的 Google IO 宣布 Kotlin 成为 Android 开发的官方语言。<br> 2018年谷歌I/O 发布了一系列辅助android开发者的实用工具,合称Jetpack,以帮助开发者构建出色的 Android 应用。</p>
</blockquote>
<h4 id="一-什么是Jetpack:"><a href="#一-什么是Jetpack:" class="headerlink" title="一.什么是Jetpack:"></a>一.什么是Jetpack:</h4><p> Jetpack 是一套库、工具和指南,可帮助开发者更轻松地编写优质应用。这些组件可帮助您遵循最佳做法、让您摆脱编写样板代码的工作并简化复杂任务,以便您将精力集中放在所需的代码上。<br>换言之,Google利用Jetpack将一些优秀的Android组件库进行了标准化。</p>
<h4 id="二-作用:"><a href="#二-作用:" class="headerlink" title="二.作用:"></a>二.作用:</h4><p>Android Jetpack 完美兼容 Kotlin 语言,利用 Android KTX 可大幅节省代码量。<br>Jetpack 包含与平台 API 解除捆绑的 androidx.* 软件包库。这意味着,它可以提供向后兼容性,且比 Android 平台的更新频率更高,以此确保您始终可以获取最新且最好的 Jetpack 组件版本。</p>
<ul>
<li>加速开发:组件可以单独采用(不过这些组件是为协同工作而构建的),同时利用 Kotlin 语言功能帮助您提高工作效率。</li>
<li>消除样板代码:Android Jetpack 可管理繁琐的 Activity(如后台任务、导航和生命周期管理)。以便您可以专注于如何让自己的应用出类拔萃。</li>
<li>构建高质量的强大应用:Jetpack 组件围绕现代化设计实践构建而成,具有向后兼容性,可以减少崩溃和内存泄漏。</li>
</ul>
</summary>
<category term="Jetpack" scheme="https://inote.fun/categories/Jetpack/"/>
<category term="Jetpack" scheme="https://inote.fun/tags/Jetpack/"/>
</entry>
<entry>
<title>收藏网络资源分享</title>
<link href="https://inote.fun/2019/10/26/%E6%94%B6%E8%97%8F%E7%BD%91%E7%BB%9C%E8%B5%84%E6%BA%90%E5%88%86%E4%BA%AB/"/>
<id>https://inote.fun/2019/10/26/收藏网络资源分享/</id>
<published>2019-10-26T03:05:57.000Z</published>
<updated>2019-10-26T03:29:49.100Z</updated>
<content type="html"><![CDATA[<h1 id="收藏网络资源分享"><a href="#收藏网络资源分享" class="headerlink" title="收藏网络资源分享"></a>收藏网络资源分享</h1><p>尚硅谷Android企业级技术视频 </p><p><img src="/images/%E5%B0%9A%E7%A1%85%E8%B0%B7Android%E4%BC%81%E4%B8%9A%E7%BA%A7%E6%8A%80%E6%9C%AF%E8%A7%86%E9%A2%91.png" alt="尚硅谷Android企业级技术视频"></p><p>链接: <a href="https://pan.baidu.com/s/1oyaSlbpW5ZIN4ZVNIc16Kg" target="_blank" rel="noopener">https://pan.baidu.com/s/1oyaSlbpW5ZIN4ZVNIc16Kg</a> 提取码: ec9a</p><hr><a id="more"></a><p>Android FrameWork底层开发视频全套 </p><p><img src="/images/AndroidFrameWork%E5%BA%95%E5%B1%82%E5%BC%80%E5%8F%91%E8%A7%86%E9%A2%91%E5%85%A8%E5%A5%97.png" alt="AndroidFrameWork底层开发视频全套"></p><p>链接: <a href="https://pan.baidu.com/s/1EbvcJFqOfMkLcqdY4eEIlg" target="_blank" rel="noopener">https://pan.baidu.com/s/1EbvcJFqOfMkLcqdY4eEIlg</a> 提取码: 4u5a</p><hr><p>尚学堂java马士兵视频全套 </p><p><img src="/images/%E5%B0%9A%E5%AD%A6%E5%A0%82java%E9%A9%AC%E5%A3%AB%E5%85%B5%E8%A7%86%E9%A2%91%E5%85%A8%E5%A5%97.png" alt="尚学堂java马士兵视频全套"></p><p>链接: <a href="https://pan.baidu.com/s/1YfdictXlWtZDKh9cbBhLqA" target="_blank" rel="noopener">https://pan.baidu.com/s/1YfdictXlWtZDKh9cbBhLqA</a> 提取码: bwai</p><hr><p>C#入门到精通视频教程 </p><p><img src="/images/CShap%E5%85%A5%E9%97%A8%E5%88%B0%E7%B2%BE%E9%80%9A%E8%A7%86%E9%A2%91%E6%95%99%E7%A8%8B.png" alt="C#入门到精通视频教程"></p><p>链接: <a href="https://pan.baidu.com/s/1ZErqeH3lYD9P8noT-i4Bmg" target="_blank" rel="noopener">https://pan.baidu.com/s/1ZErqeH3lYD9P8noT-i4Bmg</a> 提取码: gycw</p><hr><p>Android基础资料包pdf </p><p><img src="/images/Android%E5%9F%BA%E7%A1%80%E8%B5%84%E6%96%99%E5%8C%85pdf.png" alt="Android基础资料包pdf"></p><p>链接: <a href="https://pan.baidu.com/s/1zFlH1bjue1hJibRwO6UqmQ" target="_blank" rel="noopener">https://pan.baidu.com/s/1zFlH1bjue1hJibRwO6UqmQ</a> 提取码: fymt</p><hr><p>大话设计模式全本 </p><p>链接: <a href="https://pan.baidu.com/s/17Jl1csmfo2WjergkzeNGGw" target="_blank" rel="noopener">https://pan.baidu.com/s/17Jl1csmfo2WjergkzeNGGw</a> 提取码: fmsy</p><hr><p>Android源码 </p><p><img src="/images/Android%E6%BA%90%E7%A0%81.png" alt="Android源码 "></p><p>链接: <a href="https://pan.baidu.com/s/11VnHrNXQIw2U0ezlqZbcuA" target="_blank" rel="noopener">https://pan.baidu.com/s/11VnHrNXQIw2U0ezlqZbcuA</a> 提取码: nn64</p><hr><p>老罗Android开发视频教程 </p><p><img src="/images/%E8%80%81%E7%BD%97Android%E5%BC%80%E5%8F%91%E8%A7%86%E9%A2%91%E6%95%99%E7%A8%8B.png" alt="老罗Android开发视频教程"></p><p>链接: <a href="https://pan.baidu.com/s/1gWcX1XECRq6S5A3xe6hHTQ" target="_blank" rel="noopener">https://pan.baidu.com/s/1gWcX1XECRq6S5A3xe6hHTQ</a> 提取码: 5i8q</p><hr><p>python自学视频 </p><p><img src="/images/python%E8%87%AA%E5%AD%A6%E8%A7%86%E9%A2%91.png" alt="python自学视频 "></p><p>链接: <a href="https://pan.baidu.com/s/17ef8w1ba0o8KADhJ76SbFQ" target="_blank" rel="noopener">https://pan.baidu.com/s/17ef8w1ba0o8KADhJ76SbFQ</a> 提取码: 22w7</p><hr><p>kotlin系统入门与进阶 </p><p><img src="/images/kotlin%E7%B3%BB%E7%BB%9F%E5%85%A5%E9%97%A8%E4%B8%8E%E8%BF%9B%E9%98%B6.png" alt="kotlin系统入门与进阶"></p><p>链接: <a href="https://pan.baidu.com/s/1x8ukxA4Ffjs3-hGXF29Oxg" target="_blank" rel="noopener">https://pan.baidu.com/s/1x8ukxA4Ffjs3-hGXF29Oxg</a> 提取码: 464j</p><hr><p>深入理解Android卷1,卷2,Wifi卷 PDF版 </p><p><img src="/images/%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3Android%E5%8D%B7.png" alt="深入理解Android卷"></p><p>链接: <a href="https://pan.baidu.com/s/1a3-5Ve1atoMWGXkwPQY6ZQ" target="_blank" rel="noopener">https://pan.baidu.com/s/1a3-5Ve1atoMWGXkwPQY6ZQ</a> 提取码: 44fd</p><hr>]]></content>
<summary type="html">
<h1 id="收藏网络资源分享"><a href="#收藏网络资源分享" class="headerlink" title="收藏网络资源分享"></a>收藏网络资源分享</h1><p>尚硅谷Android企业级技术视频 </p>
<p><img src="/images/%E5%B0%9A%E7%A1%85%E8%B0%B7Android%E4%BC%81%E4%B8%9A%E7%BA%A7%E6%8A%80%E6%9C%AF%E8%A7%86%E9%A2%91.png" alt="尚硅谷Android企业级技术视频"></p>
<p>链接: <a href="https://pan.baidu.com/s/1oyaSlbpW5ZIN4ZVNIc16Kg" target="_blank" rel="noopener">https://pan.baidu.com/s/1oyaSlbpW5ZIN4ZVNIc16Kg</a> 提取码: ec9a</p>
<hr>
</summary>
<category term="知识点" scheme="https://inote.fun/categories/%E7%9F%A5%E8%AF%86%E7%82%B9/"/>
<category term="网盘资源" scheme="https://inote.fun/tags/%E7%BD%91%E7%9B%98%E8%B5%84%E6%BA%90/"/>
</entry>
<entry>
<title>kotlin之Lambda表达式</title>
<link href="https://inote.fun/2019/10/26/kotlin%E4%B9%8BLambda%E8%A1%A8%E8%BE%BE%E5%BC%8F/"/>
<id>https://inote.fun/2019/10/26/kotlin之Lambda表达式/</id>
<published>2019-10-25T17:01:49.000Z</published>
<updated>2019-10-25T17:03:04.984Z</updated>
<content type="html"><![CDATA[<h1 id="kotlin之Lambda表达式"><a href="#kotlin之Lambda表达式" class="headerlink" title="kotlin之Lambda表达式"></a>kotlin之Lambda表达式</h1><blockquote><p> Java8中引入,匿名函数。</p><p> 普通的Lambda表达式类似对应kotlin普通函数的声明,而带接收者的lambda表达式则类似对应kotlin的扩展函数。</p></blockquote><h5 id="lambda的基本语法"><a href="#lambda的基本语法" class="headerlink" title="lambda的基本语法"></a>lambda的基本语法</h5><p><code>{ variable -> body_of_function}</code> 示例:<code>{ x:Int, y:Int -> x + y }</code></p><p>lambda表达式始终用花括号包围,实参并没有用括号括起来。箭头把实参列表和lambda的函数体隔开</p><a id="more"></a><h5 id="lambda作为函数的参数传递"><a href="#lambda作为函数的参数传递" class="headerlink" title="lambda作为函数的参数传递"></a>lambda作为函数的参数传递</h5><p>示例:<code>val sum = { x: Int, y: Int -> x + y }</code></p><p>可以把lambda表达式存储在一个变量中,把这个变量当做普通函数对待,也可以直接写作函数参数。</p><h5 id="lambda表达式的返回值"><a href="#lambda表达式的返回值" class="headerlink" title="lambda表达式的返回值"></a>lambda表达式的返回值</h5><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></pre></td><td class="code"><pre><span class="line">val isOddNumber = { number: Int -></span><br><span class="line"> println("number is $number")</span><br><span class="line"> number % 2 == 1</span><br><span class="line"> }</span><br></pre></td></tr></table></figure><p>lambda表达式返回值总是返回函数体内部最后一行表达式的值</p><h5 id="invoke-方法"><a href="#invoke-方法" class="headerlink" title="invoke 方法"></a>invoke 方法</h5><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">fun main(args: Array<String>) { </span><br><span class="line"> val add= { </span><br><span class="line"> left: Int, right: Int </span><br><span class="line"> -> </span><br><span class="line"> left + right </span><br><span class="line"> } </span><br><span class="line"> println(add.invoke(2, 3)) </span><br><span class="line"> }</span><br></pre></td></tr></table></figure><p>一个变量 add,赋值为一个 Lambda 表达式。Lambda 表达式用一对大括号括起来,后面先依次写下参数及其类型,如果没有就不写,接着写下 -> ,这表明后面的是函数体了,函数体的最后一句的表达式结果就是 Lambda 表达式的返回值,比如这里的返回值就是参数求和的结果。后面我们用 () 的形式调用这个 Lambda 表达式,其实这个 () 对应的是 invoke 方法。</p><h5 id="结合kotlin-扩展函数使用"><a href="#结合kotlin-扩展函数使用" class="headerlink" title="结合kotlin 扩展函数使用"></a>结合kotlin 扩展函数使用</h5><p><a href="https://inote.fun/2019/09/28/Kotlin%E4%B8%8Ejava%E5%AF%B9%E6%AF%94/">Kotlin与java对比</a></p><hr><p>注意:语法简化是把双刃剑,简化固然不错,使用简单方便,但是不能滥用,也需要考虑到代码的可读性.上图中Lambda化简成的最简单形式用it这种,一般在多个Lambda嵌套的时候不建议使用,严重造成代码可读性,到最后估计连开发者都不知道it指代什么了。</p><p><img src="/images/kotlin_vs_java.png" alt="kotlinVSjava"></p>]]></content>
<summary type="html">
<h1 id="kotlin之Lambda表达式"><a href="#kotlin之Lambda表达式" class="headerlink" title="kotlin之Lambda表达式"></a>kotlin之Lambda表达式</h1><blockquote>
<p> Java8中引入,匿名函数。</p>
<p> 普通的Lambda表达式类似对应kotlin普通函数的声明,而带接收者的lambda表达式则类似对应kotlin的扩展函数。</p>
</blockquote>
<h5 id="lambda的基本语法"><a href="#lambda的基本语法" class="headerlink" title="lambda的基本语法"></a>lambda的基本语法</h5><p><code>{ variable -&gt; body_of_function}</code> 示例:<code>{ x:Int, y:Int -&gt; x + y }</code></p>
<p>lambda表达式始终用花括号包围,实参并没有用括号括起来。箭头把实参列表和lambda的函数体隔开</p>
</summary>
<category term="Android" scheme="https://inote.fun/categories/Android/"/>
<category term="kotlin" scheme="https://inote.fun/categories/Android/kotlin/"/>
<category term="kotlin" scheme="https://inote.fun/tags/kotlin/"/>
</entry>
<entry>
<title>第一次买房经历</title>
<link href="https://inote.fun/2019/10/20/%E7%AC%AC%E4%B8%80%E6%AC%A1%E4%B9%B0%E6%88%BF%E7%BB%8F%E5%8E%86/"/>
<id>https://inote.fun/2019/10/20/第一次买房经历/</id>
<published>2019-10-20T15:21:09.000Z</published>
<updated>2019-10-25T16:22:59.285Z</updated>
<content type="html"><![CDATA[<h1 id="第一次买房经历"><a href="#第一次买房经历" class="headerlink" title="第一次买房经历"></a>第一次买房经历</h1><blockquote><p>为什么标题是:第一次买房经历,因为内心还是希望能有第二次….哈哈哈哈</p></blockquote><p>关键字:</p><ul><li><p><strong>坐标:江苏-南京</strong></p></li><li><p><strong>二手房</strong></p></li></ul><a id="more"></a><h4 id="购房证明"><a href="#购房证明" class="headerlink" title="购房证明"></a>购房证明</h4><ul><li>1.三年内24个月社保(补缴无效),没办法太多补缴了,中间有近一年没有交社保。此路对于我不通。</li><li>2.本科毕业,可以直接落户南京集体户口。刚过完年,又回了一趟老家迁户口。集体户口就是一张纸,户主是不认识的没有血缘关系的一个名字,地址是虚拟的地址。一张纸远没有小红本安全感,太low。还好只是过渡,如果不是需要,真心不推荐落集体户,农村户口未来肯定越来越吃香,我是之前迁到学校,毕业,非师范类专业,户口转回老家,农转非了。蛋疼。<br>政策又有变化了,现在好像大专,也可以落户六合,溧水,高淳购房。<h4 id="看房"><a href="#看房" class="headerlink" title="看房"></a>看房</h4>根据预算,选区域。钱少也有钱少的好处,好处就是选择范围小,没必要那么纠结地段,照自己能买的选就是了。</li></ul><p>什么安居客,我爱我家,链家手机里都装了一个遍。</p><p>其中看房过程也遇到许多好玩的事:</p><ul><li>安居客水分稍大,也就是假房源比较多。</li><li>链家中介费比较贵,好像3个点,不能谈,有点忘记了,预算本来就吃紧,但是有些房源业主与链家签了合同,也就是只能在链家成交,如果约定时间没有成交,链家会补业主钱,这个是个坑,有一个房子看中了,就因为这个独家的合同,作罢。</li><li>我爱我家,中介费比链家稍低,好像2个点左右,能谈。如果没有认识的靠谱中介,推荐我爱我家吧,至少正规,多花点钱,买心安,我爱我家,那个中介小伙,也带我看了不少房,确实靠谱点,虽然后面没在他那买,最后有点不愉快,大不了删微信就是了。</li><li>链家中介,给人急功近利的感觉,还没看几套,没事就吐露出一会这个房被卖了,那个房被卖了,逼单,让人有点恼火,最后干脆不在链家看房了。</li><li>安居客鱼龙混杂,因为朋友是中介,本来安居客里房友带看,然后准备朋友那边买,业主跟房友中介通气,当然,这事我也没办地道,但是最后房友竟然同我朋友说要吃我3个点,他们平分,当然房友不知道对方是我朋友,奇葩,吃我3个点,我可能买吗,看了这么多房,真没那个房子说一定要买的感受。当然约谈价格,我朋友偷偷发短息后,我去都没去。作罢。</li><li>其中也看到过,业主急卖的,低于市场价六七万,犹豫了一晚上,第二天联系,就卖出去了。</li></ul><p>最后是在陪别人看房过程,看中了最后买的房。真是偶然,跟人生很像,不要说一定要什么什么样,可能决定就在某个当下。唯一思索的就是,未来大概率不后悔即可。目前来看,还可以,我妈很喜欢。</p><h4 id="谈价"><a href="#谈价" class="headerlink" title="谈价"></a>谈价</h4><p>谈价,我真的不会讲价。我觉得看重了,差不多,不必市场价贵就行了。</p><p>最后还是我朋友跟另一个同事合伙谈价,我最后拍板就行了。我内心是准备即使谈不了,目前也没有比市场价高多少,也准备买的,当然,如果能谈点更好。</p><p>最后谈下来了1.3w,也还行吧,听说业主之前卖了好几套,内心估计稳的一笔,谈不了多少。</p><h4 id="贷款"><a href="#贷款" class="headerlink" title="贷款"></a>贷款</h4><p>根据中介沟通的担保公司,走贷款流程。全程因为相信中介的朋友,就是不停的签字,估计担保公司都很诧异,怎么签的这么快,估计别人来都要把文件都看一遍,我是,对方告诉我那签字,我扫了一眼合同名字,就直接签了。</p><p>走的是组合贷,商业30年,公积金20年。等了大概半个月左右,就通知审核通过了,可以网签了。办事效率现在比以前快多了。</p><h4 id="网签过户"><a href="#网签过户" class="headerlink" title="网签过户"></a>网签过户</h4><p>按约定的时间,双方到房产局网签过户,跟着中介,交税交钱。</p><p>因为房子,原来业主不住。网签过户后,我就把首付和尾款都给了,对方给了房子钥匙。</p><p>剩下的就是业主等下款。估计等了一个多月,钱先到我账上,呆了一天,就自动划到对方账上了。</p><p><img src="/images/%E6%88%BF%E4%BA%A7%E6%9C%AC.jpg" alt="小红本谁不爱"></p><hr><p>接下来,就是吃土,还贷款。</p>]]></content>
<summary type="html">
<h1 id="第一次买房经历"><a href="#第一次买房经历" class="headerlink" title="第一次买房经历"></a>第一次买房经历</h1><blockquote>
<p>为什么标题是:第一次买房经历,因为内心还是希望能有第二次….哈哈哈哈</p>
</blockquote>
<p>关键字:</p>
<ul>
<li><p><strong>坐标:江苏-南京</strong></p>
</li>
<li><p><strong>二手房</strong></p>
</li>
</ul>
</summary>
<category term="心情" scheme="https://inote.fun/categories/%E5%BF%83%E6%83%85/"/>
<category term="购房" scheme="https://inote.fun/tags/%E8%B4%AD%E6%88%BF/"/>
</entry>
<entry>
<title>一次车被刮蹭的经历</title>
<link href="https://inote.fun/2019/10/20/%E4%B8%80%E6%AC%A1%E8%BD%A6%E8%A2%AB%E5%88%AE%E8%B9%AD%E7%9A%84%E7%BB%8F%E5%8E%86/"/>
<id>https://inote.fun/2019/10/20/一次车被刮蹭的经历/</id>
<published>2019-10-20T14:27:03.000Z</published>
<updated>2019-10-25T16:23:14.242Z</updated>
<content type="html"><![CDATA[<h1 id="一次车被刮蹭的经历"><a href="#一次车被刮蹭的经历" class="headerlink" title="一次车被刮蹭的经历"></a>一次车被刮蹭的经历</h1><p>事情要从昨天星期六说起。</p><p>7月份开始一直单休,好不容易昨天双休了。自然饱饱的睡了一觉,然后起来泡杯咖啡好好逛逛博客,一天的时间输出两篇文章,本来是准备写一篇的,写着写着,感觉有点长,啰嗦,跑题,干脆当两篇发了。</p><p>晚上,在厨房炒菜煮饭吃。突然听到有人敲门。赶紧跑去开门,当时一直在想是谁呢?难道是抄燃气表的,打开门。原来是一个男的,门一开,那人就开口。说你车被人撞了,我一惊,以为是骗子。然后他准确的描述了我的车停的位置,我还是有点不信的,我也没敢表露出来,接着听。然后他说是找物业要的我的住址,还给我看了聊天记录。这时,才相信我车真被人刮蹭了。</p><p>他然后继续说,我听着,嘴里说着谢谢。他说车被撞的时候,他正好在边上,听到很大声,我说,车撞的严重不?他说听着反正很大声,然后有点变形了。我心里一惊,妈的,这么严重啊!我停车的时候就怕被人蹭,还专门把车停的很里面,至少车位靠路的三分之一还空出来的,这都能被人撞,那人开车技术也太渣了吧。然后给我看了下他拍的照片,一个照片是撞我车的那个车牌号,蓝色雪铁龙,一个照片是拍的我车被刮了好几条痕,白色漆露出了黑色的底。奶奶的,一天呆在家里没出门,也这么倒霉啊。看完照片,感觉也还好,没特别严重,毕竟车开了三年多了,也没那么心疼。前几个月同事新买的车,停路边,被共享单车刮了下,都报警了,但是没有监控,不知道肇事车,警察没管。</p><p>然后那人告诉我他住我楼上,让我赶紧下去看看吧。下午发生的事,这都晚上了,还以为我知道车被撞了。我说着谢谢,送他走后,也没立即下楼,有点饿,继续回厨房炒菜,幸好刚才把火关了,不然这白菜就要黑了。继续炒菜,然后吃饭。</p><a id="more"></a><p><img src="/images/%E8%BD%A6%E5%88%AE%E8%B9%AD1.jpg" alt="车刮蹭"></p><p>但是心里总有点疙瘩,边吃饭边搜索了下“车被刮,怎么办?”,大部分答案都是:1.找监控查车牌,查人。2.122交通事故报案,3.48小时内保险公司报备。我已经知道车牌了,但是我想着的是需要联系方式,联系到肇事人。</p><ul><li>上支付宝小程序找了下看看能不能车牌号查到联系人电话,搜了一个输入车牌号,没找到。也就是那个人没有使用过””一键挪车’’功能,数据库没有他记录。作罢!</li><li></li><li>打122,允许定位,然后小姐姐接到电话。问我人有没事,备案(双方车牌号,双方车型,车颜色),询问事故地点,告诉我一会有当地的交警会给我打电话。几分钟后,就来电话了,继续备案(双方车牌号,双方车型,车颜色,我的身份证号),然后我问能查到对方手机号吗?需要我工作日去当地的交警大队作详细备案,事故确认后,才会联系对方,然后约时间双方一起到交警大队确认事故责任。卧槽!这么麻烦,当然我没说出来,口中还是谢谢,然后挂了电话。报案这么麻烦,如果按这个流程,至少要请两天假。得不偿失啊!一会下去看看车严重不,在说吧。但是内心基本这个办法pass了,还是私了比较经济实惠。前提是车损失不严重,也就是500以内吧。内心挣扎了一番。<br><img src="/images/%E8%BD%A6%E5%88%AE%E8%B9%AD2.jpg" alt="122通话"></li><li></li><li>因为刚才楼上邻居说,肇事车不是小区内的车。所以我没第一时间找物业管家。但是如果报案那条不行,只能找物业查一查车牌,赌一赌了。给物业发了短信,让帮查一查车牌。但是今天太晚了,需要明天。我担心物业怕担责任,就算查到了,也不会说是小区的车。我故意给她说,如果不是小区的车,我就要报案。这样我肯定能查出来车是不是小区的,这样她不会唐塞我了,本着大事化小,小时化了,真报案处理,花费双方太多时间,不划算。</li></ul><p>第二天,也就是今天,一直没等到物业消息,经过一晚上,内心也不想报案了,流程太繁琐了,如果不是小区的车,也就自认倒霉吧,只是便宜了那个人,开的什么车,周末,小区内那么宽过道都能刮到我车。还是发了条消息,问是不是小区车。过了一会,物业给了我回复,是小区的车。没有联系方式,是租户,不是业主。<br><img src="/images/%E8%BD%A6%E5%88%AE%E8%B9%AD3.jpg" alt="物业"></p><p>内心小小的激动了下,还好。能联系上对方,就好说,一会去找他,如果他态度不好,那也就麻烦就麻烦,直接走报案流程走。如果态度比较ok,愿意私了,少就少点吧,都是小区,也不准备闹多大动静,只是想给他个警醒,撞车了,就一走了之。要知道我车前挡风玻璃是有我联系方式的(临时停车,请多关照)。当然最终重要的是,要非常谢谢楼上的邻居目睹了刮蹭经过,而且还拍了对方的车牌号,并且不怕麻烦的联系物业,告诉我。</p><p>抽根烟,想想买车第一年过年回老家,上高速开了6个多小时,下高速经过县城的时候,刮了别人的车,比我现在被人刮轻多了,被人敲了500出去。没办法,花钱消灾,懒得争吵。今天,我是被刮,但是感觉也没硬气太多,确实车被刮,挺烦躁的,需要花时间去维修,都是时间啊。也不准备要多少钱,网上搜索了下,做漆,一般都要三四百,那到时候要四百吧。</p><p>内心OS了一番,按物业给的地址,去找人了。敲门,问了下,是不是xxxxx车牌号的车主,不是,不过是合租的另一个人,然后要了对方手机号,打电话,说了下事,对方态度还行,很快就承认了,说但是走的急,没有联系方式,但是我车前挡风玻璃是留了联系方式的,也不纠结了,怎么处理,走保险,但是需要48小时内报备,对方看来也没想走保险,只是说了下一种处理办法。那我就直说了,私了吧。出价,400,不行太高了,做漆要不了那么多,200,不行,我还要请假花时间去处理,做漆至少三四百呢,折中300.不扯了。成交,微信转账。</p><p>事情处理完毕,不说300能不能解决事情吧,确实车被刮,挺恼火的,去维修需要时间,还要放在维修厂几天。只能说减少了点损失,把这事记录下来,也算让自己经历了。下次在遇到,至少知道怎么处理,事来了就解决,也不用老放心里添堵。<br><img src="/images/%E8%BD%A6%E5%88%AE%E8%B9%AD4.jpg" alt="报案回执短信"></p>]]></content>
<summary type="html">
<h1 id="一次车被刮蹭的经历"><a href="#一次车被刮蹭的经历" class="headerlink" title="一次车被刮蹭的经历"></a>一次车被刮蹭的经历</h1><p>事情要从昨天星期六说起。</p>
<p>7月份开始一直单休,好不容易昨天双休了。自然饱饱的睡了一觉,然后起来泡杯咖啡好好逛逛博客,一天的时间输出两篇文章,本来是准备写一篇的,写着写着,感觉有点长,啰嗦,跑题,干脆当两篇发了。</p>
<p>晚上,在厨房炒菜煮饭吃。突然听到有人敲门。赶紧跑去开门,当时一直在想是谁呢?难道是抄燃气表的,打开门。原来是一个男的,门一开,那人就开口。说你车被人撞了,我一惊,以为是骗子。然后他准确的描述了我的车停的位置,我还是有点不信的,我也没敢表露出来,接着听。然后他说是找物业要的我的住址,还给我看了聊天记录。这时,才相信我车真被人刮蹭了。</p>
<p>他然后继续说,我听着,嘴里说着谢谢。他说车被撞的时候,他正好在边上,听到很大声,我说,车撞的严重不?他说听着反正很大声,然后有点变形了。我心里一惊,妈的,这么严重啊!我停车的时候就怕被人蹭,还专门把车停的很里面,至少车位靠路的三分之一还空出来的,这都能被人撞,那人开车技术也太渣了吧。然后给我看了下他拍的照片,一个照片是撞我车的那个车牌号,蓝色雪铁龙,一个照片是拍的我车被刮了好几条痕,白色漆露出了黑色的底。奶奶的,一天呆在家里没出门,也这么倒霉啊。看完照片,感觉也还好,没特别严重,毕竟车开了三年多了,也没那么心疼。前几个月同事新买的车,停路边,被共享单车刮了下,都报警了,但是没有监控,不知道肇事车,警察没管。</p>
<p>然后那人告诉我他住我楼上,让我赶紧下去看看吧。下午发生的事,这都晚上了,还以为我知道车被撞了。我说着谢谢,送他走后,也没立即下楼,有点饿,继续回厨房炒菜,幸好刚才把火关了,不然这白菜就要黑了。继续炒菜,然后吃饭。</p>
</summary>
<category term="心情" scheme="https://inote.fun/categories/%E5%BF%83%E6%83%85/"/>
<category term="心情" scheme="https://inote.fun/tags/%E5%BF%83%E6%83%85/"/>
</entry>
<entry>
<title>关于程序员的第二职业</title>
<link href="https://inote.fun/2019/10/19/%E5%85%B3%E4%BA%8E%E7%A8%8B%E5%BA%8F%E5%91%98%E7%9A%84%E7%AC%AC%E4%BA%8C%E8%81%8C%E4%B8%9A/"/>
<id>https://inote.fun/2019/10/19/关于程序员的第二职业/</id>
<published>2019-10-19T09:59:57.000Z</published>
<updated>2019-10-21T13:55:10.604Z</updated>
<content type="html"><![CDATA[<h1 id="关于程序员的第二职业"><a href="#关于程序员的第二职业" class="headerlink" title="关于程序员的第二职业"></a>关于程序员的第二职业</h1><p>之前扯淡了下程序员的<a href="https://freefuncode.github.io/2019/10/01/%E5%85%B3%E4%BA%8E%E8%81%8C%E4%B8%9A%E7%94%9F%E6%B6%AF%E7%9A%84%E6%83%B3%E6%B3%95/" target="_blank" rel="noopener">关于职业生涯的想法</a>,那个概念有点大,直到最后,我也无法准确的给出我的规划,现在,就扯扯程序员的一些副业吧。</p><p><img src="/images/%E5%89%AF%E4%B8%9A1.jpg" alt="副业"></p><a id="more"></a><hr><h5 id="一-先来了解两个概念:"><a href="#一-先来了解两个概念:" class="headerlink" title="一 . 先来了解两个概念:"></a>一 . 先来了解两个概念:</h5><ul><li>什么叫斜杠青年?</li></ul><blockquote><p><strong>来自百科介绍</strong>:<br><strong>斜杠青年</strong>,指的是这样一个人群:他们不满足单一职业和身份的束缚,而是选择一种能够拥有多重职业和多重身份的多元生活。这些人在自我介绍中会用斜杠来区分,例如,张三,记者/演员/摄影师。<br>例子:工作时间是IDC行业的程序员,休息的时候就变成了笔耕不辍的作家,周末还能化身成变出一桌美味菜肴的营养师…这“程序猿/作家/营养师”的多重身份,就是对「斜杠青年」的诠释。<br>斜杠青年的出现并非偶然,而是社会发展的必然现象,也是进步的体现。这种进步使人类摆脱“工业革命”带来的限制和束缚,释放天性。</p></blockquote><ul><li>什么是T型青年?<blockquote><p>T型人才是一种新型人才类型。用字母“T”来表示他们的知识结构特点。“—”表示某一领域的专精,“|”表示知识的深度也就是知识面。当你在一个领域越专越精,知识面越广阔。你就越能触达到更高的顶峰。</p></blockquote></li></ul><p>从概念上,对于专业性领域比较强的职业,我偏向于建议向T型青年发展。如果是从事服务行业,专业不是那么强的职业,偏向于斜杠方向发展。</p><p>两种方式,没有对错。针对个人选择而已。两种方式都是提升自己综合素质,就像投资,只是投资策略不同,如果把领域专业技能提升换算成时间成本(即:只要花对应时间就能提升对应的专业水平),就是投资配额(花时间)比例不同。</p><p><img src="/images/%E5%89%AF%E4%B8%9A2.jpg" alt="副业"></p><hr><h5 id="二-程序员职业"><a href="#二-程序员职业" class="headerlink" title="二. 程序员职业"></a>二. 程序员职业</h5><p>从上面看出来,软件开发工作,不排除编程越来越普及,现在不是流行少儿编程吗,哈哈哈。但是目前来看属于专业性比较强的职业。也就是比较好的方向属于T型青年,也不排除个人对其他领域有很强的兴趣和爱好,对编程比较讨厌,只是碍于生活需要的选择,这些就另当别论了。</p><p>程序员,是一个专业比较强的职业。所以,我觉得,职业的头5-7年,还是本职技能积累提升的阶段,这个阶段还是以职业技能积累为主。</p><p>目前社会的一些想法:1-3:初级程序员,3-5年中级程序员,5-10年高级程序员。当然程序员技能不能完全按年龄来计算。只是一个大概的等级划到工龄来计算,所以我上面说职业头5-7年,还属于专业积累的过程。</p><p>当然,如果选择的第二职业与第一职业不冲突,相反还是相辅相成,也可以提前进行。</p><hr><h5 id="三-程序员的一些副业"><a href="#三-程序员的一些副业" class="headerlink" title="三.程序员的一些副业"></a>三.程序员的一些副业</h5><ul><li><p><strong>接私活</strong><br>平台,圈子比较重要,这个网上平台接,价格已经被压的死死的了。利润很低,锻炼下代码能力还行,挣钱,挣的也是幸苦钱。当然接一些你已经有成品,或者稍微改改就能交付的私活,还是很有赚头的。比较靠谱的是熟人介绍,所以需要平时的项目积累和人脉积累。</p></li><li><p><strong>投资,理财</strong><br>这个没有那个资本,还是当一个生活常识吧,不推荐发展成为职业。</p></li><li><p><strong>写作,公众号</strong><br>这是一个需要持续输出的职业,持续能输出干货。如果没有那个毅力,一般人坚持不下来。但是如果写出了名气,对于自己职业规划也是很有好处。</p></li><li><p><strong>开发自己的产品</strong><br>这个对个人能力要求最高,需要全栈技能。</p></li><li><p><strong>知识付费</strong><br>知识付费的红利期虽然已过,但是做付费课程永远都不迟。因为这行的新知识总是层出不穷。也不断有新人往里冲。<br>这是缺点也是优点,掌握第一手信息和熟练已有的技能都是副业的不二之选。</p></li><li><p>…</p></li></ul><hr><h5 id="最后的最后"><a href="#最后的最后" class="headerlink" title="最后的最后"></a>最后的最后</h5><blockquote><p>最理想的情况是副业在赚钱的同时可以对主业进行属性加成。</p></blockquote><p><img src="/images/%E5%89%AF%E4%B8%9A3.jpg" alt="副业"></p>]]></content>
<summary type="html">
<h1 id="关于程序员的第二职业"><a href="#关于程序员的第二职业" class="headerlink" title="关于程序员的第二职业"></a>关于程序员的第二职业</h1><p>之前扯淡了下程序员的<a href="https://freefuncode.github.io/2019/10/01/%E5%85%B3%E4%BA%8E%E8%81%8C%E4%B8%9A%E7%94%9F%E6%B6%AF%E7%9A%84%E6%83%B3%E6%B3%95/" target="_blank" rel="noopener">关于职业生涯的想法</a>,那个概念有点大,直到最后,我也无法准确的给出我的规划,现在,就扯扯程序员的一些副业吧。</p>
<p><img src="/images/%E5%89%AF%E4%B8%9A1.jpg" alt="副业"></p>
</summary>
<category term="心情" scheme="https://inote.fun/categories/%E5%BF%83%E6%83%85/"/>
<category term="副业" scheme="https://inote.fun/tags/%E5%89%AF%E4%B8%9A/"/>
</entry>
<entry>
<title>Android-kotlin-coroutine协程的概念</title>
<link href="https://inote.fun/2019/10/19/Android-kotlin-coroutine%E5%8D%8F%E7%A8%8B%E7%9A%84%E6%A6%82%E5%BF%B5/"/>
<id>https://inote.fun/2019/10/19/Android-kotlin-coroutine协程的概念/</id>
<published>2019-10-19T08:40:15.000Z</published>
<updated>2019-10-21T13:55:38.812Z</updated>
<content type="html"><![CDATA[<h1 id="Android-kotlin-coroutine协程的概念"><a href="#Android-kotlin-coroutine协程的概念" class="headerlink" title="Android-kotlin-coroutine协程的概念"></a>Android-kotlin-coroutine协程的概念</h1><h4 id="一-进程,线程,协程-概念"><a href="#一-进程,线程,协程-概念" class="headerlink" title="一. 进程,线程,协程 概念"></a>一. 进程,线程,协程 概念</h4><h5 id="进程与线程"><a href="#进程与线程" class="headerlink" title="进程与线程"></a>进程与线程</h5><ul><li><p>进程是资源分配的最小单位,线程是程序执行的最小单位。</p></li><li><p>进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段、堆栈段和数据段,这种操作非常昂贵。而线程是共享进程中的数据的,使用相同的地址空间,因此CPU切换一个线程的花费远比进程要小很多,同时创建一个线程的开销也比进程要小很多。</p><blockquote><p>为了加大一个应用可使用的内存通过多进程来获取多份内存空间<br>通过给四大组件指定android:process属性可以轻易开启多进程</p></blockquote></li><li><p>线程之间的通信更方便,同一进程下的线程共享全局变量、静态变量等数据,而进程之间的通信需要以通信的方式(IPC-跨进程通信)进行。不过如何处理好同步与互斥是编写多线程程序的难点。</p><blockquote><p>跨进程通信方式有:</p><p> 1. 通过Intent(Bundle)附加extras来传递信息</p><p> 2. 通过共享文件来共享数据</p><p> 3. 采用Binder方式来是想跨进程通信</p><p> 4. 采用ContentProvider</p><p> 5. 采用socket</p></blockquote></li><li><p>但是多进程程序更健壮,多线程程序只要有一个线程死掉,整个进程也死掉了,而一个进程死掉并不会对另外一个进程造成影响,因为进程有自己独立的地址空间。</p><blockquote><p>延申到android崩溃同样道理。</p><p>app中大量Web页面的使用容易导致App内存占用巨大,存在内存泄露,崩溃率高等问题,WebView独立进程的使用是解决Android WebView相关问题的一个合理的方案。</p></blockquote></li></ul><p><img src="/images/%E8%BF%9B%E7%A8%8B%E4%B8%8E%E7%BA%BF%E7%A8%8B.jpg" alt="进程与线程"></p><a id="more"></a><h5 id="线程与协程"><a href="#线程与协程" class="headerlink" title="线程与协程"></a>线程与协程</h5><blockquote><p>kotlin协程是一种用户态的轻量级线程。一个进程可以拥有多个线程一样,一个线程也可以拥有多个协程。</p><p>协程不是被操作系统内核所管理,而完全是由程序所控制(也就是在用户态执行)。</p><p>协程的开销远远小于线程的开销。</p></blockquote><p>协程的特点在于是单线程执行,那和多线程比,协程有何优势?换句话说,协程的出现解决了线程的那些痛点。</p><ul><li><strong>极高的执行效率</strong>:因为子程序切换不是线程切换,而是由程序自身控制,因此,没有线程切换的开销,和多线程比,线程数量越多,协程的性能优势就越明显;</li><li><strong>不需要多线程的锁机制</strong>:因为只有一个线程,也不存在同时写变量冲突,在协程中控制共享资源不加锁,只需要判断状态就好了,所以执行效率比多线程高很多。</li></ul><p><img src="/images/%E7%BA%BF%E7%A8%8B%E4%B8%8E%E5%8D%8F%E7%A8%8B.jpg" alt="线程与协程"></p><h5 id="小结:"><a href="#小结:" class="headerlink" title="小结:"></a>小结:</h5><p>进程:拥有自己独立的堆和栈,既不共享堆,也不共享栈,进程由操作系统调度;<br>线程:拥有自己独立的栈和共享的堆,共享堆,不共享栈,标准线程由操作系统调度;<br>协程:拥有自己独立的栈和共享的堆,共享堆,不共享栈,协程由程序员在协程的代码里显示调度。</p><h4 id="二-Kotlin协程基本使用"><a href="#二-Kotlin协程基本使用" class="headerlink" title="二. Kotlin协程基本使用"></a>二. Kotlin协程基本使用</h4><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><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">//----例如:伪代码----</span><br><span class="line">launch(Background) {</span><br><span class="line"> //执行耗时操作</span><br><span class="line"> val bitmap = MediaStore.getBitmap(uri) </span><br><span class="line"> launch(UI) {</span><br><span class="line"> //更新UI</span><br><span class="line"> imageView.setImageBitmap(bitmap)</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h5 id="集成环境"><a href="#集成环境" class="headerlink" title="集成环境"></a>集成环境</h5><ul><li><p>集成kotlin插件</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></pre></td><td class="code"><pre><span class="line">ext.kotlin_version = '1.3.11'</span><br><span class="line">dependencies {</span><br><span class="line"> classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li><li><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></pre></td><td class="code"><pre><span class="line">implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.1.0"</span><br><span class="line">//或使用android</span><br><span class="line">implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.0"</span><br></pre></td></tr></table></figure></li><li><p>experimental启用声明</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></pre></td><td class="code"><pre><span class="line">//在module的build.gradle中声明</span><br><span class="line">kotlin {</span><br><span class="line"> experimental {</span><br><span class="line"> coroutines 'enable'</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li></ul><h5 id="创建"><a href="#创建" class="headerlink" title="创建"></a>创建</h5><ul><li><strong>launch</strong><br>创建协程</li><li><strong>async</strong><br>创建带返回值的协程,返回的是 Deferred 类</li><li><strong>withContext</strong><br>不创建新的协程,在指定协程上运行代码块</li><li><strong>runBlocking</strong><br>不是 GlobalScope 的 API,可以独立使用,区别是 runBlocking 里面的 delay 会阻塞线程,而 launch 创建的不会。<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><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">//launch</span><br><span class="line">launch{</span><br><span class="line"> delay(1000)</span><br><span class="line"> println("launch")</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line">//async 有返回值</span><br><span class="line">async {</span><br><span class="line"> delay(1000)</span><br><span class="line"> println("async")</span><br><span class="line"> //async 才能有return</span><br><span class="line"> return@async ""</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li></ul><h5 id="协程上下文-CoroutineContext"><a href="#协程上下文-CoroutineContext" class="headerlink" title="协程上下文-CoroutineContext"></a>协程上下文-CoroutineContext</h5><ul><li><p><strong>Dispatchers.Default</strong><br>共享后台线程池里的线程</p></li><li><p><strong>Dispatchers.Main</strong><br>Android主线程</p></li><li><p><strong>Dispatchers.IO</strong><br>共享后台线程池里的线程</p></li><li><p><strong>Dispatchers.Unconfined</strong><br>不限制,使用父Coroutine的现场</p></li><li><p><strong>newSingleThreadContext</strong><br>使用新的线程</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><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">/**</span><br><span class="line"> * 上下文</span><br><span class="line"> */</span><br><span class="line">launch { // 运行在父协程的上下文中,即 runBlocking 主协程</span><br><span class="line"> println("main runBlocking : I'm working in thread ${Thread.currentThread().name}")</span><br><span class="line">}</span><br><span class="line">launch(Dispatchers.Default) { // 将会获取默认调度器</span><br><span class="line"> println("Default : I'm working in thread ${Thread.currentThread().name}")</span><br><span class="line">}</span><br><span class="line">launch(Dispatchers.Main) { // Android主线程</span><br><span class="line"> println("Main : I'm working in thread ${Thread.currentThread().name}")</span><br><span class="line">}</span><br><span class="line">launch(Dispatchers.IO) { // 共享后台线程池里的线程</span><br><span class="line"> println("IO : I'm working in thread ${Thread.currentThread().name}")</span><br><span class="line">}</span><br><span class="line">launch(Dispatchers.Unconfined) { // 不受限的——将工作在主线程中</span><br><span class="line"> println("Unconfined : I'm working in thread ${Thread.currentThread().name}")</span><br><span class="line">}</span><br><span class="line">launch(newSingleThreadContext("MyOwnThread")) { // 将使它获得一个新的线程</span><br><span class="line"> println("newSingleThreadContext: I'm working in thread ${Thread.currentThread().name}")</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li></ul><h5 id="协程的挂起和恢复"><a href="#协程的挂起和恢复" class="headerlink" title="协程的挂起和恢复"></a>协程的挂起和恢复</h5><blockquote><p>thread 线程之间采取的是竞争 cpu 时间段的方法,谁抢到谁运行,由系统内核控制,对我们来说是不可见不可控的。协程不同,协程之间不用竞争、谁运行、谁挂起、什么时候恢复都是由我们自己控制的。</p></blockquote><ul><li><p>协程执行时, 协程和协程,协程和线程内代码是顺序运行的。</p></li><li><p>协程挂起时,就不会执行了,而是等待挂起完成且线程空闲时才能继续执行。</p><ul><li>suspend 修饰的方法挂起的是协程本身。</li><li>await,会阻塞外部协程。适用于多个同级 IO 操作的情况。await()可以返回当前协程的执行结果。</li></ul><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><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">runBlocking {</span><br><span class="line"> val deferred1 = async(Dispatchers.Default) {</span><br><span class="line"> println(Thread.currentThread())</span><br><span class="line"> "hello1"</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> async(Dispatchers.Default){</span><br><span class="line"> println(Thread.currentThread())</span><br><span class="line"> println("hello2")</span><br><span class="line"> //await()可以返回当前协程的执行结果: hello1</span><br><span class="line"> println(deferred1.await())</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> }</span><br></pre></td></tr></table></figure></li></ul><hr><p>kotlin汇总介绍: <a href="http://www.kotlincn.net/docs/reference/coroutines/coroutines-guide.html" target="_blank" rel="noopener">kotlin协程指南</a></p><hr><blockquote><p>工作需要,目前正在写一个kotlin社交项目。项目中用到room存储数据,在线程里通过Dao操作本地数据库,根据Dao数据返回到主线程更新UI。这个线程切换,使用协程来操作,代码简洁易读。所以花点时间了解下!</p><p>Kotlin中的协程也是通过线程池来实现的。而在Kotlin中,在线程之上也建立了在线程中类似于Looper+Handler的机制,让协程可以在多个线程中切换,以及进行数据的传递。<br> <a href="https://juejin.im/post/5daa9938e51d4524b95169f6" target="_blank" rel="noopener">Android子线程切换到UI线程方法总结</a></p></blockquote>]]></content>
<summary type="html">
<h1 id="Android-kotlin-coroutine协程的概念"><a href="#Android-kotlin-coroutine协程的概念" class="headerlink" title="Android-kotlin-coroutine协程的概念"></a>Android-kotlin-coroutine协程的概念</h1><h4 id="一-进程,线程,协程-概念"><a href="#一-进程,线程,协程-概念" class="headerlink" title="一. 进程,线程,协程 概念"></a>一. 进程,线程,协程 概念</h4><h5 id="进程与线程"><a href="#进程与线程" class="headerlink" title="进程与线程"></a>进程与线程</h5><ul>
<li><p>进程是资源分配的最小单位,线程是程序执行的最小单位。</p>
</li>
<li><p>进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段、堆栈段和数据段,这种操作非常昂贵。而线程是共享进程中的数据的,使用相同的地址空间,因此CPU切换一个线程的花费远比进程要小很多,同时创建一个线程的开销也比进程要小很多。</p>
<blockquote>
<p>为了加大一个应用可使用的内存通过多进程来获取多份内存空间<br>通过给四大组件指定android:process属性可以轻易开启多进程</p>
</blockquote>
</li>
<li><p>线程之间的通信更方便,同一进程下的线程共享全局变量、静态变量等数据,而进程之间的通信需要以通信的方式(IPC-跨进程通信)进行。不过如何处理好同步与互斥是编写多线程程序的难点。</p>
<blockquote>
<p>跨进程通信方式有:</p>
<p> 1. 通过Intent(Bundle)附加extras来传递信息</p>
<p> 2. 通过共享文件来共享数据</p>
<p> 3. 采用Binder方式来是想跨进程通信</p>
<p> 4. 采用ContentProvider</p>
<p> 5. 采用socket</p>
</blockquote>
</li>
<li><p>但是多进程程序更健壮,多线程程序只要有一个线程死掉,整个进程也死掉了,而一个进程死掉并不会对另外一个进程造成影响,因为进程有自己独立的地址空间。</p>
<blockquote>
<p>延申到android崩溃同样道理。</p>
<p>app中大量Web页面的使用容易导致App内存占用巨大,存在内存泄露,崩溃率高等问题,WebView独立进程的使用是解决Android WebView相关问题的一个合理的方案。</p>
</blockquote>
</li>
</ul>
<p><img src="/images/%E8%BF%9B%E7%A8%8B%E4%B8%8E%E7%BA%BF%E7%A8%8B.jpg" alt="进程与线程"></p>
</summary>
<category term="Android" scheme="https://inote.fun/categories/Android/"/>
<category term="kotlin" scheme="https://inote.fun/categories/Android/kotlin/"/>
<category term="coroutine协程" scheme="https://inote.fun/tags/coroutine%E5%8D%8F%E7%A8%8B/"/>
</entry>
<entry>
<title>Android子线程切换到UI线程方法总结</title>
<link href="https://inote.fun/2019/10/19/Android%E5%AD%90%E7%BA%BF%E7%A8%8B%E5%88%87%E6%8D%A2%E5%88%B0UI%E7%BA%BF%E7%A8%8B%E6%96%B9%E6%B3%95%E6%80%BB%E7%BB%93/"/>
<id>https://inote.fun/2019/10/19/Android子线程切换到UI线程方法总结/</id>
<published>2019-10-19T05:10:59.000Z</published>
<updated>2019-10-21T13:56:00.891Z</updated>
<content type="html"><![CDATA[<h4 id="线程切换"><a href="#线程切换" class="headerlink" title="线程切换"></a>线程切换</h4><blockquote><p>通过消息发送(发布)和接收(订阅)的方式切换的。</p></blockquote><h5 id="1-Handler"><a href="#1-Handler" class="headerlink" title="1 .Handler"></a>1 .Handler</h5><blockquote><p>子线程(非UI线程)调用handler对象sendMessage(msg)方法,将消息发送给关联Looper,Looper将消息存储在MessageQueue消息队列里面。</p><p>然后轮巡取出MessageQueue中的消息给UI线程中handler处理,handler得到消息调用handleMessage方法处理消息,从而可以更新Ui。</p></blockquote><a id="more"></a><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><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"> private Handler handler2=new Handler(){</span><br><span class="line"> @Override</span><br><span class="line"> public void handleMessage(Message msg) {</span><br><span class="line"> switch (msg.what){</span><br><span class="line"> case 1:</span><br><span class="line"> //UI线程</span><br><span class="line"> textView.setText(msg.obj.toString());</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">new Thread(){</span><br><span class="line"> @Override</span><br><span class="line"> public void run() {</span><br><span class="line"> //执行相关耗时操作等等...</span><br><span class="line"> //休眠3s</span><br><span class="line"> sleep(3000);</span><br><span class="line"> Message message = new Message();</span><br><span class="line"> //区分标志</span><br><span class="line"> message.what=1;</span><br><span class="line"> //传参到ui线程</span><br><span class="line"> message.obj=123123;</span><br><span class="line"> handler2.sendMessage(message);</span><br><span class="line"> }</span><br><span class="line"> }.start();</span><br></pre></td></tr></table></figure><p>** 扩展注意:**</p><ul><li>1 . Handler机制与Activity生命周期不一致的原因,容易导致内存泄漏。</li><li>2 . 实例化 handler<figure class="highlight plain"><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">//实例化handler在其他线程的时候要下面这样写(UI线程内部已经实现,无需写)</span><br><span class="line"> private Handler handler = new Handler(Looper.getMainLooper());</span><br></pre></td></tr></table></figure></li></ul><h5 id="2-Activity-runOnUiThread"><a href="#2-Activity-runOnUiThread" class="headerlink" title="2. Activity.runOnUiThread"></a>2. Activity.runOnUiThread</h5><blockquote><p>用Activity对象的runOnUiThread方法更新,在子线程中通过runOnUiThread()方法更新UI </p></blockquote><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><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">new Thread() {</span><br><span class="line"> public void run() {</span><br><span class="line"> while (i++ < 1000) {</span><br><span class="line"> try {</span><br><span class="line"> runOnUiThread(new Runnable() {</span><br><span class="line"> @Override</span><br><span class="line"> public void run() {</span><br><span class="line"> textView.setText("#" + i);</span><br><span class="line"> }</span><br><span class="line"> });</span><br><span class="line"> Thread.sleep(300);</span><br><span class="line"> } catch (InterruptedException e) {</span><br><span class="line"> e.printStackTrace();</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }.start();</span><br></pre></td></tr></table></figure><h5 id="3-View-post-Runnable-r"><a href="#3-View-post-Runnable-r" class="headerlink" title="3. View.post(Runnable r)"></a>3. View.post(Runnable r)</h5><blockquote><p>View.post(Runnableaction),View获得当前线程(即UI线程)的Handler,然后将action对象post到Handler里。</p><p>在Handler里,它将传递过来的action对象包装成一个Message(Message的callback为action),然后将其投入UI线程的消息循环中。</p><p>在Handler再次处理该Message时,直接调用runnable的run方法。而此时,已经路由到UI线程里,因此,我们可以毫无顾虑的来更新UI。</p></blockquote><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><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">new Thread(){</span><br><span class="line"> @Override</span><br><span class="line"> public void run() {</span><br><span class="line"> super.run();</span><br><span class="line"> for (int i=0;i<3;i++){</span><br><span class="line"> try {</span><br><span class="line"> sleep(1000);</span><br><span class="line"> } catch (InterruptedException e) {</span><br><span class="line"> e.printStackTrace();</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> tv.post(new Runnable() {</span><br><span class="line"> @Override</span><br><span class="line"> public void run() {</span><br><span class="line"> tv.setText("通过View.post(Runnable r) 方法");</span><br><span class="line"> }</span><br><span class="line"> });</span><br><span class="line"> }</span><br><span class="line"> }.run();</span><br></pre></td></tr></table></figure><p><strong>扩展注意:</strong></p><p>子线程能不能更新UI,答案是<strong>肯定</strong>的。具体阅读下这篇文章:<a href="https://juejin.im/post/5da14e8ae51d45782b0c1c20" target="_blank" rel="noopener">Android 子线程更新UI?</a></p><p>上面就是为了实现用一个Thread来更新tv,可以实现这个功能,刷新UI界面。但是这样是不对的,因为它违背了单线程模型:Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行。</p><h5 id="4-AsyncTask"><a href="#4-AsyncTask" class="headerlink" title="4. AsyncTask"></a>4. AsyncTask</h5><blockquote><p>内部就是一个Handler和线程池的封装。在线程池中执行后台任务,并在执行过程中将执行进度传递给主线程,当任务执行完毕后,将最终结果传递给主线程。</p></blockquote><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line">private class MyAsyncTask extends AsyncTask{</span><br><span class="line">//第一阶段————准备阶段</span><br><span class="line"> @Override</span><br><span class="line"> protected void onPreExecute() {</span><br><span class="line"> super.onPreExecute();</span><br><span class="line"> } </span><br><span class="line"> //第二阶段————耗时操作</span><br><span class="line"> @Override</span><br><span class="line"> protected Object doInBackground(Object[] objects) {</span><br><span class="line"> for (int i=0;i<3;i++){</span><br><span class="line"> try {</span><br><span class="line"> sleep(1000);</span><br><span class="line"> } catch (InterruptedException e) {</span><br><span class="line"> e.printStackTrace();</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> return objects[0].toString();</span><br><span class="line"> }</span><br><span class="line"> //第三阶段———— 更新UI</span><br><span class="line"> @Override</span><br><span class="line"> protected void onPostExecute(Object o) {</span><br><span class="line"> super.onPostExecute(o);</span><br><span class="line"> tv.setText(o.toString());</span><br><span class="line"> }</span><br><span class="line"> }</span><br></pre></td></tr></table></figure><h5 id="5-Rxjava"><a href="#5-Rxjava" class="headerlink" title="5. Rxjava"></a>5. Rxjava</h5><blockquote><p>RXJAVA的实现,是一种扩展式的观察者模式。</p><p>RXJAVA中有四种概念。observable(被观察者),observer(观察者),subscribe(订阅),事件。</p><p>Observable和Observer通过subscribe来实现订阅关系。</p><p>与传统的观察者模式不同,除了onNext事件外,rxjava还提供了onCompleted和onError。当不再有onNext事件发送时,将以onCompleted事件作为结束。当处理过程中出现异常时,会触发onError,同时队列自动终止,不允许再有事件发出。onCompleted和onError在一个序列中有且只有一个,二者互斥,只能出现一个。</p></blockquote><p>源码来自:<a href="https://www.jianshu.com/p/9d4e39a83a74" target="_blank" rel="noopener">RxJava线程切换代替Thread和Handler</a></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><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"> public static <T> void doTask(final Task<T> task) {</span><br><span class="line"> //创建被观察者 Observable,它决定什么时候触发事件以及触发怎样的事件。</span><br><span class="line"> Observable.create(new Observable.OnSubscribe<T>() {</span><br><span class="line"> @Override</span><br><span class="line"> public void call(Subscriber<? super T> subscriber) {</span><br><span class="line"> // 线程执行耗时操作</span><br><span class="line">// task.doOnIOThread();</span><br><span class="line">// subscriber.onNext(task.getT());</span><br><span class="line"> subscriber.onCompleted();</span><br><span class="line"> }</span><br><span class="line"> })</span><br><span class="line"> .subscribeOn(Schedulers.io())</span><br><span class="line"> .observeOn(AndroidSchedulers.mainThread())</span><br><span class="line"> //订阅</span><br><span class="line"> .subscribe(new Action1<T>() {</span><br><span class="line"> @Override</span><br><span class="line"> public void call(T t) {</span><br><span class="line"> //主线程更新UI</span><br><span class="line">// task.doOnUIThread();</span><br><span class="line"> }</span><br><span class="line"> }, new Action1<Throwable>() {</span><br><span class="line"> @Override</span><br><span class="line"> public void call(Throwable throwable) {</span><br><span class="line"> throwable.printStackTrace();</span><br><span class="line"> }</span><br><span class="line"> });</span><br><span class="line"> }</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h4 id="线程切换"><a href="#线程切换" class="headerlink" title="线程切换"></a>线程切换</h4><blockquote>
<p>通过消息发送(发布)和接收(订阅)的方式切换的。</p>
</blockquote>
<h5 id="1-Handler"><a href="#1-Handler" class="headerlink" title="1 .Handler"></a>1 .Handler</h5><blockquote>
<p>子线程(非UI线程)调用handler对象sendMessage(msg)方法,将消息发送给关联Looper,Looper将消息存储在MessageQueue消息队列里面。</p>
<p>然后轮巡取出MessageQueue中的消息给UI线程中handler处理,handler得到消息调用handleMessage方法处理消息,从而可以更新Ui。</p>
</blockquote>
</summary>
<category term="Android" scheme="https://inote.fun/categories/Android/"/>
<category term="知识点" scheme="https://inote.fun/categories/Android/%E7%9F%A5%E8%AF%86%E7%82%B9/"/>
<category term="线程切换" scheme="https://inote.fun/tags/%E7%BA%BF%E7%A8%8B%E5%88%87%E6%8D%A2/"/>
</entry>
<entry>
<title>谈谈逛博客的小习惯</title>
<link href="https://inote.fun/2019/10/13/%E8%B0%88%E8%B0%88%E9%80%9B%E5%8D%9A%E5%AE%A2%E7%9A%84%E5%B0%8F%E4%B9%A0%E6%83%AF/"/>
<id>https://inote.fun/2019/10/13/谈谈逛博客的小习惯/</id>
<published>2019-10-13T10:43:22.000Z</published>
<updated>2019-10-21T13:56:07.842Z</updated>
<content type="html"><![CDATA[<p><img src="/images/guangboke.jpg" alt="逛博客"></p><h4 id="一-事情经过"><a href="#一-事情经过" class="headerlink" title="一. 事情经过"></a>一. 事情经过</h4><p>国庆节后的一周,上了六天班了,明天有继续新的一周,也就是节后要连续上两周班,确实还有点疲惫。<br>下班回到家,虽然很累,打开电脑,不自然的就打开了各大博客网站:掘金,博客园,csdn,简书。阅读下最近一周的博文。<br>看了一会,就意识到一个有意思的问题:打开电脑前,是准备看看腾讯视频有没有更新新的电影;但是电脑启动后,坐下来,我竟然无意识的就打开了各个博客网站,我都这么疲惫了,真的是无意识的动作。<br>突然意识到,我竟然有了一个这么小习惯,每周都要腾一点时间出来看看最近几天博客上发生的事,给自己的知识库,吸取补充下养分。<br>再深思下,从啥时候开始了这样的习惯?应该是最近两三年吧。<br>为什么能持续?反思下,阅读开阔我的眼界,追逐技术的更迭。也许阅读博客给我安全感,避免让自己被淘汰吧。</p><blockquote><p>我们的眼睛就是我们的监狱,我们的眼光所到处就是我们监狱的围墙 —尼采</p></blockquote><a id="more"></a><h4 id="二-一般看什么?"><a href="#二-一般看什么?" class="headerlink" title="二. 一般看什么?"></a>二. 一般看什么?</h4><blockquote><p>博客园,csdn,简书,掘金,其他等等…</p></blockquote><h5 id="博客园"><a href="#博客园" class="headerlink" title="博客园"></a>博客园</h5><p>首先,我会看下博客园。这个网站是我很久就关注了,那时候,刚毕业一两年,也是同事推荐,毕竟那时候是做.net方面工作,而博客园是.net开发人员最多的地方。初期,也不知道写什么东西,就捣鼓了一些界面换肤的功能,喜欢很炫的页面效果,现在心态平稳了,反而喜欢简约点。文章的话,感觉自己写不出新东西,也见过网上很多文章层次不齐,大同小异,抄别人的吧,感觉挂不住脸。总之,文章产出量不多。<br>现在看博客园,.net文章偶尔也会看,也就仅仅是看而已了。重点可能是大龄程序员的一些趣事和it方面新闻为主了。可以说是为了情怀而看的吧。因为在博客园大龄码农比较多吧,曾今我也是.net阵营里的一员呢。</p><h5 id="csdn"><a href="#csdn" class="headerlink" title="csdn"></a>csdn</h5><p>csdn,是唯一一个我没有在上面写过正儿八经文章的网站了,如果追述接触时间,应该要比博客园时间长,因为我毕业找毕业设计的时候搜过。曾今还冲过csdn会员,记得那会是50元半年吧,主要是下一些资料或者源码。曾今我也把自己的毕业设计源码和一些小案例上传以获取一些积分。现在有了github,基本好几年没有从csdn下过东西了。<br>在csdn应该也是看一些新闻为主了,给我的感觉是,工作头两年的用户比较多吧,如果偶尔有几篇好文,应该也是作者各大网站群发,在掘金应该也能看到。</p><h5 id="简书"><a href="#简书" class="headerlink" title="简书"></a>简书</h5><p>简书应该是上网找资料,突然发现好几次都跳到简书,慢慢让我感兴趣起来了。曾经安卓端系列好文出的比较多,因为简书有一个很显眼的专题功能,所以许多作者,会把博客划分系列,收录到专题。给人系统性去学习某一专题,这点很不错。<br>但是节前简书估计是被ZF请“喝茶了”,节前长达一个月无法发表文章,节后一段时间,很多搜索引擎收录的文章跳转无法访问,让人很恼火。慢慢,简书,在我心里位置下降了不少,现在主要还是搜索系列文章,系统的看专题。</p><h5 id="掘金"><a href="#掘金" class="headerlink" title="掘金"></a>掘金</h5><p>掘金给我的感觉是一个逼格很高的网站,接触也是在今年。掘金里安卓方面好文章比其他网站要多,上面也有很多大厂员工,也有很多移动端牛人。<br>真正深入,花时间最多的应该是在掘金了。遇到一篇好文章可能会花不少时间,然后遇到一些不熟悉的领域就去搜索,可能搜索就搜索到了简书的专题系列。哈哈哈。</p><h4 id="三-持续学习"><a href="#三-持续学习" class="headerlink" title="三. 持续学习"></a>三. 持续学习</h4><blockquote><p>stay hungry stay foolish –Steve Jobs</p></blockquote><p>阅读是一个好习惯,让人充实自己。也希望这个习惯一直保留下去。后面会更大的扩宽自己知识面。提升自己的软硬实力,提升自己的综合实力。</p><p>30岁,是一个开始。当自己茫然的时候,那就阅读充实自己吧。</p>]]></content>
<summary type="html">
<p><img src="/images/guangboke.jpg" alt="逛博客"></p>
<h4 id="一-事情经过"><a href="#一-事情经过" class="headerlink" title="一. 事情经过"></a>一. 事情经过</h4><p>国庆节后的一周,上了六天班了,明天有继续新的一周,也就是节后要连续上两周班,确实还有点疲惫。<br>下班回到家,虽然很累,打开电脑,不自然的就打开了各大博客网站:掘金,博客园,csdn,简书。阅读下最近一周的博文。<br>看了一会,就意识到一个有意思的问题:打开电脑前,是准备看看腾讯视频有没有更新新的电影;但是电脑启动后,坐下来,我竟然无意识的就打开了各个博客网站,我都这么疲惫了,真的是无意识的动作。<br>突然意识到,我竟然有了一个这么小习惯,每周都要腾一点时间出来看看最近几天博客上发生的事,给自己的知识库,吸取补充下养分。<br>再深思下,从啥时候开始了这样的习惯?应该是最近两三年吧。<br>为什么能持续?反思下,阅读开阔我的眼界,追逐技术的更迭。也许阅读博客给我安全感,避免让自己被淘汰吧。</p>
<blockquote>
<p>我们的眼睛就是我们的监狱,我们的眼光所到处就是我们监狱的围墙 —尼采</p>
</blockquote>
</summary>
<category term="心情" scheme="https://inote.fun/categories/%E5%BF%83%E6%83%85/"/>
<category term="习惯" scheme="https://inote.fun/tags/%E4%B9%A0%E6%83%AF/"/>
</entry>
<entry>
<title>bsdiff&bspatch增量更新概念介绍</title>
<link href="https://inote.fun/2019/10/07/bsdiff%E5%92%8Cbspatch%E5%A2%9E%E9%87%8F%E6%9B%B4%E6%96%B0%E6%A6%82%E5%BF%B5%E4%BB%8B%E7%BB%8D/"/>
<id>https://inote.fun/2019/10/07/bsdiff和bspatch增量更新概念介绍/</id>
<published>2019-10-07T02:22:16.000Z</published>
<updated>2019-10-21T13:56:13.700Z</updated>
<content type="html"><![CDATA[<blockquote><p>随着Android生态,技术越来越成熟,目前市场很多Android的项目工程很大,团队人数多,慢慢衍生出了许多组件化插件化技术。<br>同时也因为Android安装包apk也在逐渐增大,每次发布,用户更新apk环境复杂,如果全量更新下载apk的话在使用流量情况下,网络环境不好等等,对于用户体验是非常不好的。</p></blockquote><h4 id="首先区分下几个概念"><a href="#首先区分下几个概念" class="headerlink" title="首先区分下几个概念"></a>首先区分下几个概念</h4><p><strong>组件化</strong> : 把常用的模块代码,抽取lib工程或者jar达到复用的效果。<br><strong>插件化</strong>:目的是把需要实现的模块或功能当做一个独立的提取出来,减少宿主的规模,当需要使用到相应的功能时再去加载相应的模块。涉及动态代理,ClassLoader,以及另一个apk资源的加载。例如:360的DroidPlugin (推荐)<br><strong>热修复</strong>:往往是从修复bug的角度出发,强调的是在不需要二次安装应用的前提下修复已知的bug(涉及关键词:Hook技术、动态代理等)。例如:阿里 AndFix。<br><strong>增量更新</strong>:APK增量更新是很多大厂APP采用的技术。bsdiff库生成补丁文件方式下载跟旧版本APK合成生成新版APK的原理(ligbspatch.so)。手机游戏app增量更新使用较多。例如:<a href="https://github.com/cundong/SmartAppUpdates" target="_blank" rel="noopener">SmartAppUpdates</a></p><a id="more"></a><hr><p><img src="/images/bsdiff&bspatch.jpg" alt="bsdiff&bspatch"></p><p><strong>bsdiff生成patch -> bzip2压缩 -> android下载patch -> bzip2解压patch -> bspatch合并patch -> 新的apk</strong></p><blockquote><p>bsdiff并不是专门为apk增量更新设计的,它可以对任何二进制文件进行差分和合并。bzip2的功能是利用哈夫曼编码对文件进行无损压缩(将差分包进行压缩便于网络传输)和解压。</p></blockquote><p>流程:</p><ul><li>在服务器端,生成两个版本apk的差分包;</li><li>在手机客户端,使用已安装的apk与这个差分包进行合成,得到新版的apk;</li><li>校验新合成的apk文件是否完整,MD5或SHA1是否正确,如正确,则引导用户安装;</li></ul><hr><h4 id="常用命令"><a href="#常用命令" class="headerlink" title="常用命令"></a>常用命令</h4><p>bsdiff 生成patch包 命令:<code>bsdiff oldfile newfile patchfile</code> 例如: <code>bsdiff xx_v1.0.apk xx_v2.0.apk xx.patch</code></p><p>bspatch生成新的APK: 命令: <code>bspatch oldfile newfile patchfile</code> 例如: <code>bsdiff xx_v1.0.apk xx_v2.0.apk xx.patch</code></p><h4 id="使用"><a href="#使用" class="headerlink" title="使用"></a>使用</h4><p><a href="https://blog.csdn.net/u012484172/article/details/54932717" target="_blank" rel="noopener">Android增量更新——bsdiff&bspatch</a></p><h4 id="缺点:"><a href="#缺点:" class="headerlink" title="缺点:"></a>缺点:</h4><p>增量升级并非完美无缺的升级方式,至少存在以下两点不足:</p><ul><li><p>增量升级是以两个应用版本之间的差异来生成补丁的,你无法保证用户每次的及时升级到最新,所以你必须对你所发布的每一个版本都和最新的版本作差分,以便使所有版本的用户都可以差分升级,这样操作相对于原来的整包升级较为繁琐,不过可以通过自动化的脚本批量生成。</p></li><li><p>增量升级成功的前提是,用户手机端必须有能够让你拷贝出来且与你服务器用于差分的版本一致的apk,这样就存在,例如,系统内置的apk无法获取到,无法进行增量升级;对于某些与你差分版本一致,但是内容有过修改的(比如破解版apk),这样也是无法进行增量升级的,为了防止合成补丁错误,最好通过md5 或者其他方式对patch包进行完整性的校验。</p></li></ul>]]></content>
<summary type="html">
<blockquote>
<p>随着Android生态,技术越来越成熟,目前市场很多Android的项目工程很大,团队人数多,慢慢衍生出了许多组件化插件化技术。<br>同时也因为Android安装包apk也在逐渐增大,每次发布,用户更新apk环境复杂,如果全量更新下载apk的话在使用流量情况下,网络环境不好等等,对于用户体验是非常不好的。</p>
</blockquote>
<h4 id="首先区分下几个概念"><a href="#首先区分下几个概念" class="headerlink" title="首先区分下几个概念"></a>首先区分下几个概念</h4><p><strong>组件化</strong> : 把常用的模块代码,抽取lib工程或者jar达到复用的效果。<br><strong>插件化</strong>:目的是把需要实现的模块或功能当做一个独立的提取出来,减少宿主的规模,当需要使用到相应的功能时再去加载相应的模块。涉及动态代理,ClassLoader,以及另一个apk资源的加载。例如:360的DroidPlugin (推荐)<br><strong>热修复</strong>:往往是从修复bug的角度出发,强调的是在不需要二次安装应用的前提下修复已知的bug(涉及关键词:Hook技术、动态代理等)。例如:阿里 AndFix。<br><strong>增量更新</strong>:APK增量更新是很多大厂APP采用的技术。bsdiff库生成补丁文件方式下载跟旧版本APK合成生成新版APK的原理(ligbspatch.so)。手机游戏app增量更新使用较多。例如:<a href="https://github.com/cundong/SmartAppUpdates" target="_blank" rel="noopener">SmartAppUpdates</a></p>
</summary>
<category term="Android" scheme="https://inote.fun/categories/Android/"/>
<category term="知识点" scheme="https://inote.fun/categories/Android/%E7%9F%A5%E8%AF%86%E7%82%B9/"/>
<category term="增量更新" scheme="https://inote.fun/tags/%E5%A2%9E%E9%87%8F%E6%9B%B4%E6%96%B0/"/>
</entry>
<entry>
<title>《蛮荒故事》电影观后感</title>
<link href="https://inote.fun/2019/10/04/post%E3%80%8A%E8%9B%AE%E8%8D%92%E6%95%85%E4%BA%8B%E3%80%8B%E7%94%B5%E5%BD%B1%E8%A7%82%E5%90%8E%E6%84%9F/"/>
<id>https://inote.fun/2019/10/04/post《蛮荒故事》电影观后感/</id>
<published>2019-10-04T01:37:22.000Z</published>
<updated>2019-10-21T13:56:39.224Z</updated>
<content type="html"><![CDATA[<p><img src="/images/%E8%9B%AE%E8%8D%92%E6%95%85%E4%BA%8B.jpg" alt="蛮荒故事"></p><blockquote><p>这个电影由六个毫无关系的小故事构成,每个故事都不长但高潮迭起,看了让人欲罢不能,情节都充斥着复仇成功的快感,看的时候就觉得有些类似于贾樟柯的天注定,但贾樟柯更妙在每个独立故事中的主角之间有着千丝万缕的联系,而蛮荒故事则像六个独立的小剧集拼凑而成。</p></blockquote><blockquote><p>第一个故事是特别短,发生在一架航班上,一个中年男人和一个模特搭话,接着有人听到他们谈论的一个人,最后发现整架飞机里的乘客都认识最开始谈论的那个人,因为飞机里的每个乘客都或多或少伤害过他,后来他们才得知这架飞机的机长就是他们都伤害过的那个人,最后飞机冲向一对在花园里的夫妇,不用说,应该就是那个人的父母,因为他们从小就给他巨大的精神压力。</p></blockquote><blockquote><p>第二个故事发生在一个饭店里,女主发现夜里新来的客人是自己的仇人,他放高利贷最后逼女主的爸爸自杀,后来又诱奸了女主的母亲,不得已女主的妈妈带着女主逃到了现在生活的城市。女主把这个消息告诉了店里另一个女服务员,性格泼辣剽悍,她建议女主给仇人的饭里下老鼠药,但女主犹犹豫豫最后没有这么做。但那个女服务员自作主张在仇人的饭里下了药,但后来仇人的儿子也来吃饭,女主不想因此弄死两个人,故意惹怒了仇人让他停止吃饭,但仇人反过来开始欺凌女主,那个女服务员情急之下用刀捅死了仇人。</p></blockquote><blockquote><p>第三个故事想一个公路片,男主因为前面一辆破旧的车挡着路自己难以超车,就骂了那个车主,但走到半路车胎突然漏气,他不得已把车停到一座桥边开始换轮胎。后来那个车主赶上来,吓得男主赶紧跑到车里。那个司机一看就是瞟形大汉,浑身充满了野气,看到男主把车停到路边,就开始复仇,先用千斤顶砸车玻璃,后来当着男主的面在车上拉屎撒尿。男主气不过,正巧那个司机把车停在他的车前,就用自己的车把那辆车顶到河里。后来发现那个司机没有死,准备上来复仇,就赶紧开车溜之大吉。但想想还是觉得自己受到巨大的侮辱,男主就又掉头想撞死那个司机,那个司机赶紧躲开,后来男主的车几轮漂移,但因为车轮本身还没有加固,最后车轮脱落,整个车失去控制也翻到河里。男主和瞟形大汉就在河里几番挣扎想要互相弄死对方,最后车爆炸把两个人都烧死了。</p></blockquote><blockquote><p>第四个关于反抗政府腐败的故事,因为一些政府官员为了敛财,随意把停在路边的车拖走,借口是违章停车,必须交高额的赎金。男主几次找政府部门理论都没有结果,还因此弄得妻离子散,最后也丢了工作。男主本身是建筑设计师,平时会有工作要求把一些旧楼给炸掉,于是男主在自己的车里放了易炸品,一次拖车部分又来把男主的车拖走,等到被拖车辆的集中地,男主的车爆炸,造成重大损失,男主被因此关进监狱。但很多普通人视男主为英雄,敢于反抗政府,并要求政府释放男主,声称是因为拖车才导致车辆爆炸。最后男主的妻子和女儿也回到他身边。</p></blockquote><blockquote><p>第五个故事是在影射司法不公。一个富二代开车撞死一个孕妇后逃逸,后来他的父亲请律师想法设法帮他逃脱法律的制裁,最后决定请家中的园丁顶替他的罪名,并决定给园丁50万美金。但后来检察官来检查车查询证据时,发现园丁并不符合犯罪者的特征。后来律师想用钱贿赂律师并告诉富二代的父亲说得拿100万美金才能摆平,但后来律师,检察官还有园丁都想再在这一家人身上多捞点油水,富二代的父亲忍无可忍,决定放弃合作,让富二代自己去自首。最后经过几轮协商达成一致后,在警察带园丁去警局时,潜伏在声讨人群中孕妇的丈夫用酒瓶砸死了园丁。</p></blockquote><blockquote><p>第六个故事特别荒诞。新娘在婚礼上发现丈夫和他的女同事有染,在婚礼进行中先是和饭店的服务员发生关系,后来又故意把新郎的女同事弄受伤,在婚礼上疯疯癫癫,把整个仪式弄得一团糟。新郎和他的家人也都要精神崩溃。但后来这对新人发现最后的结果是两败俱伤,男主主动邀请女主跳舞,后来两个人开始激吻,让在场所有的人瞠目结舌,因为他们都觉得这对儿新人不可能再在一起了。但在一片混乱中,这对新人开始在放着他们新婚蛋糕的桌子上做爱,电影就在这样荒诞的喜剧中收场。</p></blockquote><ul><li>每个复仇故事的都体现了人性中野蛮的一面,谋杀,隐藏,放纵,每个故事都把人性的阴暗面血淋淋的放到台面上,让观众忘却所谓的文明,忘却束缚人性所谓的道德。爱就是爱,恨就是恨,受伤害了就要复仇,不管什么伦理仁慈,把人性的蛮荒充分展现出来。本该就没有什么所谓的圣人,人大部分时候都是压抑着活着,除非被逼的迫不得已,人性的蛮荒只是被秘密的隐藏,但不不代表它就不存在。等蛮荒占了上风,那种释放,会似火山爆发一般蔓延。</li></ul><a id="more"></a><hr><ul><li>精彩翻转,一波三折,细思又只是意料之内,因为电影拍的其实生活本来的样子,始于荒谬,止于更荒谬,是真实残酷的白描,与我们也能产生很多共鸣。因为每个人都有过一闪而过的犯罪念头,但大多困于法律、困与人自身的道德良知选择不作为,这部片子就把我们没敢做出来的那部分呈现了出来,狠狠戳中我们的软肋。这个世界总是如此厌倦又可笑。</li></ul><hr><ul><li>人不管在多优越的环境下成长受了多么良好的教育,本质里的兽性是不会被抹灭的,它只是蛰伏着,如同一座长年植被覆盖的活火山,随时有爆发的可能。人作为高级动物,生来是自带蛮力的,这在孩童时期得到充分体现,可以动不动为了争夺而肉搏,你打了我一下我就必须还以颜色才能体现公平,儿时的人类划分等级,依靠本能的身体素质,这是确保自己不吃亏的最直观指标,无法随着时代的进步而改变,我们口中形容孩子的“幼稚”,无知的那部分随着成长得到填充,暴力的那部分始终潜伏在基因深处脉动着。成人,作为社会的一员,在文明的世界里被无数的框架限制,隐忍的弹性不断增强,人人都习惯了身不由己,看人眼色,遵从规则行事。</li></ul><hr><ul><li>将生活中的矛盾冲突无限放大,把人性的阴暗暴露得彻彻底底,从航班到公路到婚礼,在极致的绝境下,不同主题的复仇行动都压抑又快意。每一个故事都很荒诞,每一个故事又都很真实。</li></ul><hr><ul><li>这个几个故事,直接而露骨地揭露人性中的另一面。一方面,你会说故事中的人物太过激动,一方面,你看见他们为了报复所作所为,又多少可以理解和畅快,这就是人性的复杂,它不仅仅只有善,有时候压抑怒火的伪善,撕开那层皮囊就成为了恶。不同的报复,结果也不同,有死亡,有和解,有引起公众的同情,也看见社会的不公。</li></ul>]]></content>
<summary type="html">
<p><img src="/images/%E8%9B%AE%E8%8D%92%E6%95%85%E4%BA%8B.jpg" alt="蛮荒故事"></p>
<blockquote>
<p>这个电影由六个毫无关系的小故事构成,每个故事都不长但高潮迭起,看了让人欲罢不能,情节都充斥着复仇成功的快感,看的时候就觉得有些类似于贾樟柯的天注定,但贾樟柯更妙在每个独立故事中的主角之间有着千丝万缕的联系,而蛮荒故事则像六个独立的小剧集拼凑而成。</p>
</blockquote>
<blockquote>
<p>第一个故事是特别短,发生在一架航班上,一个中年男人和一个模特搭话,接着有人听到他们谈论的一个人,最后发现整架飞机里的乘客都认识最开始谈论的那个人,因为飞机里的每个乘客都或多或少伤害过他,后来他们才得知这架飞机的机长就是他们都伤害过的那个人,最后飞机冲向一对在花园里的夫妇,不用说,应该就是那个人的父母,因为他们从小就给他巨大的精神压力。</p>
</blockquote>
<blockquote>
<p>第二个故事发生在一个饭店里,女主发现夜里新来的客人是自己的仇人,他放高利贷最后逼女主的爸爸自杀,后来又诱奸了女主的母亲,不得已女主的妈妈带着女主逃到了现在生活的城市。女主把这个消息告诉了店里另一个女服务员,性格泼辣剽悍,她建议女主给仇人的饭里下老鼠药,但女主犹犹豫豫最后没有这么做。但那个女服务员自作主张在仇人的饭里下了药,但后来仇人的儿子也来吃饭,女主不想因此弄死两个人,故意惹怒了仇人让他停止吃饭,但仇人反过来开始欺凌女主,那个女服务员情急之下用刀捅死了仇人。</p>
</blockquote>
<blockquote>
<p>第三个故事想一个公路片,男主因为前面一辆破旧的车挡着路自己难以超车,就骂了那个车主,但走到半路车胎突然漏气,他不得已把车停到一座桥边开始换轮胎。后来那个车主赶上来,吓得男主赶紧跑到车里。那个司机一看就是瞟形大汉,浑身充满了野气,看到男主把车停到路边,就开始复仇,先用千斤顶砸车玻璃,后来当着男主的面在车上拉屎撒尿。男主气不过,正巧那个司机把车停在他的车前,就用自己的车把那辆车顶到河里。后来发现那个司机没有死,准备上来复仇,就赶紧开车溜之大吉。但想想还是觉得自己受到巨大的侮辱,男主就又掉头想撞死那个司机,那个司机赶紧躲开,后来男主的车几轮漂移,但因为车轮本身还没有加固,最后车轮脱落,整个车失去控制也翻到河里。男主和瞟形大汉就在河里几番挣扎想要互相弄死对方,最后车爆炸把两个人都烧死了。</p>
</blockquote>
<blockquote>
<p>第四个关于反抗政府腐败的故事,因为一些政府官员为了敛财,随意把停在路边的车拖走,借口是违章停车,必须交高额的赎金。男主几次找政府部门理论都没有结果,还因此弄得妻离子散,最后也丢了工作。男主本身是建筑设计师,平时会有工作要求把一些旧楼给炸掉,于是男主在自己的车里放了易炸品,一次拖车部分又来把男主的车拖走,等到被拖车辆的集中地,男主的车爆炸,造成重大损失,男主被因此关进监狱。但很多普通人视男主为英雄,敢于反抗政府,并要求政府释放男主,声称是因为拖车才导致车辆爆炸。最后男主的妻子和女儿也回到他身边。</p>
</blockquote>
<blockquote>
<p>第五个故事是在影射司法不公。一个富二代开车撞死一个孕妇后逃逸,后来他的父亲请律师想法设法帮他逃脱法律的制裁,最后决定请家中的园丁顶替他的罪名,并决定给园丁50万美金。但后来检察官来检查车查询证据时,发现园丁并不符合犯罪者的特征。后来律师想用钱贿赂律师并告诉富二代的父亲说得拿100万美金才能摆平,但后来律师,检察官还有园丁都想再在这一家人身上多捞点油水,富二代的父亲忍无可忍,决定放弃合作,让富二代自己去自首。最后经过几轮协商达成一致后,在警察带园丁去警局时,潜伏在声讨人群中孕妇的丈夫用酒瓶砸死了园丁。</p>
</blockquote>
<blockquote>
<p>第六个故事特别荒诞。新娘在婚礼上发现丈夫和他的女同事有染,在婚礼进行中先是和饭店的服务员发生关系,后来又故意把新郎的女同事弄受伤,在婚礼上疯疯癫癫,把整个仪式弄得一团糟。新郎和他的家人也都要精神崩溃。但后来这对新人发现最后的结果是两败俱伤,男主主动邀请女主跳舞,后来两个人开始激吻,让在场所有的人瞠目结舌,因为他们都觉得这对儿新人不可能再在一起了。但在一片混乱中,这对新人开始在放着他们新婚蛋糕的桌子上做爱,电影就在这样荒诞的喜剧中收场。</p>
</blockquote>
<ul>
<li>每个复仇故事的都体现了人性中野蛮的一面,谋杀,隐藏,放纵,每个故事都把人性的阴暗面血淋淋的放到台面上,让观众忘却所谓的文明,忘却束缚人性所谓的道德。爱就是爱,恨就是恨,受伤害了就要复仇,不管什么伦理仁慈,把人性的蛮荒充分展现出来。本该就没有什么所谓的圣人,人大部分时候都是压抑着活着,除非被逼的迫不得已,人性的蛮荒只是被秘密的隐藏,但不不代表它就不存在。等蛮荒占了上风,那种释放,会似火山爆发一般蔓延。</li>
</ul>
</summary>
<category term="心情" scheme="https://inote.fun/categories/%E5%BF%83%E6%83%85/"/>
<category term="电影" scheme="https://inote.fun/tags/%E7%94%B5%E5%BD%B1/"/>
</entry>
<entry>
<title>Android View绘制流程</title>
<link href="https://inote.fun/2019/10/03/AndroidView%E7%BB%98%E5%88%B6%E6%B5%81%E7%A8%8B/"/>
<id>https://inote.fun/2019/10/03/AndroidView绘制流程/</id>
<published>2019-10-03T04:18:40.000Z</published>
<updated>2019-10-21T13:56:21.869Z</updated>
<content type="html"><![CDATA[<h1 id="Android-View绘制流程"><a href="#Android-View绘制流程" class="headerlink" title="Android View绘制流程"></a>Android View绘制流程</h1><blockquote><p>Android绘制经历了三个步骤:</p><ul><li>1.Measure 测量View大小</li><li>2.layout 计算摆放位置</li><li>3.draw 画View</li></ul></blockquote><a id="more"></a>]]></content>
<summary type="html">
<h1 id="Android-View绘制流程"><a href="#Android-View绘制流程" class="headerlink" title="Android View绘制流程"></a>Android View绘制流程</h1><blockquote>
<p>Android绘制经历了三个步骤:</p>
<ul>
<li>1.Measure 测量View大小</li>
<li>2.layout 计算摆放位置</li>
<li>3.draw 画View</li>
</ul>
</blockquote>
</summary>
<category term="Android" scheme="https://inote.fun/categories/Android/"/>
<category term="知识点" scheme="https://inote.fun/categories/Android/%E7%9F%A5%E8%AF%86%E7%82%B9/"/>
<category term="view绘制" scheme="https://inote.fun/tags/view%E7%BB%98%E5%88%B6/"/>
</entry>
<entry>
<title>Android屏幕适配</title>
<link href="https://inote.fun/2019/10/03/Android%E5%B1%8F%E5%B9%95%E9%80%82%E9%85%8D/"/>
<id>https://inote.fun/2019/10/03/Android屏幕适配/</id>
<published>2019-10-03T01:07:38.000Z</published>
<updated>2019-10-21T13:56:30.304Z</updated>
<content type="html"><![CDATA[<h1 id="Android屏幕适配方案"><a href="#Android屏幕适配方案" class="headerlink" title="Android屏幕适配方案"></a>Android屏幕适配方案</h1><blockquote><p>先讲述一些屏幕适配相关概念,然后介绍下3种主要的适配方案以及优缺点。</p></blockquote><h3 id="一-基本概念"><a href="#一-基本概念" class="headerlink" title="一.基本概念"></a>一.基本概念</h3><h4 id="1-像素(px)"><a href="#1-像素(px)" class="headerlink" title="1. 像素(px)"></a>1. 像素(px)</h4><ul><li>像素是手机屏幕的最小构成单元。<h4 id="2-分辨率-(px)"><a href="#2-分辨率-(px)" class="headerlink" title="2. 分辨率 (px)"></a>2. 分辨率 (px)</h4></li><li>手机在横向、纵向上的像素点数总和,一般描述成 宽高 ,即横向像素点个数纵向像素点个数。</li><li>例如:1080x1920,即宽度方向上有1080个像素点,在高度方向上有1920个像素点。<h4 id="3-屏幕尺寸(inch)"><a href="#3-屏幕尺寸(inch)" class="headerlink" title="3.屏幕尺寸(inch)"></a>3.屏幕尺寸(inch)</h4></li><li>手机对角线的物理尺寸,单位 英寸(inch),一英寸大约2.54cm,</li><li>例如:常见的尺寸有4.7寸、5寸、5.5寸、6寸<h4 id="4-屏幕像素密度-dpi"><a href="#4-屏幕像素密度-dpi" class="headerlink" title="4.屏幕像素密度 (dpi)"></a>4.屏幕像素密度 (dpi)</h4></li><li>每英寸长度上像素点个数。”dot per inch”:</li><li>例如每英寸内有160个像素点,则其像素密度为160dpi。<h5 id="以上四者之间关系"><a href="#以上四者之间关系" class="headerlink" title="以上四者之间关系"></a>以上四者之间关系</h5></li><li>$ √((宽px)²+(高px)²) / (屏幕尺寸inch) = (屏幕像素密度dpi) $ <h4 id="5-dp,dip,sp"><a href="#5-dp,dip,sp" class="headerlink" title="5. dp,dip,sp"></a>5. dp,dip,sp</h4></li><li>dip和dp是一个意思,都是Density Independent Pixels的缩写,即密度无关像素。</li><li>例如:在Android中,规定以160dpi为基准,1dip=1px,如果密度是320dpi,则1dip=2px,以此类推。</li><li>android中的dp在渲染前会将dp转为px,计算公式:<br>$px = density * dp;$<br>$density = dpi / 160;$<br>$px = dp * (dpi / 160);$</li><li>注意:dp与px不一定都是2倍的关系,与屏幕像素密度dpi有关。<h4 id="6-hdpi,mdpi,xhdpi,xxhdpi,xxxhdpi"><a href="#6-hdpi,mdpi,xhdpi,xxhdpi,xxxhdpi" class="headerlink" title="6. hdpi,mdpi,xhdpi,xxhdpi,xxxhdpi"></a>6. hdpi,mdpi,xhdpi,xxhdpi,xxxhdpi</h4></li><li>用来修饰Android中的drawable文件夹及values文件夹,用来区分不同像素密度下的图片和dimen值。</li><li>在设计图标时,对于五种主流的像素密度(mdpi、hdpi、xhdpi、xxhdpi 和 xxxhdpi)应按照 2:3:4:6:8 的比例进行缩放。</li></ul><a id="more"></a><hr><h3 id="2-适配方案"><a href="#2-适配方案" class="headerlink" title="2.适配方案"></a>2.适配方案</h3><blockquote><p>主要介绍一些适配方案,至于布局编码注意的问题,不详细介绍了。</p><ul><li>使用 “wrap_content” 和 “match_parent” 尺寸值而不是硬编码的尺寸,视图就会相应地仅使用自身所需的空间或展开以填满可用空间。</li><li>weight是线性布局的一个独特的属性,我们可以使用这个属性来按照比例对界面进行分配。</li><li>使用相对布局,禁用绝对布局。等等…</li></ul><p>适配目的是使得某一元素在Android不同尺寸、不同分辨率的手机上具备相同的显示效果。</p></blockquote><h4 id="1-屏幕分辨率限定符(宽高限定符)"><a href="#1-屏幕分辨率限定符(宽高限定符)" class="headerlink" title="1.屏幕分辨率限定符(宽高限定符)"></a>1.屏幕分辨率限定符(宽高限定符)</h4><blockquote><p>设定一个基准的分辨率,也就是设计图对应的分辨率,其他分辨率都根据这个基准分辨率来计算,在不同的尺寸文件夹内部,根据该尺寸编写对应的dimens文件。</p></blockquote><ul><li>屏幕分辨率限定符适配需要在 res 文件夹下创建各种屏幕分辨率对应的 values-xxx 文件夹。</li><li>然后根据一个基准分辨率,例如基准分辨率为 1280x720,将宽度分成 720 份,取值为 1px~720px,将高度分成 1280 份,取值为1px—1280px,生成各种分辨率对应的 dimens.xml 文件。<blockquote><p>基准分辨率 1280x720 对应的dimes文件:</p><ul><li>宽度为720,将任何分辨率的宽度整分为720份,取值为x1-x720</li><li>高度为1280,将任何分辨率的高度整分为1280份,取值为y1-y1280</li></ul><p>那么对于1080*1920的分辨率的dimens文件来说,宽度如下:</p><ul><li>x1=(1080/720)*1=1.5px </li><li>x2=(1080/720)*2=3px<br>…</li><li>x719=(1080/720)*719=1078.5px</li><li>x720=(1080/720)*720=1080px</li></ul></blockquote></li></ul><p>如下分别为分辨率 1280x720 与 1920x1080 所对应的横向dimens.xml 文件:<br><img src="/images/dimens_01.jpg" alt="分辨率 1280x720 与 1920x1080 所对应的横向dimens"></p><ul><li>缺点<br>这个方案有一个致命的缺陷,那就是需要精准命中才能适配,比如1920x1080的手机就一定要找到1920x1080的限定符,否则就只能用统一的默认的dimens文件了。而使用默认的尺寸的话,UI就很可能变形,简单说,就是容错机制很差。</li></ul><h4 id="2-smallestWidth-限定符"><a href="#2-smallestWidth-限定符" class="headerlink" title="2. smallestWidth 限定符"></a>2. smallestWidth 限定符</h4><blockquote><p>smallestWidth适配,或者叫sw限定符适配。指的是Android会识别屏幕可用高度和宽度的最小尺寸的dp值(其实就是手机的宽度值),然后根据识别到的结果去资源文件中寻找对应限定符的文件夹下的资源文件。<br><strong>smallestWidth 限定符 和宽高限定符适配原理上是一样的,都是系统通过特定的规则来选择对应的文件。</strong></p></blockquote><ul><li>smallestWidth 限定符屏幕适配方案 只是把 dimens.xml 文件中的值从 px 换成了 dp,原理和使用方式都是没变的。</li></ul><p><img src="/images/dimens_02.jpg" alt="最小宽度为 360dp 与最小宽度为 640dp 所对应的 dimens"></p><ul><li><p>插件ScreenMatch自动生成dimes文件<br><a href="https://www.jianshu.com/p/1302ad5a4b04" target="_blank" rel="noopener">一种非常好用的Android屏幕适配</a></p></li><li><p>优点:</p><blockquote><ul><li>smallestWidth 限定符比屏幕分辨率限定符需要少量 dimens.xml 文件</li><li>smallestWidth 限定符适配采用的单位是 dp 和 sp。屏幕分辨率限定符采用px。</li><li>屏幕分辨率限定符需要精准命中才能适配,而 smallestWidth 限定符适配寻找 dimens.xml 文件的原理是从大往小找,即使没有完全匹配也能达到不错的适配效果。</li></ul></blockquote></li><li><p>缺点:</p><blockquote><ul><li>侵入性高,在所有地方都需要引用。</li><li>还是没有办法覆盖所有的机型分辨率,部分机型可能适配效果还是不佳。</li><li>不能以高度为基准进行适配。</li><li>生成很多文件,增大APP体积1~2M。</li></ul></blockquote></li></ul><h4 id="3-今日头条适配方案"><a href="#3-今日头条适配方案" class="headerlink" title="3. 今日头条适配方案"></a>3. 今日头条适配方案</h4><blockquote><p>今日头条屏幕适配方案的核心原理在于,动态计算density,通过系统api,将density赋值给系统,抛弃掉系统默认计算density的计算公式。<br>公式: $density = 屏幕宽度px / 设计图宽度(375dp)$</p></blockquote><ul><li><p>如何使用<br><a href="https://blog.csdn.net/wang_yong_hui_1234/article/details/82113714" target="_blank" rel="noopener">今日头条屏幕适配方案</a></p></li><li><p>优点</p><blockquote><ul><li>使用成本非常低,操作非常简单</li><li>侵入性非常低</li><li>可适配三方库的控件和系统的控件</li></ul></blockquote></li><li><p>缺点</p><blockquote><ul><li>会全局影响APP的控件大小,例如一些第三方库控件,他们设计的时候可能设计图尺寸并不是像我们一样是375dp,这样就会导致控件大小变形等一些问题。<br>当某个系统控件或三方库控件的设计图尺寸和和我们项目自身的设计图尺寸差距非常大时,这个问题就越严重。</li></ul></blockquote></li></ul><hr><p>参考:<a href="https://cloud.tencent.com/developer/article/1426238" target="_blank" rel="noopener">Android屏幕适配方案分析</a></p>]]></content>
<summary type="html">
<h1 id="Android屏幕适配方案"><a href="#Android屏幕适配方案" class="headerlink" title="Android屏幕适配方案"></a>Android屏幕适配方案</h1><blockquote>
<p>先讲述一些屏幕适配相关概念,然后介绍下3种主要的适配方案以及优缺点。</p>
</blockquote>
<h3 id="一-基本概念"><a href="#一-基本概念" class="headerlink" title="一.基本概念"></a>一.基本概念</h3><h4 id="1-像素(px)"><a href="#1-像素(px)" class="headerlink" title="1. 像素(px)"></a>1. 像素(px)</h4><ul>
<li>像素是手机屏幕的最小构成单元。<h4 id="2-分辨率-(px)"><a href="#2-分辨率-(px)" class="headerlink" title="2. 分辨率 (px)"></a>2. 分辨率 (px)</h4></li>
<li>手机在横向、纵向上的像素点数总和,一般描述成 宽高 ,即横向像素点个数纵向像素点个数。</li>
<li>例如:1080x1920,即宽度方向上有1080个像素点,在高度方向上有1920个像素点。<h4 id="3-屏幕尺寸(inch)"><a href="#3-屏幕尺寸(inch)" class="headerlink" title="3.屏幕尺寸(inch)"></a>3.屏幕尺寸(inch)</h4></li>
<li>手机对角线的物理尺寸,单位 英寸(inch),一英寸大约2.54cm,</li>
<li>例如:常见的尺寸有4.7寸、5寸、5.5寸、6寸<h4 id="4-屏幕像素密度-dpi"><a href="#4-屏幕像素密度-dpi" class="headerlink" title="4.屏幕像素密度 (dpi)"></a>4.屏幕像素密度 (dpi)</h4></li>
<li>每英寸长度上像素点个数。”dot per inch”:</li>
<li>例如每英寸内有160个像素点,则其像素密度为160dpi。<h5 id="以上四者之间关系"><a href="#以上四者之间关系" class="headerlink" title="以上四者之间关系"></a>以上四者之间关系</h5></li>
<li>$ √((宽px)²+(高px)²) / (屏幕尺寸inch) = (屏幕像素密度dpi) $ <h4 id="5-dp,dip,sp"><a href="#5-dp,dip,sp" class="headerlink" title="5. dp,dip,sp"></a>5. dp,dip,sp</h4></li>
<li>dip和dp是一个意思,都是Density Independent Pixels的缩写,即密度无关像素。</li>
<li>例如:在Android中,规定以160dpi为基准,1dip=1px,如果密度是320dpi,则1dip=2px,以此类推。</li>
<li>android中的dp在渲染前会将dp转为px,计算公式:<br>$px = density * dp;$<br>$density = dpi / 160;$<br>$px = dp * (dpi / 160);$</li>
<li>注意:dp与px不一定都是2倍的关系,与屏幕像素密度dpi有关。<h4 id="6-hdpi,mdpi,xhdpi,xxhdpi,xxxhdpi"><a href="#6-hdpi,mdpi,xhdpi,xxhdpi,xxxhdpi" class="headerlink" title="6. hdpi,mdpi,xhdpi,xxhdpi,xxxhdpi"></a>6. hdpi,mdpi,xhdpi,xxhdpi,xxxhdpi</h4></li>
<li>用来修饰Android中的drawable文件夹及values文件夹,用来区分不同像素密度下的图片和dimen值。</li>
<li>在设计图标时,对于五种主流的像素密度(mdpi、hdpi、xhdpi、xxhdpi 和 xxxhdpi)应按照 2:3:4:6:8 的比例进行缩放。</li>
</ul>
</summary>
<category term="Android" scheme="https://inote.fun/categories/Android/"/>
<category term="知识点" scheme="https://inote.fun/categories/Android/%E7%9F%A5%E8%AF%86%E7%82%B9/"/>
<category term="屏幕适配" scheme="https://inote.fun/tags/%E5%B1%8F%E5%B9%95%E9%80%82%E9%85%8D/"/>
</entry>
<entry>
<title>《蝴蝶效应》电影观后感</title>
<link href="https://inote.fun/2019/10/02/%E8%9D%B4%E8%9D%B6%E6%95%88%E5%BA%94-%E7%94%B5%E5%BD%B1%E8%A7%82%E5%90%8E%E6%84%9F/"/>
<id>https://inote.fun/2019/10/02/蝴蝶效应-电影观后感/</id>
<published>2019-10-02T09:04:13.000Z</published>
<updated>2019-10-21T13:56:46.024Z</updated>
<content type="html"><![CDATA[<p><img src="/images/TheButterflyEffect.jpg" alt="蝴蝶效应"></p><p>丢失一个钉子,坏了一只蹄铁;<br>坏了一只蹄铁,折了一匹战马;<br>折了一匹战马,伤了一位骑士;<br>伤了一位骑士,输了一场战斗;<br>输了一场战斗,亡了一个帝国。</p><hr><blockquote><p> 蝴蝶效应(The Butterfly Effect):<br> 主角伊万曾经有一个糟糕的童年,因为他行为闯下了大祸,令他童年充满不堪回忆的往事。而事实上,他确实只是依稀记得一点可怕的情景,这些情景一直纠缠着他的正常生活。伊万接受心理学家建议,把琐碎生活记在记事本里,却偶然发现通过记事本回到过去。<br> 这时他才清楚记起,童年时候的自己做了那么多的错事。他幻想着用现在的意识,潜入童年的身体,去弥补种种过失给人们带来的伤害,尤其是希望与当年暗恋的凯西最终走回一起。然而他一次次的跨越时空的更改,只能越来越招致现实世界的不可救药。</p></blockquote><a id="more"></a><hr><h5 id="精彩影评:"><a href="#精彩影评:" class="headerlink" title="精彩影评:"></a>精彩影评:</h5><ul><li>每一次的选择已经是最好的选择了。改变未必是优化。</li><li>你无法改变一个人又不毁掉他。</li><li>我们都有过回到过去的冲动,都想重新开始做个更好的自己,然而宿命横亘在前,不管你怎样做,无论你做怎样的选择,最终都避不开无休无止的挫败伤痛。最干净的办法就是从未来过。这似乎有些悲观消极,因此圣贤又谆谆告诫我们,往者不可谏,来者犹可追,告诉我们满目山河空念远,不如怜取眼前人。</li></ul><hr><p>暂且不谈,我如果具备这样改变过去的特异能力,当然如果我有,我也许会去改变一些事,但是改变什么?当然是买彩票了,哈哈哈。</p><p>其实回归现实的说,特异功能是不会有的,也许影片导演在告诉我们,反思过去的人生,你活的开心吗。最后,你会发现其实现在这样平平淡淡挺好,改变从来不是一下子,国学讲究中庸,也许这就是古人悟出的生活真谛。改变都是从一点一滴开始,用力过猛适得其反。永远不知道未来事情走向,能做的就是坦然面对所有即将发生的事,做好现在正在做的事,对已发生的事释然。</p><p>改变总是在不经意间。同样每一个不经意间都可能改变所有事。</p>]]></content>
<summary type="html">
<p><img src="/images/TheButterflyEffect.jpg" alt="蝴蝶效应"></p>
<p>丢失一个钉子,坏了一只蹄铁;<br>坏了一只蹄铁,折了一匹战马;<br>折了一匹战马,伤了一位骑士;<br>伤了一位骑士,输了一场战斗;<br>输了一场战斗,亡了一个帝国。</p>
<hr>
<blockquote>
<p> 蝴蝶效应(The Butterfly Effect):<br> 主角伊万曾经有一个糟糕的童年,因为他行为闯下了大祸,令他童年充满不堪回忆的往事。而事实上,他确实只是依稀记得一点可怕的情景,这些情景一直纠缠着他的正常生活。伊万接受心理学家建议,把琐碎生活记在记事本里,却偶然发现通过记事本回到过去。<br> 这时他才清楚记起,童年时候的自己做了那么多的错事。他幻想着用现在的意识,潜入童年的身体,去弥补种种过失给人们带来的伤害,尤其是希望与当年暗恋的凯西最终走回一起。然而他一次次的跨越时空的更改,只能越来越招致现实世界的不可救药。</p>
</blockquote>
</summary>
<category term="心情" scheme="https://inote.fun/categories/%E5%BF%83%E6%83%85/"/>
<category term="电影" scheme="https://inote.fun/tags/%E7%94%B5%E5%BD%B1/"/>
</entry>
</feed>