-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.html
1269 lines (885 loc) · 215 KB
/
index.html
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
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html>
<head><meta name="generator" content="Hexo 3.8.0">
<meta charset="utf-8">
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link rel="dns-prefetch" href="http://yoursite.com">
<title>aicaprio的博客</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta property="og:type" content="website">
<meta property="og:title" content="aicaprio的博客">
<meta property="og:url" content="http://yoursite.com/index.html">
<meta property="og:site_name" content="aicaprio的博客">
<meta property="og:locale" content="default">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="aicaprio的博客">
<link rel="alternative" href="/atom.xml" title="aicaprio的博客" type="application/atom+xml">
<link rel="icon" href="/favicon.png">
<link rel="stylesheet" type="text/css" href="/./main.0cf68a.css">
<style type="text/css">
#container.show {
background: linear-gradient(200deg,#a0cfe4,#e8c37e);
}
</style>
</head>
</html>
<body>
<div id="container" q-class="show:isCtnShow">
<canvas id="anm-canvas" class="anm-canvas"></canvas>
<div class="left-col" q-class="show:isShow">
<div class="overlay" style="background: #4d4d4d"></div>
<div class="intrude-less">
<header id="header" class="inner">
<a href="/" class="profilepic">
<img src="/assets/avatar/avatar.jpeg" class="js-avatar">
</a>
<hgroup>
<h1 class="header-author"><a href="/">硕</a></h1>
</hgroup>
<p class="header-subtitle">行到水穷处,坐看云起时</p>
<nav class="header-menu">
<ul>
<li><a href="/">主页</a></li>
<li><a href="/tags/Android/">Android</a></li>
<li><a href="/tags/JAVAEE/">JAVAEE</a></li>
<li><a href="/tags/Casual/">Casual</a></li>
</ul>
</nav>
<nav class="header-smart-menu">
<a q-on="click: openSlider(e, 'innerArchive')" href="javascript:void(0)">所有文章</a>
<a q-on="click: openSlider(e, 'aboutme')" href="javascript:void(0)">关于我</a>
</nav>
<nav class="header-nav">
<div class="social">
<a class="github" target="_blank" href="https://github.com/aicaprio" title="github"><i class="icon-github"></i></a>
<a class="mail" target="_blank" href="/[email protected]" title="mail"><i class="icon-mail"></i></a>
<a class="twitter" target="_blank" href="https://twitter.com/aicaprio" title="twitter"><i class="icon-twitter"></i></a>
</div>
</nav>
</header>
</div>
</div>
<div class="mid-col" q-class="show:isShow,hide:isShow|isFalse">
<nav id="mobile-nav">
<div class="overlay js-overlay" style="background: #4d4d4d"></div>
<div class="btnctn js-mobile-btnctn">
<div class="slider-trigger list" q-on="click: openSlider(e)"><i class="icon icon-sort"></i></div>
</div>
<div class="intrude-less">
<header id="header" class="inner">
<div class="profilepic">
<img src="/assets/avatar/avatar.jpeg" class="js-avatar">
</div>
<hgroup>
<h1 class="header-author js-header-author">硕</h1>
</hgroup>
<p class="header-subtitle"><i class="icon icon-quo-left"></i>行到水穷处,坐看云起时<i class="icon icon-quo-right"></i></p>
<nav class="header-nav">
<div class="social">
<a class="github" target="_blank" href="https://github.com/aicaprio" title="github"><i class="icon-github"></i></a>
<a class="mail" target="_blank" href="/[email protected]" title="mail"><i class="icon-mail"></i></a>
<a class="twitter" target="_blank" href="https://twitter.com/aicaprio" title="twitter"><i class="icon-twitter"></i></a>
</div>
</nav>
<nav class="header-menu js-header-menu">
<ul style="width: 70%">
<li style="width: 25%"><a href="/">主页</a></li>
<li style="width: 25%"><a href="/tags/Android/">Android</a></li>
<li style="width: 25%"><a href="/tags/JAVAEE/">JAVAEE</a></li>
<li style="width: 25%"><a href="/tags/Casual/">Casual</a></li>
</ul>
</nav>
</header>
</div>
<div class="mobile-mask" style="display:none" q-show="isShow"></div>
</nav>
<div id="wrapper" class="body-wrap">
<div class="menu-l">
<div class="canvas-wrap">
<canvas data-colors="#eaeaea" data-sectionHeight="100" data-contentId="js-content" id="myCanvas1" class="anm-canvas"></canvas>
</div>
<div id="js-content" class="content-ll">
<article id="post-Kotlin-vs-Swift" class="article article-type-post article-index" itemscope="" itemprop="blogPost">
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2020/08/04/Kotlin-vs-Swift/">Kotlin-vs-Swift</a>
</h1>
<a href="/2020/08/04/Kotlin-vs-Swift/" class="archive-article-date">
<time datetime="2020-08-04T06:46:03.000Z" itemprop="datePublished"><i class="icon-calendar icon"></i>2020-08-04</time>
</a>
</header>
<div class="article-entry" itemprop="articleBody">
<h3 id="1-字符串-gt-原始内容与转义内容"><a href="#1-字符串-gt-原始内容与转义内容" class="headerlink" title="1. 字符串->原始内容与转义内容"></a>1. 字符串->原始内容与转义内容</h3><p><strong>Swift</strong><br><code>#""#</code>包含的字符串,会显示原始内容。<br><code>#""#</code>包含的字符串,如果在转义字符前加<code>#</code>,则转义字符生效。<br>显示原始内容一般还是使用<code>"""</code>比较方便。<br><img src="/2020/08/04/Kotlin-vs-Swift/字符串1.png" alt="示例"></p>
<blockquote>
<p>比较:<br>在<code>Swfit</code>中,<code>"""</code>的起始必须是独立的一行,结束也必须是独立的一行。<br>但是在<code>Kotlin</code>中,没有这个限制:<br><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">val str = """原始内容"""</span><br><span class="line">println(str)</span><br></pre></td></tr></table></figure></p>
</blockquote>
</div>
<div class="article-info article-info-index">
<div class="article-tag tagcloud">
<i class="icon-price-tags icon"></i>
<ul class="article-tag-list">
<li class="article-tag-list-item">
<a href="javascript:void(0)" class="js-tag article-tag-list-link color3">Android</a>
</li>
</ul>
</div>
<p class="article-more-link">
<a class="article-more-a" href="/2020/08/04/Kotlin-vs-Swift/">展开全文 >></a>
</p>
<div class="clearfix"></div>
</div>
</div>
</article>
<aside class="wrap-side-operation">
<div class="mod-side-operation">
<div class="jump-container" id="js-jump-container" style="display:none;">
<a href="javascript:void(0)" class="mod-side-operation__jump-to-top">
<i class="icon-font icon-back"></i>
</a>
<div id="js-jump-plan-container" class="jump-plan-container" style="top: -11px;">
<i class="icon-font icon-plane jump-plane"></i>
</div>
</div>
</div>
</aside>
<article id="post-lambda表达式" class="article article-type-post article-index" itemscope="" itemprop="blogPost">
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2019/12/18/lambda表达式/">lambda表达式</a>
</h1>
<a href="/2019/12/18/lambda表达式/" class="archive-article-date">
<time datetime="2019-12-18T07:15:52.000Z" itemprop="datePublished"><i class="icon-calendar icon"></i>2019-12-18</time>
</a>
</header>
<div class="article-entry" itemprop="articleBody">
<h2 id="基础知识点"><a href="#基础知识点" class="headerlink" title="基础知识点"></a>基础知识点</h2><p>只要能快速使用就可以了,不需要深究…</p>
<h5 id="lambda表达式与函数式接口的区别"><a href="#lambda表达式与函数式接口的区别" class="headerlink" title="lambda表达式与函数式接口的区别"></a>lambda表达式与函数式接口的区别</h5><blockquote>
<p>函数式接口(Functional Interfaces,简称:<strong>FI</strong>)<br>首先是一个<strong>接口</strong>,然后就是在这个接口里面<strong>只能</strong>有<strong>一个抽象方法</strong>。</p>
</blockquote>
<blockquote>
<p>lambda表达式是一种<strong>语法糖</strong>,为了能够方便、快捷、幽雅的创建出FI的实例<br>又被成为“闭包”或“匿名方法”。</p>
</blockquote>
<h5 id="lambda表达式的语法由参数列表,箭头符号(-gt-)和函数体组成"><a href="#lambda表达式的语法由参数列表,箭头符号(-gt-)和函数体组成" class="headerlink" title="lambda表达式的语法由参数列表,箭头符号(->)和函数体组成"></a>lambda表达式的语法由参数列表,箭头符号(->)和函数体组成</h5><p><img src="http://upload-images.jianshu.io/upload_images/3866941-3951533058a2f69f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<p><strong>函数体</strong> 既可以是一个<strong>表达式</strong>,也可以是一个<strong>语句块</strong></p>
<blockquote>
<p>表达式会被执行,然后返回执行结果。</p>
</blockquote>
<blockquote>
<p>语句块中的语句会被依次执行,就像方法中的语句一样。<br> <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></pre></td><td class="code"><pre><span class="line">return语句会把控制权交给匿名方法的调用者 </span><br><span class="line"></span><br><span class="line">break和continue只能在循环中使用</span><br><span class="line"></span><br><span class="line">如果函数体有返回值,那么函数体内部的每一条路径都必须有返回值</span><br><span class="line"></span><br><span class="line">表达式函数体适合小型lambda表达式,它消除了return关键字,使得语法更加简洁。</span><br></pre></td></tr></table></figure></p>
</blockquote>
<blockquote>
<p>FI的名称并不是lambda表达式的一部分,对于给定的lambda表达式,它的类型(也就是自己所对应的FI的接口类型)是由其上下文推导而来。</p>
</blockquote>
<h5 id="几个例子"><a href="#几个例子" class="headerlink" title="几个例子"></a>几个例子</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></pre></td><td class="code"><pre><span class="line">(int x, int y) -> x + y</span><br><span class="line">() -> 42</span><br><span class="line">(String s) -> { System.out.println(s); }</span><br></pre></td></tr></table></figure>
<p>第一个lambda表达式接收x和y这两个整形参数并返回它们的和;</p>
<p>第二个lambda表达式不接收参数,返回整数’42’;</p>
<p>第三个lambda表达式接收一个字符串并把它打印到控制台,不返回值。</p>
<h5 id="可以省略的部分"><a href="#可以省略的部分" class="headerlink" title="可以省略的部分"></a>可以省略的部分</h5><ol>
<li><p>函数体如果是表达式,可以省略**return关键字。</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">(int x, int y) -> x + y</span><br><span class="line">() -> 42</span><br></pre></td></tr></table></figure>
</li>
<li><p>函数体<strong>只有一行</strong>,可以省略<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></pre></td><td class="code"><pre><span class="line">FileFilter java = (File f) -> f.getName().endsWith("*.java");</span><br><span class="line"></span><br><span class="line">String user = doPrivileged(() -> System.getProperty("user.name"));</span><br></pre></td></tr></table></figure>
</li>
<li><p>因为lambda表达式的类型是从上下文推导而来,<br> 所以可以省略参数列表里的<strong>参数类型</strong>。</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Comparator<String> c = (s1, s2) -> s1.compareToIgnoreCase(s2);</span><br></pre></td></tr></table></figure>
</li>
<li><p>当lambda的<strong>参数只有一个</strong>而且它的类型可以被推导得知时,<br> 该<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></pre></td><td class="code"><pre><span class="line">FileFilter java = f -> f.getName().endsWith(".java");</span><br><span class="line"></span><br><span class="line">button.addActionListener(e -> ui.dazzle(e.getModifiers()));</span><br></pre></td></tr></table></figure>
</li>
</ol>
<p><br></p>
<h2 id="方法的调用"><a href="#方法的调用" class="headerlink" title="方法的调用"></a>方法的调用</h2><blockquote>
<p>前提一:在函数式接口(FI)的作用域内</p>
</blockquote>
<blockquote>
<p>前提二:lambda表达式函数体必须是表达式(函数体只有一行)。 </p>
</blockquote>
<blockquote>
<p>前提三:那个表达式的格式是:符合java语法标准的,方法的调用</p>
</blockquote>
<p>另外,记住3种情况就可以:</p>
<h5 id="一-静态方法的调用"><a href="#一-静态方法的调用" class="headerlink" title="一. 静态方法的调用"></a>一. 静态方法的调用</h5><blockquote>
<p>类名::静态方法名</p>
</blockquote>
<p><strong>示例</strong><br>公用类:<br><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">public class Student {</span><br><span class="line"></span><br><span class="line"> private Integer id;</span><br><span class="line"></span><br><span class="line"> private String name;</span><br><span class="line"></span><br><span class="line"> public Student(Integer id, String name) {</span><br><span class="line"> this.id = id;</span><br><span class="line"> this.name = name;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> public String getStudentInfo() {</span><br><span class="line"> return "Student:name:" + name + ",id:" + id;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> public void printStudentInfo() {</span><br><span class="line"> Log.d("CCC", getStudentInfo());</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> public void printStudentInfo2(String addedNote) {</span><br><span class="line"> Log.d("CCC", "addedNote:" + addedNote + " " + getStudentInfo());</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure></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></pre></td><td class="code"><pre><span class="line">public class StudentUtils {</span><br><span class="line"> public static String getStudentInfo(Student student) {</span><br><span class="line"> return student.getStudentInfo();</span><br><span class="line"> }</span><br><span class="line">}</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></pre></td><td class="code"><pre><span class="line">public class GetStudentInfoUseCase {</span><br><span class="line"> public String getStudentInfo(Student student){</span><br><span class="line"> return student.getStudentInfo();</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>数据源:<br><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></pre></td><td class="code"><pre><span class="line">private List<Student> getData() {</span><br><span class="line"> List<Student> list = new ArrayList<>();</span><br><span class="line"></span><br><span class="line"> for (int i = 0; i < 100; i++) {</span><br><span class="line"> Integer id = i + 1;</span><br><span class="line"> list.add(new Student(id, "N" + id));</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> return list;</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<p>静态方法的调用:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">private void testStaticRef() {</span><br><span class="line"> getData().forEach(StudentUtils::getStudentInfo);</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>就是这么简单,但是我们要看下演化的流程。下面是原版:<br><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">getData().forEach(new java.util.function.Consumer<Student>() {</span><br><span class="line"> @Override</span><br><span class="line"> public void accept(Student student) {</span><br><span class="line"> StudentUtils.getStudentInfo(student);</span><br><span class="line"> }</span><br><span class="line">});</span><br></pre></td></tr></table></figure></p>
<p>将 FI 转为lambda:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">getData().forEach(student -> StudentUtils.getStudentInfo(student));</span><br></pre></td></tr></table></figure>
<p>可以看到:</p>
<ul>
<li><p>GetCardInfoUseCase.getCardInfo的<strong>参数列表</strong> 与 FI 方法【accept(Student student) 】的<strong>参数列表</strong>是一致的</p>
</li>
<li><p>向GetCardInfoUseCase.getCardInfo传的值<strong>正好</strong>就是FI方法的实参</p>
</li>
</ul>
<blockquote>
<p>正因为静态方法与FI方法两者的参数列表一致,且由FI方法传递给静态方法,也就是说无论FI的方法是什么,静态方法都要保持一致并接收。<br>所以可以直接省略参数列表,直接显示是什么类的什么方法。</p>
</blockquote>
<p>也就是:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">getData().forEach(StudentUtils::getStudentInfo);</span><br></pre></td></tr></table></figure></p>
<h5 id="二-实例上的实例方法调用"><a href="#二-实例上的实例方法调用" class="headerlink" title="二. 实例上的实例方法调用"></a>二. 实例上的实例方法调用</h5><blockquote>
<p>实例对象::实例方法名</p>
</blockquote>
<p><strong>示例</strong><br><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></pre></td><td class="code"><pre><span class="line">private void testInstInstRef() {</span><br><span class="line"> GetStudentInfoUseCase useCase = new GetStudentInfoUseCase();</span><br><span class="line"></span><br><span class="line"> getData().forEach(useCase::getStudentInfo);</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<p>演化的流程,下面原版:<br><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">getData().forEach(new java.util.function.Consumer<Student>() {</span><br><span class="line"> @Override</span><br><span class="line"> public void accept(Student student) {</span><br><span class="line"> useCase.getStudentInfo(student);</span><br><span class="line"> }</span><br><span class="line">});</span><br></pre></td></tr></table></figure></p>
<p> FI 转为lambda:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">getData().forEach(student -> useCase.getStudentInfo(student));</span><br></pre></td></tr></table></figure></p>
<p>最后:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">getData().forEach(useCase::getStudentInfo);</span><br></pre></td></tr></table></figure></p>
<p>同理:lambda实例方法的参数列表必须同FI方法的参数列表保持一致</p>
<p>#####三. 类型上的实例方法调用</p>
<blockquote>
<p>类名::实例方法名</p>
</blockquote>
<p>可以看出:它的调用方式同第一种“静态方法的调用”</p>
<p><strong>示例</strong><br><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">private void testClsInstRef() {</span><br><span class="line"> getData().forEach(Student::printStudentInfo);</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<p>演化流程,下面是原版:<br><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">getData().forEach(new java.util.function.Consumer<Student>() {</span><br><span class="line"> @Override</span><br><span class="line"> public void accept(Student student) {</span><br><span class="line"> student.printStudentInfo();</span><br><span class="line"> }</span><br><span class="line">});</span><br></pre></td></tr></table></figure></p>
<p>将FI 转为lambda:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">getData().forEach(student -> student.printStudentInfo());</span><br></pre></td></tr></table></figure></p>
<p>最后:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">getData().forEach(Student::printStudentInfo);</span><br></pre></td></tr></table></figure></p>
<h5 id="来来来,划重点:"><a href="#来来来,划重点:" class="headerlink" title="来来来,划重点:"></a>来来来,划重点:</h5><blockquote>
<p>前两种方式是将FI的实参,作为lambda方法的实参来使用<br>而第三种,FI的实参,是作为lambda方法的<strong>调用者</strong>来使用</p>
</blockquote>
<p>这就是第三种可以使用<strong>类型::实例方法名</strong>来调用的原因。</p>
<p>有利必有弊,第三种默认是将lambda方法的<strong>第一个</strong>实参作为该实例方法的调用者(本文FI方法【accept(Student student) 】只是恰巧只有一个,其他FI方法可以有多个)。但这种调用的局限性非常明显,那就是对于被调用的方法而言<strong>不能有参数</strong>。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">getData().forEach(Student::printStudentInfo2);</span><br></pre></td></tr></table></figure></p>
<p>printStudentInfo2(String addedNote)方法有一个参数,编译时报如下错:</p>
<p><img src="http://upload-images.jianshu.io/upload_images/3866941-07f3537779b09c8c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<p>可以看出:编译器直接将printStudentInfo2方法识别为静态方法</p>
<p>以上就是三种方法的快速使用总结。其他方法的调用还有:超类上的实例方法调用,构造方法的调用,数组构造方法调用等这些不常用的就不赘述了,用到再自己查阅资料。</p>
</div>
<div class="article-info article-info-index">
<div class="article-tag tagcloud">
<i class="icon-price-tags icon"></i>
<ul class="article-tag-list">
<li class="article-tag-list-item">
<a href="javascript:void(0)" class="js-tag article-tag-list-link color2">JavaEE</a>
</li>
</ul>
</div>
<p class="article-more-link">
<a class="article-more-a" href="/2019/12/18/lambda表达式/">展开全文 >></a>
</p>
<div class="clearfix"></div>
</div>
</div>
</article>
<aside class="wrap-side-operation">
<div class="mod-side-operation">
<div class="jump-container" id="js-jump-container" style="display:none;">
<a href="javascript:void(0)" class="mod-side-operation__jump-to-top">
<i class="icon-font icon-back"></i>
</a>
<div id="js-jump-plan-container" class="jump-plan-container" style="top: -11px;">
<i class="icon-font icon-plane jump-plane"></i>
</div>
</div>
</div>
</aside>
<article id="post-ConstraintLayout随笔" class="article article-type-post article-index" itemscope="" itemprop="blogPost">
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2019/10/09/ConstraintLayout随笔/">ConstraintLayout随笔</a>
</h1>
<a href="/2019/10/09/ConstraintLayout随笔/" class="archive-article-date">
<time datetime="2019-10-09T05:57:35.000Z" itemprop="datePublished"><i class="icon-calendar icon"></i>2019-10-09</time>
</a>
</header>
<div class="article-entry" itemprop="articleBody">
<p>ConstraintLayout相关的知识点,不定期更新。</p>
</div>
<div class="article-info article-info-index">
<div class="article-tag tagcloud">
<i class="icon-price-tags icon"></i>
<ul class="article-tag-list">
<li class="article-tag-list-item">
<a href="javascript:void(0)" class="js-tag article-tag-list-link color3">Android</a>
</li>
</ul>
</div>
<p class="article-more-link">
<a class="article-more-a" href="/2019/10/09/ConstraintLayout随笔/">展开全文 >></a>
</p>
<div class="clearfix"></div>
</div>
</div>
</article>
<aside class="wrap-side-operation">
<div class="mod-side-operation">
<div class="jump-container" id="js-jump-container" style="display:none;">
<a href="javascript:void(0)" class="mod-side-operation__jump-to-top">
<i class="icon-font icon-back"></i>
</a>
<div id="js-jump-plan-container" class="jump-plan-container" style="top: -11px;">
<i class="icon-font icon-plane jump-plane"></i>
</div>
</div>
</div>
</aside>
<article id="post-UML类图中的关系类型" class="article article-type-post article-index" itemscope="" itemprop="blogPost">
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2019/04/17/UML类图中的关系类型/">UML类图中的关系类型</a>
</h1>
<a href="/2019/04/17/UML类图中的关系类型/" class="archive-article-date">
<time datetime="2019-04-17T06:35:22.000Z" itemprop="datePublished"><i class="icon-calendar icon"></i>2019-04-17</time>
</a>
</header>
<div class="article-entry" itemprop="articleBody">
<p><em>开始前,先介绍两个在线制作UML的网站:</em><br><a href="https://www.lucidchart.com" target="_blank" rel="noopener">LucidChart</a> 和 <a href="https://www.processon.com" target="_blank" rel="noopener">ProcessOn</a></p>
<p>然后是“类图”的<a href="https://en.wikipedia.org/wiki/Class_diagram" target="_blank" rel="noopener">官方Wiki</a>。直接上官方的原因是为了避免在理解某些术语时可能出现的“义同词不同”的歧义。<br><em>另附上其他好的<a href="https://www.visual-paradigm.com/guide/uml-unified-modeling-language/uml-class-diagram-tutorial/" target="_blank" rel="noopener">文章</a>。</em></p>
<h1 id="关系-Relationships"><a href="#关系-Relationships" class="headerlink" title="关系(Relationships)"></a>关系(Relationships)</h1><p>关系是一个通用术语,涵盖在类和对象图上找到的特定类型的逻辑连接。一个类可能涉及与其他类的一个或多个关系,下面逐一介绍各种类型关系。</p>
<h2 id="类级关系-Class-level-relationships"><a href="#类级关系-Class-level-relationships" class="headerlink" title="类级关系(Class-level relationships)"></a>类级关系(Class-level relationships)</h2><h6 id="泛化-Generalization-继承-Inheritance"><a href="#泛化-Generalization-继承-Inheritance" class="headerlink" title="泛化(Generalization)/继承(Inheritance)"></a>泛化(Generalization)/继承(Inheritance)</h6><p>泛化表示的是,两个相关类中的一个(子类)被认为是另一个(超类)的特殊形式,如此该超类被认为是该子类的泛化。实际上,这也意味着子类的任何实例也都是超类的实例。</p>
<p>从生物分类中我们可以发现这是一个典型泛化树的例子:人类是猿猴的亚类,猿猴是哺乳动物的亚类,等等。通过短语“A是B”(人类是哺乳动物,哺乳动物是动物)最容易理解这种关系。</p>
<p>泛化关系也称为“继承”或“is a”关系。</p>
<p>泛化关系中的超类也称为父类/基类。</p>
<p>特化关系中的子类也称为派生类/继承类。</p>
<p>“A是B的一种”的例子:“橡木是一种树”,“汽车是一种车”</p>
<p><em>注:接口继承接口同样适用。</em></p>
<p>它的标志是:<strong>实线 + 空心封闭的箭头 箭头在右侧</strong>, 如下图所示:<br><img src="/2019/04/17/UML类图中的关系类型/泛化箭头.png" alt="箭头"></p>
<p><img src="/2019/04/17/UML类图中的关系类型/泛化例子.png" alt="示例"></p>
<h6 id="实现-Realization-Implementation"><a href="#实现-Realization-Implementation" class="headerlink" title="实现(Realization/Implementation)"></a>实现(Realization/Implementation)</h6><p>在UML建模中,实现关系是两个模型元素之间的关系,其中一个模型元素(客户端)实现或执行另一个模型元素(供应商)指定的行为。</p>
<p>实现只能在类图或者组件图上显示,这里只提类图。</p>
<p>实现是连接客户端元素和供应商元素的类、接口之间的关系。类与接口之间的实现关系表明该类实现了该接口提供的操作。</p>
<p>它的标志是:<strong>虚线 + 空心封闭的箭头 箭头在右侧</strong>,如下图所示:<br><img src="/2019/04/17/UML类图中的关系类型/实现箭头.png" alt="箭头"></p>
<p><img src="/2019/04/17/UML类图中的关系类型/实现例子.png" alt="示例"></p>
<h2 id="对象级关系-Instance-level-relationships"><a href="#对象级关系-Instance-level-relationships" class="headerlink" title="对象级关系(Instance-level relationships)"></a>对象级关系(Instance-level relationships)</h2><h6 id="依赖-Dependency"><a href="#依赖-Dependency" class="headerlink" title="依赖(Dependency)"></a>依赖(Dependency)</h6><p>Dependency指的是独立的模型元素与非独立的模型元素间的,一种<strong>语义上的</strong>关联性。</p>
<p>如果两个模型元素,对其中一个元素(the server or target)定义的更改,可能会导致另外一个元素(the client or source)引起变化,则该场景描述的就是依赖的关系。</p>
<p>这种关联是<strong>单向性的</strong>。</p>
<p>它的标志是:<strong>虚线 + 非封闭箭头 箭头在右侧</strong>,如下图所示:</p>
<p><img src="/2019/04/17/UML类图中的关系类型/依赖箭头.png" alt="箭头"></p>
<p><img src="/2019/04/17/UML类图中的关系类型/依赖例子.png" alt="示例"></p>
<h6 id="关联-Association"><a href="#关联-Association" class="headerlink" title="关联(Association)"></a>关联(Association)</h6><p>An association represents a family of links. (关联关系可以被描绘为:一系列链接的族群)</p>
<p>“二元关联”(具有两端)通常用一条直线来表示。</p>
<p>一个关联关系中可以存在多个类之间的链接。如果一个关联关系中有三个链接,通常称之为“三元关联”。</p>
<p>关联关系可以被命名,每个链接的尾端都可以被修饰,诸如:角色名称(role names),所有权指示符(ownership indicators),多样性(multiplicity),可见性(visibility)以及其他属性。</p>
<p>关联代表一系列链接。 二元关联(具有两端)通常表示为线。 关联可以链接任意数量的类。 与三个链接的关联称为三元关联。 </p>
<p>可以命名关联关系,并且可以使用角色名称,所有权指示符,多样性,可见性和其他属性来装饰关联的末尾。</p>
<p>有四种不同类型的关联:双向关联(bi-directionally),单向关联(uni-directional),聚合关联(aggregation)(包括组合/聚合)(includes composition aggregation)和自身关联(reflexive)(又称为递归关联)。 其中双向关联和单向关联是最常见的关联。</p>
<p>关联的一个例子:航班类与飞机类就是一种双向关联。</p>
<p>关联呈现的是<strong>两个对象间共享的静态关系。</strong> </p>
<p>它的标志是:<strong>单纯一条实线</strong>,也有的表示为:<strong>实线 + 非封闭箭头 箭头在右侧</strong>如下图所示:<br><img src="/2019/04/17/UML类图中的关系类型/关联箭头1.png" alt="箭头1"><br><img src="/2019/04/17/UML类图中的关系类型/关联箭头2.png" alt="箭头2"></p>
<p><img src="/2019/04/17/UML类图中的关系类型/关联例子.png" alt="示例"></p>
<h6 id="聚合-Aggregation"><a href="#聚合-Aggregation" class="headerlink" title="聚合(Aggregation)"></a>聚合(Aggregation)</h6><p>聚合是“has a”关联关系的变体,聚合比关联(Association)更加具体些,它表示的这样的一种关联关系:“局部-全局”(part-whole)或者是“一部分”(part-of)。</p>
<p>如下的图解所示:教授有一门课要教。</p>
<p><img src="/2019/04/17/UML类图中的关系类型/聚合例子1.png" alt="例子1"></p>
<p>聚合作为”关联”的一种,它同样具备”被命名”或者其他“关联”所具备的装饰内容。</p>
<p>但是,聚合获取一般不涉及两个以上的类,它必须是一个“二元关联关系”,<strong>除此之外,“聚合”和“关联”几乎没什么区别。</strong> </p>
<p>当一个类是是其他类的集合或者容器时,这是一种聚合关系。但是这些被包含的类不应该对容器有强生命周期依赖关系,容器中的元素即使被销毁,容器本身也可以依旧存在。</p>
<p>聚合是一种<strong>语义上的</strong>扩展对象,在很多操作中,它经常被看做是一个独立单元来处理,尽管从<strong>物理上</strong>它是由很多较小级别的对象组成的。</p>
<p>它的标志是:<strong>实线 + 空心菱形 菱形在左侧</strong>,如下图所示:</p>
<p><img src="/2019/04/17/UML类图中的关系类型/聚合箭头.png" alt="箭头"></p>
<p>一个聚合的例子:图书馆和学生。学生可以不依赖图书馆而存在,学生和图书馆之间的关系就是一种聚合。如下图:</p>
<p><img src="/2019/04/17/UML类图中的关系类型/聚合例子2.png" alt="例子2"></p>
<h6 id="组合-Composition"><a href="#组合-Composition" class="headerlink" title="组合(Composition)"></a>组合(Composition)</h6><p>“组合关系”其实是一种特殊的“聚合关系”:当“整体”被销毁时,“局部”也会被销毁。<br>也就是说,组合关系中的“局部”无法独立于“整体”而存在。</p>
<p>它的标志是:<strong>实线 + 实心菱形 菱形在左侧</strong>,如下图所示:</p>
<p><img src="/2019/04/17/UML类图中的关系类型/组合箭头.png" alt="箭头"> </p>
<blockquote>
<p>组合(Composition)和聚合(Aggregation)的比较<br><br><b>组合(Composition)</b><br><br>可用于描述<b>“现实世界”</b>中的<b>“整体-局部”</b>的关系,比如:现实中的引擎是汽车的一部分。<br><br>当容器被摧毁时,它的所有组成内容都会被销毁。比如:一所大学与其院系之间的关系。<br><br><b>聚合(Aggregation)</b><br><br>一般描述的是<b>软件或者数据库关系</b>,比如:引擎模型ENG01是汽车模型CM01的一部分,因此引擎模型ENG01也可能是其他汽车模型的一部分。<br><br>当容器被摧毁时,与其聚合的内容通常不会被销毁。比如:一个教授有很多学生。但当教授去世时,他的学生并不会跟着他一起去世。<br><br>因此,聚合关系通常表示的是<b>“目录级”</b>的容纳。而组合一般表示的是<b>“物理级”</b>的容纳。</p>
</blockquote>
</div>
<div class="article-info article-info-index">
<div class="article-tag tagcloud">
<i class="icon-price-tags icon"></i>
<ul class="article-tag-list">
<li class="article-tag-list-item">
<a href="javascript:void(0)" class="js-tag article-tag-list-link color2">Casual</a>
</li>
</ul>
</div>
<p class="article-more-link">
<a class="article-more-a" href="/2019/04/17/UML类图中的关系类型/">展开全文 >></a>
</p>
<div class="clearfix"></div>
</div>
</div>
</article>
<aside class="wrap-side-operation">
<div class="mod-side-operation">
<div class="jump-container" id="js-jump-container" style="display:none;">
<a href="javascript:void(0)" class="mod-side-operation__jump-to-top">
<i class="icon-font icon-back"></i>
</a>
<div id="js-jump-plan-container" class="jump-plan-container" style="top: -11px;">
<i class="icon-font icon-plane jump-plane"></i>
</div>
</div>
</div>
</aside>
<article id="post-年轻时的太白" class="article article-type-post article-index" itemscope="" itemprop="blogPost">
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2019/04/15/年轻时的太白/">年轻时的李白</a>
</h1>
<a href="/2019/04/15/年轻时的太白/" class="archive-article-date">
<time datetime="2019-04-15T03:24:35.000Z" itemprop="datePublished"><i class="icon-calendar icon"></i>2019-04-15</time>
</a>
</header>
<div class="article-entry" itemprop="articleBody">
<p><em>年轻时的李白,未诩太白,不是谪仙人,也不曾“天子呼来不上船”,那时的他还未与敬亭山“相看两不厌”,更不会“眼前有景道不得”搁笔黄鹤楼。那时的他才华横溢、卓尔不群、风华正茂、意气风发、飒爽英姿、斗志昂扬、青云直上,壮志凌云!一起感受下那时的他,与那时的万丈豪情:</em></p>
<h6 id="上李邕"><a href="#上李邕" class="headerlink" title="上李邕"></a>上李邕</h6><p><strong>大鹏一日同风起,扶摇直上九万里。<br>假令风歇时下来,犹能簸却沧溟水。<br>世人见我恒殊调,闻余大言皆冷笑。<br>宣父犹能畏后生,丈夫未可轻年少。</strong></p>
<p><img src="/2019/04/15/年轻时的太白/李白.png" alt="图片"></p>
</div>
<div class="article-info article-info-index">
<div class="article-tag tagcloud">
<i class="icon-price-tags icon"></i>
<ul class="article-tag-list">
<li class="article-tag-list-item">
<a href="javascript:void(0)" class="js-tag article-tag-list-link color2">Casual</a>
</li>
</ul>
</div>
<p class="article-more-link">
<a class="article-more-a" href="/2019/04/15/年轻时的太白/">展开全文 >></a>
</p>
<div class="clearfix"></div>
</div>
</div>
</article>
<aside class="wrap-side-operation">
<div class="mod-side-operation">
<div class="jump-container" id="js-jump-container" style="display:none;">
<a href="javascript:void(0)" class="mod-side-operation__jump-to-top">
<i class="icon-font icon-back"></i>
</a>
<div id="js-jump-plan-container" class="jump-plan-container" style="top: -11px;">
<i class="icon-font icon-plane jump-plane"></i>
</div>
</div>
</div>
</aside>
<article id="post-使用Gradle配置SonarQube" class="article article-type-post article-index" itemscope="" itemprop="blogPost">
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2019/04/03/使用Gradle配置SonarQube/">使用Gradle配置SonarQube</a>
</h1>
<a href="/2019/04/03/使用Gradle配置SonarQube/" class="archive-article-date">
<time datetime="2019-04-03T01:59:01.000Z" itemprop="datePublished"><i class="icon-calendar icon"></i>2019-04-03</time>
</a>
</header>
<div class="article-entry" itemprop="articleBody">
<p><em>主要分两步</em></p>
<h5 id="一-代码内Gradle配置"><a href="#一-代码内Gradle配置" class="headerlink" title="一. 代码内Gradle配置"></a>一. 代码内Gradle配置</h5><p>首先是<code>Project</code>级Gradle的配置:<br><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></pre></td><td class="code"><pre><span class="line">buildscript {</span><br><span class="line"></span><br><span class="line"> repositories {</span><br><span class="line"> jcenter()</span><br><span class="line"> maven {url "https://plugins.gradle.org/m2/"}</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> dependencies {</span><br><span class="line"> classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.7"</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">plugins {</span><br><span class="line"> id "org.sonarqube" version "2.7"</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<p>注意:<br><code>plugins</code>前面只可以是<code>buildscript</code>或者<code>plugins</code>,<br>类似这样的<code>apply from: "dependencies.gradle"</code>放在<code>plugins</code>前面任何地方,都会出错。</p>
<p>然后是<code>主Module</code>的Gradle配置:<br><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">apply plugin: 'com.android.application'</span><br><span class="line"></span><br><span class="line">sonarqube {</span><br><span class="line"> properties {</span><br><span class="line"> property "sonar.sources", "src/main/java"</span><br><span class="line"> property "sonar.projectKey", "${YourKey}"</span><br><span class="line"> property "sonar.projectName", "${YourName}"</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<h5 id="二-本地环境Gradle配置"><a href="#二-本地环境Gradle配置" class="headerlink" title="二. 本地环境Gradle配置"></a>二. 本地环境Gradle配置</h5><p>定位到<code>~/.gradle</code>目录下,如果没有<code>gradle.properties</code>,则新建该文件。<br>配置如下内容:<br><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">systemProp.sonar.host.url=xxx</span><br><span class="line">#----- Token generated from an account with 'publish analysis' permission</span><br><span class="line">systemProp.sonar.login=xxx</span><br><span class="line">org.gradle.caching=true</span><br></pre></td></tr></table></figure></p>
<p>配置完毕并且sync后,会产生<code>root级gralde</code>-><code>Task</code>-><code>other</code>-><code>sonarqube</code>指令,直接run即可。</p>
<p>更多内容,请见<a href="https://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner+for+Gradle" target="_blank" rel="noopener">官方文档。</a></p>
</div>
<div class="article-info article-info-index">
<div class="article-tag tagcloud">
<i class="icon-price-tags icon"></i>
<ul class="article-tag-list">
<li class="article-tag-list-item">
<a href="javascript:void(0)" class="js-tag article-tag-list-link color3">Android</a>
</li>
</ul>
</div>
<p class="article-more-link">
<a class="article-more-a" href="/2019/04/03/使用Gradle配置SonarQube/">展开全文 >></a>
</p>
<div class="clearfix"></div>
</div>
</div>
</article>
<aside class="wrap-side-operation">
<div class="mod-side-operation">
<div class="jump-container" id="js-jump-container" style="display:none;">
<a href="javascript:void(0)" class="mod-side-operation__jump-to-top">
<i class="icon-font icon-back"></i>
</a>
<div id="js-jump-plan-container" class="jump-plan-container" style="top: -11px;">
<i class="icon-font icon-plane jump-plane"></i>
</div>
</div>
</div>
</aside>
<article id="post-名词汇总篇" class="article article-type-post article-index" itemscope="" itemprop="blogPost">
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2019/03/29/名词汇总篇/">名词汇总篇(持续更新)</a>
</h1>
<a href="/2019/03/29/名词汇总篇/" class="archive-article-date">
<time datetime="2019-03-29T05:39:06.000Z" itemprop="datePublished"><i class="icon-calendar icon"></i>2019-03-29</time>
</a>
</header>
<div class="article-entry" itemprop="articleBody">
<p><em>虽然是很基础,也许是基础到不屑的零散点,而且这里也不负责挖掘背后更多的内容。<br>但是这里能呈现的是,知识点的快速检索以及中英文官方命名的比较等。</em></p>
<h3 id="1-XML,Xmlns"><a href="#1-XML,Xmlns" class="headerlink" title="1. XML,Xmlns"></a>1. XML,Xmlns</h3><p>XML(Extensible Markup Language/可扩展标记语言),标准通用标记语言的子集,是一种用于标记电子文件使其具有结构性的标记语言。</p>
<p>Xmlns(XML Namespaces的缩写)是一个属性,是XML(标准通用标记语言的子集)命名空间。作用是赋予命名空间一个唯一的名称。<br>XML 命名空间属性被放置于元素的开始标签之中,并使用以下的语法:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">xmlns:namespace-prefix="namespaceURI"</span><br></pre></td></tr></table></figure></p>
<p>当命名空间被定义在元素的开始标签中时,所有带有相同前缀的子元素都会与同一个命名空间相关联。</p>
<h3 id="2-URI-parts-and-components"><a href="#2-URI-parts-and-components" class="headerlink" title="2. URI parts and components"></a>2. URI parts and components</h3><p>An URI string is composed of 8 components and 5 parts:</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></pre></td><td class="code"><pre><span class="line">foo://example.com:8042/over/there?name=ferret#nose</span><br><span class="line"> \_/ \______________/\_________/ \_________/ \__/</span><br><span class="line"> | | | | |</span><br><span class="line">scheme authority path query fragment</span><br><span class="line"> | _____________________|__</span><br><span class="line"> / \ / \</span><br><span class="line"> urn:example:animal:ferret:nose</span><br></pre></td></tr></table></figure>
<p>The URI authority part in itself can be composed of up to 3 parts:</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">john:[email protected]:8042</span><br><span class="line">\______/ \_________/ \__/</span><br><span class="line"> | | |</span><br><span class="line">userinfo host port</span><br></pre></td></tr></table></figure>
<p>The userinfo part is composed of the user and the pass components:</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">captain:future</span><br><span class="line">\_____/ \____/</span><br><span class="line"> | |</span><br><span class="line"> user pass</span><br></pre></td></tr></table></figure>
<blockquote>
<p><code>URI</code>:Uniform Resource Identifier(统一资源标识符)<br><code>URL</code>:Uniform Resource Locator(统一资源定位符)<br><code>URN</code>:Uniform Resource Name(统一资源名称)<br><code>URL</code>和<code>URN</code>都是<code>URI</code>的子集,<a href="https://en.wikipedia.org/wiki/Uniform_Resource_Identifier#Relationship_between_URI.2C_URL.2C_and_URN" target="_blank" rel="noopener">点击了解三者关系</a>。</p>
</blockquote>
<p>其他相关:<br><code>java.net.URI</code><br><code>android.net.Uri</code><br><code>java.net.URL</code></p>
<h3 id="3-路径分隔符"><a href="#3-路径分隔符" class="headerlink" title="3. 路径分隔符"></a>3. 路径分隔符</h3><blockquote>
<p><code>Linux</code>,<code>Unix</code>,<code>URI/URL</code> 用的是<strong>斜杠</strong>(<code>"/"</code>)</p>
</blockquote>
<blockquote>
<p><code>Windows</code>用的是<strong>反斜杠</strong>(<code>"\"</code>)</p>
</blockquote>
<h3 id="4-nbsp-ReactiveX之Scheduler"><a href="#4-nbsp-ReactiveX之Scheduler" class="headerlink" title="4. ReactiveX之Scheduler"></a>4. ReactiveX之Scheduler</h3><blockquote>
<p> The <code>SubscribeOn</code> operator designates which thread the <code>Observable</code> will begin operating on, <strong>no matter at what point in the chain of operators that operator is called</strong>.<br><code>ObserveOn</code>, on the other hand, affects the thread that the <code>Observable</code> will use <strong>below</strong> where that operator appears. For this reason, you may call <code>ObserveOn</code> <strong>multiple times at various points during the chain of Observable operators</strong> in order to change on which threads certain of those operators operate.</p>
</blockquote>
<p><code>subscribeOn</code>可以放在<code>subscribe</code>之前的任意地方,指定产生数据源所在的线程(本例就是:<code>fromCallable</code>中的内容所在的线程)。<br>而<code>observeOn</code>也可以放在<code>subscribe</code>之前的任意地方,用于指定订阅、处理数据源发射的数据的线程(本例就是:<code>flatMap</code>和<code>map</code>中内容所在的线程)。<br><strong>但它的作用域是:从自己开始,到下一个<code>observeOn</code>之间</strong>。</p>
<p>例1:<br><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></pre></td><td class="code"><pre><span class="line">log("主线程:" + getThreadName());</span><br><span class="line">Flowable.fromCallable(</span><br><span class="line"> () -> {</span><br><span class="line"> log("fromCallable睡前:" + getThreadName());</span><br><span class="line"> SystemClock.sleep(1000);</span><br><span class="line"> log("fromCallable睡后:" + getThreadName());</span><br><span class="line"> return getIntData(21, 22);</span><br><span class="line"> })</span><br><span class="line"> .observeOn(Schedulers.computation())</span><br><span class="line"> .flatMap(</span><br><span class="line"> list -> {</span><br><span class="line"> log("flatMap线程:" + getThreadName());</span><br><span class="line"> return Flowable.fromIterable(list);</span><br><span class="line"> })</span><br><span class="line"> .map(</span><br><span class="line"> i -> {</span><br><span class="line"> log("map1线程:" + getThreadName());</span><br><span class="line"> return String.valueOf(i);</span><br><span class="line"> })</span><br><span class="line"> .observeOn(AndroidSchedulers.mainThread())</span><br><span class="line"> .subscribeOn(Schedulers.io())</span><br><span class="line"> .map(</span><br><span class="line"> s -> {</span><br><span class="line"> log("map2线程:" + getThreadName());</span><br><span class="line"> return "编号:" + s;</span><br><span class="line"> })</span><br><span class="line"> .observeOn(Schedulers.single())</span><br><span class="line"> .map(</span><br><span class="line"> s -> {</span><br><span class="line"> log("map3线程:" + getThreadName());</span><br><span class="line"> return "学生" + s;</span><br><span class="line"> })</span><br><span class="line"> .subscribe(</span><br><span class="line"> new Subscriber<String>() {</span><br><span class="line"> @Override</span><br><span class="line"> public void onSubscribe(Subscription s) {</span><br><span class="line"> s.request(Integer.MAX_VALUE);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> @Override</span><br><span class="line"> public void onNext(String s) {</span><br><span class="line"> log("onNext: " + s);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> @Override</span><br><span class="line"> public void onError(Throwable t) {</span><br><span class="line"> log("onError: " + t.toString());</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> @Override</span><br><span class="line"> public void onComplete() {</span><br><span class="line"> log("onComplete");</span><br><span class="line"> }</span><br><span class="line"> });</span><br></pre></td></tr></table></figure></p>
<p>输出结果:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><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">8 主线程:main</span><br><span class="line">8 fromCallable睡前:RxCachedThreadScheduler-1</span><br><span class="line">9 fromCallable睡后:RxCachedThreadScheduler-1</span><br><span class="line">9 flatMap线程:RxComputationThreadPool-2</span><br><span class="line">9 map1线程:RxComputationThreadPool-2</span><br><span class="line">9 map1线程:RxComputationThreadPool-2</span><br><span class="line">9 map2线程:main</span><br><span class="line">9 map2线程:main</span><br><span class="line">9 map3线程:RxSingleScheduler-1</span><br><span class="line">9 onNext: 学生编号:21</span><br><span class="line">9 map3线程:RxSingleScheduler-1</span><br><span class="line">9 onNext: 学生编号:22</span><br><span class="line">9 onComplete</span><br></pre></td></tr></table></figure>
<p>例2,就不用flatMap了,看的方便点:<br><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></pre></td><td class="code"><pre><span class="line">log("主线程:" + getThreadName());</span><br><span class="line">Flowable.fromCallable(</span><br><span class="line"> () -> {</span><br><span class="line"> log("fromCallable睡前:" + getThreadName());</span><br><span class="line"> SystemClock.sleep(1000);</span><br><span class="line"> log("fromCallable睡后:" + getThreadName());</span><br><span class="line"> return getIntData(21, 22);</span><br><span class="line"> })</span><br><span class="line"> .map(</span><br><span class="line"> i -> {</span><br><span class="line"> log("map1线程:" + getThreadName());</span><br><span class="line"> return String.valueOf(i);</span><br><span class="line"> })</span><br><span class="line"> .map(</span><br><span class="line"> s -> {</span><br><span class="line"> log("map2线程:" + getThreadName());</span><br><span class="line"> return "编号:" + s;</span><br><span class="line"> })</span><br><span class="line"> .observeOn(Schedulers.computation())</span><br><span class="line"> .map(</span><br><span class="line"> s -> {</span><br><span class="line"> log("map3线程:" + getThreadName());</span><br><span class="line"> return "学生" + s;</span><br><span class="line"> })</span><br><span class="line"> .subscribeOn(Schedulers.io())</span><br><span class="line"> .subscribe(</span><br><span class="line"> new Subscriber<String>() {</span><br><span class="line"> @Override</span><br><span class="line"> public void onSubscribe(Subscription s) {</span><br><span class="line"> s.request(Integer.MAX_VALUE);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> @Override</span><br><span class="line"> public void onNext(String s) {</span><br><span class="line"> log("onNext: " + s);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> @Override</span><br><span class="line"> public void onError(Throwable t) {</span><br><span class="line"> log("onError: " + t.toString());</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> @Override</span><br><span class="line"> public void onComplete() {</span><br><span class="line"> log("onComplete");</span><br><span class="line"> }</span><br><span class="line"> });</span><br></pre></td></tr></table></figure></p>
<p>输出结果:<br><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">27 主线程:main</span><br><span class="line">27 fromCallable睡前:RxCachedThreadScheduler-2</span><br><span class="line">28 fromCallable睡后:RxCachedThreadScheduler-2</span><br><span class="line">28 map1线程:RxCachedThreadScheduler-2</span><br><span class="line">28 map2线程:RxCachedThreadScheduler-2</span><br><span class="line">28 map3线程:RxComputationThreadPool-2</span><br><span class="line">28 onNext: 学生编号:[21, 22]</span><br><span class="line">28 onComplete</span><br></pre></td></tr></table></figure></p>
<p>例3:<br><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></pre></td><td class="code"><pre><span class="line">log("主线程:" + getThreadName());</span><br><span class="line">Flowable.fromCallable(</span><br><span class="line"> () -> {</span><br><span class="line"> log("fromCallable睡前:" + getThreadName());</span><br><span class="line"> SystemClock.sleep(1000);</span><br><span class="line"> log("fromCallable睡后:" + getThreadName());</span><br><span class="line"> return getIntData(21, 22);</span><br><span class="line"> })</span><br><span class="line"> .subscribeOn(Schedulers.computation())</span><br><span class="line"> .map(</span><br><span class="line"> i -> {</span><br><span class="line"> log("map1线程:" + getThreadName());</span><br><span class="line"> return String.valueOf(i);</span><br><span class="line"> })</span><br><span class="line"> .map(</span><br><span class="line"> s -> {</span><br><span class="line"> log("map2线程:" + getThreadName());</span><br><span class="line"> return "编号:" + s;</span><br><span class="line"> })</span><br><span class="line"> .observeOn(Schedulers.io())</span><br><span class="line"> .map(</span><br><span class="line"> s -> {</span><br><span class="line"> log("map3线程:" + getThreadName());</span><br><span class="line"> return "学生" + s;</span><br><span class="line"> })</span><br><span class="line"> .subscribeOn(Schedulers.computation())</span><br><span class="line"> .subscribe(</span><br><span class="line"> new Subscriber<String>() {</span><br><span class="line"> @Override</span><br><span class="line"> public void onSubscribe(Subscription s) {</span><br><span class="line"> s.request(Integer.MAX_VALUE);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> @Override</span><br><span class="line"> public void onNext(String s) {</span><br><span class="line"> log("onNext: " + s);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> @Override</span><br><span class="line"> public void onError(Throwable t) {</span><br><span class="line"> log("onError: " + t.toString());</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> @Override</span><br><span class="line"> public void onComplete() {</span><br><span class="line"> log("onComplete");</span><br><span class="line"> }</span><br><span class="line"> });</span><br></pre></td></tr></table></figure></p>
<p>输出:<br><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">32 主线程:main</span><br><span class="line">32 fromCallable睡前:RxComputationThreadPool-2</span><br><span class="line">33 fromCallable睡后:RxComputationThreadPool-2</span><br><span class="line">33 map1线程:RxComputationThreadPool-2</span><br><span class="line">36 map2线程:RxComputationThreadPool-2</span><br><span class="line">33 map3线程:RxCachedThreadScheduler-1</span><br><span class="line">33 onNext: 学生编号:[21, 22]</span><br><span class="line">33 onComplete</span><br></pre></td></tr></table></figure></p>
<p>三个例子的结论已经很明显:</p>
<blockquote>
<ol>
<li><code>observeOn</code>可以放在<code>subscribe</code>之前任意地方,但它的作用域是从自己开始到下一个<code>observeOn</code>截止,<strong>它影响不了该方法之前的线程</strong>。<br>也就是说,比如例3,<code>fromCallable</code>的内容发生在<code>Schedulers.computation()</code>线程中,并且<code>map3</code>之前并没有<code>observeOn</code>,<br>所以<code>map1</code>,<code>map2</code>的线程就与<code>fromCallable</code>的线程相同。</li>
<li><code>subscribeOn</code>可以放在<code>subscribe</code>之前任意地方,但它的作用域也是<code>subscribe</code>之前任意地方,<br><strong>也就是说无论在哪里指定<code>subscribeOn</code>,都可以确定数据源所在线程。</strong></li>
<li>如果有多个<code>subscribeOn</code>怎么办?<br>例3已经回答了,那就是:<strong>只认第一个,忽略后面所有!</strong></li>
</ol>
</blockquote>
<h3 id="5-nbsp-RxRoom的几个坑:"><a href="#5-nbsp-RxRoom的几个坑:" class="headerlink" title="5. RxRoom的几个坑:"></a>5. RxRoom的几个坑:</h3><p>直接使用<code>Flowable<List<T>></code>后:<br><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">@Query("SELECT * FROM history_user")</span><br><span class="line">Flowable<List<HistoryUser>> loadHistoryUsers();</span><br></pre></td></tr></table></figure></p>
<p>使用后就不结束了,就是说不走<code>onComplte</code>了。。。</p>
<p>原因是,直接使用<code>Flowable</code>后,当你要查询的数据更新后,你就会接收到通知:</p>
<blockquote>
<p>Every time the user data is updated, the Flowable object will emit automatically,<br>allowing you to update the UI based on the latest data.</p>
</blockquote>
<p>这还是已经躲过一个坑之后了,下面继续:<br><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">@Query("SELECT * FROM validity_time2 WHERE feature = :feature")</span><br><span class="line">Flowable<ValidityTime2> getValidityTime2(int feature);</span><br></pre></td></tr></table></figure></p>
<p>如果表里没有任何数据,那么既接收不到<code>onNext</code>,也接收不到<code>onError</code>,更别提<code>onComplete</code>了。</p>
<p><strong>解决办法:</strong><br><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">@Query("SELECT * FROM validity_time2 WHERE feature = :feature")</span><br><span class="line">ValidityTime2 getValidityTime2(int feature);</span><br></pre></td></tr></table></figure></p>
<p>然后<code>Flowable.fromCallable</code>转成<code>Flowable</code>就可以了。</p>
<p>相关资料:<a href="https://medium.com/google-developers/room-rxjava-acb0cd4f3757" target="_blank" rel="noopener">资料1</a>,<a href="https://github.com/googlesamples/android-architecture-components/issues/84" target="_blank" rel="noopener">资料2</a></p>
<h3 id="6-nbsp-从Deivce-File-Explorer导出数据库的坑"><a href="#6-nbsp-从Deivce-File-Explorer导出数据库的坑" class="headerlink" title="6. 从Deivce File Explorer导出数据库的坑"></a>6. 从<code>Deivce File Explorer</code>导出数据库的坑</h3><p>一开始<code>.wal</code>文件时,直接导出<code>.db</code>文件,然后sqlite软件打开,是完全没问题。</p>
<p>但后来出现<code>.db-wal</code>后,就无法正常查看了,而且<code>.db</code>文件的永远都是4kb。</p>
<p>解决方法是:把<code>.db</code>,<code>.db-shm</code>,<code>.db-wal</code>一起导出,然后用sqlite软件打开<code>.db</code>文件,如下图所示:<br><img src="/2019/03/29/名词汇总篇/db1.png" alt="图片"> </p>
<h3 id="7-nbsp-retryWhen"><a href="#7-nbsp-retryWhen" class="headerlink" title="7. retryWhen"></a>7. retryWhen</h3><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">.retryWhen(throwableFlowable -> throwableFlowable.flatMap(</span><br><span class="line"> new Function<Throwable, Publisher<?>>() {</span><br><span class="line"> @Override</span><br><span class="line"> public Publisher<?> apply(Throwable throwable) throws Exception {</span><br><span class="line"> if (throwable instanceof TokenExpirationException) {</span><br><span class="line"> return retrieveToken();</span><br><span class="line"> }else{</span><br><span class="line"> return Flowable.error(throwable);</span><br><span class="line"> // return Flowable.just(1);</span><br><span class="line"> // throwableFlowable;</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>如果apply返回一个产生异常的Flowable,则立即停止重试操作.<br>如果apply一个不会产生异常Flowable,则会重试之前的操作.<br>如果apply中直接throwableFlowable对象,则会报<code>This processor allows only a single Subscriber</code>的错. </p>
<h3 id="8-nbsp-使用RxLifecyle时注意"><a href="#8-nbsp-使用RxLifecyle时注意" class="headerlink" title="8. 使用RxLifecyle时注意."></a>8. 使用RxLifecyle时注意.</h3><p>如果Activity注册了bindToLifecycle,当Activity关闭时,如果有Rx还在运行中,不会走<code>onError</code>,而是<code>onComplete</code>.</p>
<h3 id="9-nbsp-android-enableAapt2-false"><a href="#9-nbsp-android-enableAapt2-false" class="headerlink" title="9. android.enableAapt2=false"></a>9. <code>android.enableAapt2=false</code></h3><p>这条语句应该设置在<code>gradle.properties</code>里,用法说明:</p>
<blockquote>
<p>Android Plugin for Gradle 3.0.0之后 使用 AAPT2 改进了增量资源处理。<br>要启用 AAPT2,请将以下代码添加到您的 gradle.properties 文件中: <code>android.enableAapt2=true</code></p>
</blockquote>
<p>但是在编译时(比如使用jenkins时)出现如下提示时,会有人推荐启用上面的配置,目的是为了兼容3.0之前的Gradle:<br><code>java.util.concurrent.ExecutionException: com.android.tools.aapt2.Aapt2Exception: AAPT error: check logs for details site:stackoverflow.com</code></p>
<p>但是如果你使用了3.0后的Gralde,千万别使用这条语句,因为你会错过关于资源相关的错误提示!</p>
<p>真实场景:<br>网上下载了一张jpg图片,修改成后缀为png的图片。当时设置了<code>android.enableAapt2=false</code>,奇怪的事情发生了:<br>在<code>debug</code>环境下没任何问题,切换到<code>release</code>环境报了如下的错:<br><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">* What went wrong:</span><br><span class="line">Execution failed for task ':app:mergeReleaseResources'.</span><br><span class="line">> Error: java.util.concurrent.ExecutionException: com.android.tools.aapt2.Aapt2Exception: AAPT error: check logs for details</span><br></pre></td></tr></table></figure></p>
<p>排查后,取消设置<code>android.enableAapt2=false</code>后,给出如下提示:<br><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></pre></td><td class="code"><pre><span class="line">* What went wrong:</span><br><span class="line">Error:error: failed to read PNG signature: file does not start with PNG signature.</span><br><span class="line"></span><br><span class="line">Error:Execution failed for task ':app:mergeBaiduReleaseResources'.</span><br><span class="line">> Error: java.util.concurrent.ExecutionException: com.android.tools.aapt2.Aapt2Exception: AAPT2 error: check logs for details</span><br></pre></td></tr></table></figure></p>
<p>WHAT A FREAK ! </p>
<h3 id="10-nbsp-ExampleInstrumentedTest-一片姨妈红"><a href="#10-nbsp-ExampleInstrumentedTest-一片姨妈红" class="headerlink" title="10. ExampleInstrumentedTest 一片姨妈红"></a>10. <code>ExampleInstrumentedTest</code> 一片姨妈红</h3><p>最常规的解决方法就是一步步排查:</p>
<ul>
<li><p>相应的gradle文件下的<code>android</code>-><code>defaultConfig</code> 下有没有声明:<br><code>testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"</code><br>这条gradle默认创建的时候就有,所以一般不会有问题.</p>
</li>
<li><p>有没有<code>testCompile/testImplementation</code> <code>junit</code>,<code>androidTestCompile/androidTestImplementation</code> <code>runner</code>和<code>espresso</code><br>这条也是很好检查,然而还是没问题。<br>最后,被搞的焦头烂额时,看了<a href="https://stackoverflow.com/questions/30603487/cannot-resolve-symbol-androidjunit4" target="_blank" rel="noopener">这个答案</a>,顿时如沐春风。。。</p>
</li>
</ul>
<p>第一次知道:<code>ExampleInstrumentedTest</code>只能运行在 <strong><code>debug</code></strong> 环境之下!</p>
<h3 id="11-nbsp-EventBus-的一个小的注意点"><a href="#11-nbsp-EventBus-的一个小的注意点" class="headerlink" title="11. EventBus 的一个小的注意点"></a>11. <code>EventBus</code> 的一个小的注意点</h3><p>我们一般在<code>BaseActivity</code>的要复写如两个下方法,为了不让子类直接去操作<code>onCreate</code>方法:<br><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">@Override</span><br><span class="line">public final void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) {</span><br><span class="line"> super.onCreate(savedInstanceState, persistentState);</span><br><span class="line">}</span><br></pre></td></tr></table></figure></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">@Override</span><br><span class="line">protected final void onCreate(@Nullable Bundle savedInstanceState) {</span><br><span class="line"> super.onCreate(savedInstanceState);</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>但是当<code>EventBus</code>在<code>register</code>时,会报一个错:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">java.lang.NoClassDefFoundError: android/os/PersistableBundle</span><br></pre></td></tr></table></figure></p>
<p>解决方法:<br>取消覆写<code>onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState)</code>方法,<br>不管加不加<code>final</code>,只要覆写,就会报错。</p>
<h3 id="12-nbsp-gralde文件中的路径分隔符"><a href="#12-nbsp-gralde文件中的路径分隔符" class="headerlink" title="12. gralde文件中的路径分隔符"></a>12. <code>gralde</code>文件中的路径分隔符</h3><p>先说个场景,<code>Windows</code>系统下:</p>
<p>正式环境下的<code>jks</code>不放到于主项目中,而是放到另外一个git库中,拉取到本地。</p>
<p>里面仅有2个文件:</p>
<p><code>***.jks</code>和<code>jks.properties</code></p>
<p><code>jks.properties</code>的内容类似如下:<br><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">keyAlias=A</span><br><span class="line">keyPassword=123456</span><br><span class="line">storeFile=E:/Repository/AJKS/a.jks</span><br><span class="line">storePassword=123456</span><br></pre></td></tr></table></figure></p>
<p>然后由<code>gralde</code>去读取<code>jks.properties</code>中的数据。</p>
<p>下一步,该如何知道<code>jks.properties</code>放到哪?</p>
<p> <code>local.properties</code> 中设置了:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">jksPropertiesDir=E\:\\Repository\\AJKS\\a.properties</span><br></pre></td></tr></table></figure></p>
<p>好了,问题出现了:<br><code>storeFile</code>用的斜杠,而<code>jksPropertiesDir</code>用的是反斜杠,并且转义过。</p>
<p>思路,首先,确定的是:</p>
<p>冒号(<code>:</code>)和反斜杠(<code>\</code>)在<code>groovy</code>语法中需要转义,而斜杠(<code>/</code>)不需要。</p>
<p>所以jksPropertiesDir真正被读取的内容是:<code>E:\Repository\AJKS\a.properties</code>,这个没有任何异议。</p>
<p>为了验证<code>storeFile</code>的写法,修改<code>jksPropertiesDir</code>为<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">jksPropertiesDir=E\:/Repository/AJKS/a.properties</span><br></pre></td></tr></table></figure></p>
<p>结果编译通过!</p>
<h4 id="事实证明Windows下的gralde即可以读取反斜杠-分割的路径,也可以读取斜杠-分割的路径"><a href="#事实证明Windows下的gralde即可以读取反斜杠-分割的路径,也可以读取斜杠-分割的路径" class="headerlink" title="事实证明Windows下的gralde即可以读取反斜杠(\)分割的路径,也可以读取斜杠(/)分割的路径"></a>事实证明<code>Windows</code>下的<code>gralde</code>即可以读取反斜杠(<code>\</code>)分割的路径,也可以读取斜杠(<code>/</code>)分割的路径</h4><p>同样,如果<code>storeFile</code>如果想换成反斜杠(<code>\</code>)的写法,应该这样写:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">storeFile=E\:\\Repository\\AJKS\\a.jks</span><br></pre></td></tr></table></figure></p>
<p>最后,列个比较结果:</p>
<table>
<thead>
<tr>
<th>名称</th>
<th>写法</th>
<th>最终目标结果</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>storeFile</code></td>
<td><code>E\:\\Repository\\AJKS\\a.jks</code></td>
<td><code>E:\Repository\AJKS\a.jks</code></td>
</tr>
<tr>
<td><code>storeFile</code></td>
<td><code>E:/Repository/AJKS/a.jks</code></td>
<td><code>E:/Repository/AJKS/a.jks</code></td>
</tr>
<tr>
<td><code>jksPropertiesDir</code></td>
<td><code>E\:\\Repository\\AJKS\\a.properties</code></td>
<td><code>E:\Repository\AJKS\a.properties</code></td>
</tr>
<tr>
<td><code>jksPropertiesDir</code></td>
<td><code>E\:/Repository/AJKS/a.properties</code></td>
<td><code>E:/Repository/AJKS/a.properties</code></td>
</tr>
</tbody>
</table>
<p><strong>注:上面都验证过是完全正确的写法,特别注意下冒号(<code>:</code>),什么时候要将转义,什么时候不要。<br><code>storeFile</code>的第二种写法不要转义,而<code>jksPropertiesDir</code>的第二种写法要转义。<br>前者存在于系统指定路径下的<code>jks.properties</code>中,后者是存在于项目的<code>local.properties</code>中。</strong></p>
<h3 id="13-nbsp-动态设置是否使用Dagger2(AndroidInjection的方式)"><a href="#13-nbsp-动态设置是否使用Dagger2(AndroidInjection的方式)" class="headerlink" title="13. 动态设置是否使用Dagger2(AndroidInjection的方式)"></a>13. 动态设置是否使用Dagger2(AndroidInjection的方式)</h3><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">class BaseDaggerAppCompatActivity extends RxAppCompatActivity</span><br><span class="line"> implements HasFragmentInjector, HasSupportFragmentInjector {</span><br><span class="line"></span><br><span class="line"> @Inject DispatchingAndroidInjector<Fragment> supportFragmentInjector;</span><br><span class="line"></span><br><span class="line"> @Inject DispatchingAndroidInjector<android.app.Fragment> frameworkFragmentInjector;</span><br><span class="line"></span><br><span class="line"> @Override</span><br><span class="line"> protected void onCreate(@Nullable Bundle savedInstanceState) {</span><br><span class="line"> AndroidInjection.inject(this);</span><br><span class="line"> super.onCreate(savedInstanceState);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> @Override</span><br><span class="line"> public AndroidInjector<Fragment> supportFragmentInjector() {</span><br><span class="line"> return supportFragmentInjector;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> @Override</span><br><span class="line"> public AndroidInjector<android.app.Fragment> fragmentInjector() {</span><br><span class="line"> return frameworkFragmentInjector;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<figure class="highlight 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">@Module</span><br><span class="line">public abstract class LoginBindingModule {</span><br><span class="line"></span><br><span class="line"> @ActivityScoped</span><br><span class="line"> @ContributesAndroidInjector(modules = LoginActivityModule.class)</span><br><span class="line"> abstract LoginActivity loginActivity();</span><br><span class="line"></span><br><span class="line">}</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></pre></td><td class="code"><pre><span class="line">@Module</span><br><span class="line">public abstract class LoginActivityModule {</span><br><span class="line"></span><br><span class="line"> @ActivityScoped</span><br><span class="line"> @Binds</span><br><span class="line"> abstract LoginActivityContract.Presenter loginActivityContractPresenter(LoginActivityPresenter homePresenter);</span><br><span class="line"></span><br><span class="line">}</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></pre></td><td class="code"><pre><span class="line">public abstract class BaseActivity<T extends IPresenter> extends BaseDaggerAppCompatActivity implements IView {</span><br><span class="line"></span><br><span class="line"> @Inject protected T mPresenter;</span><br></pre></td></tr></table></figure>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">public class LoginActivity extends BaseActivity<LoginActivityContract.Presenter> implements LoginActivityContract.View {</span><br></pre></td></tr></table></figure>
<p>场景与结果:</p>
<p><strong>1.</strong> 在<code>BaseDaggerAppCompatActivity</code>里去掉<code>AndroidInjection.inject(this);</code>,并且<code>LoginBindingModule</code>里去掉对<code>LoginActivity</code>的构造。<br><strong>则即使在代码里使用<code>@Inject</code>声明成员变量,该注解都是没有任何作用的。</strong><br>(这是我们需要,<code>BaseActivity</code>当做普通的<strong>不包含Dagger功能</strong>的Activity使用。<br>另外该情况不管<code>LoginActivityModule</code>里提不提供Presenter都是没有任何影响的)</p>
<p><strong>2.</strong> 在<code>BaseDaggerAppCompatActivity</code>里去掉<code>AndroidInjection.inject(this)</code>,并且<code>LoginBindingModule</code>正常添加对<code>LoginActivity</code>的构造。<br><code>LoginActivityModule</code>里提供Presenter,<strong>编译运行都没问题,只是Presenter为空</strong>。<br><code>LoginActivityModule</code>里不提供Presenter,编译报了最常见的错:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">LoginActivityContract.Presenter cannot be provided without an @Provides- or @Produces-annotated method.</span><br></pre></td></tr></table></figure></p>
<p>对于上述情况额外说一下,如果<code>LoginActivity</code>不指定<code>LoginActivityContract.Presenter</code>这个泛型,而是直接继承<code>BaseActivity</code>,则:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">IPresenter cannot be provided without an @Provides- or @Produces-annotated method.</span><br></pre></td></tr></table></figure></p>
<p>很显然,对于<code>BaseActivity<T extends IPresenter></code>,上面并没指定<code>T</code>,默认就使用<code>IPresenter</code>类型。<br>所以对于这个例子,即使<code>LoginActivityModule</code>提供了<code>LoginActivityContract.Presenter</code>,而<code>LoginActivity</code>没指定<code><LoginActivityContract.Presenter></code>泛型,<strong>还是会报如上相同的错</strong>。</p>
<p><strong>3.</strong> 在<code>BaseDaggerAppCompatActivity</code>里加上<code>AndroidInjection.inject(this)</code>,并且<code>LoginBindingModule</code>里去掉对<code>LoginActivity</code>的构造。<br>不管<code>LoginActivityModule</code>里提不提供Presenter,结果都是<strong>编译期没问题,运行时在处<code>AndroidInjection.inject(this);</code>处报错</strong>:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Caused by: java.lang.IllegalArgumentException: No injector factory bound for Class<LoginActivity></span><br></pre></td></tr></table></figure></p>
<p><strong>4.</strong> 在<code>BaseDaggerAppCompatActivity</code>里加上<code>AndroidInjection.inject(this)</code>,并且<code>LoginBindingModule</code>正常添加对<code>LoginActivity</code>的构造。<br>这个是我们最常见的情况。<br><code>LoginActivityModule</code>里提供Presenter,一切正常。<br><code>LoginActivityModule</code>里不提供Presenter,同第2点同场景的错一致。</p>
<p><strong>通过对以上比较,可以看出</strong>:</p>
<p><strong>1.</strong> <code>LoginBindingModule</code>里使用<code>ContributesAndroidInjector</code>进行构造的操作发生在<strong>编译期</strong>。<br>如果一个Activity使用了<code>ContributesAndroidInjector</code>进行构造,则其所依赖的对象在编译时期必须提供,而且是具体的类型。<br>而<code>AndroidInjection.inject(this)</code>则发生在<strong>运行期</strong>,决定了某个Activity是否要注入使用提供的对象,与编译器的检查机制没关系。</p>
<p><strong>2.</strong> 想无痕的使用不包含<code>Dagger</code>的<code>Activity</code>,只能使用第一种情况。这种不需要在<code>LoginBindingModule</code>声明构造<code>LoginActivity</code>,更不需要提供<code>LoginActivityModule</code>。<br> <strong>使用<code>@BindsOptionalOf</code>没用!</strong>,最终还是需要在<code>LoginBindingModule</code>里构造<code>LoginActivity</code>,并且还需要提供<code>LoginActivityModule</code>,只是在该Mdoule里声明了<code>@BindsOptionalOf</code>而已,还要在<code>BaseActivity</code>里搭配<code>Optional</code>使用,还会影响其他Activity<br>(一旦使用了<code>@Inject protected Optional<T> mPresenter;</code>,所有的Activity的Moudle都提供<code>@BindsOptionalOf</code>的Presenter。如果只是<code>LoginActivityModule</code>提供了,而其他Activity的Moudle不提供,则会在出现:<br><code>Optional<HomeContract.Presenter> cannot be provided without an @Inject constructor or from an @Provides- or @Produces-annotated method.</code>这样的错误,<br>因为HomeActivityMoudle把Optional<HomeContract.Presenter>当成一个类型了。)简直灾难啊,有没有!!!<br>以后可以忘记<code>Dagger</code>有<code>@BindsOptionalOf</code>这个操作符了。<br> 在<code>BaseActivity</code>使用<code>@Inject @Nullable protected T mPresenter;</code>更是没意义。也就是说<code>@Nullbale</code><strong>没有任何作用</strong>!</p>
</div>
<div class="article-info article-info-index">
<div class="article-tag tagcloud">
<i class="icon-price-tags icon"></i>
<ul class="article-tag-list">
<li class="article-tag-list-item">
<a href="javascript:void(0)" class="js-tag article-tag-list-link color2">Casual</a>
</li>
</ul>
</div>
<p class="article-more-link">
<a class="article-more-a" href="/2019/03/29/名词汇总篇/">展开全文 >></a>
</p>
<div class="clearfix"></div>
</div>
</div>
</article>
<aside class="wrap-side-operation">
<div class="mod-side-operation">
<div class="jump-container" id="js-jump-container" style="display:none;">
<a href="javascript:void(0)" class="mod-side-operation__jump-to-top">
<i class="icon-font icon-back"></i>
</a>
<div id="js-jump-plan-container" class="jump-plan-container" style="top: -11px;">
<i class="icon-font icon-plane jump-plane"></i>
</div>
</div>
</div>
</aside>
<article id="post-未收天子河湟地,不拟回头望故乡" class="article article-type-post article-index" itemscope="" itemprop="blogPost">
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2019/03/28/未收天子河湟地,不拟回头望故乡/">未收天子河湟地,不拟回头望故乡</a>
</h1>
<a href="/2019/03/28/未收天子河湟地,不拟回头望故乡/" class="archive-article-date">
<time datetime="2019-03-28T13:33:35.000Z" itemprop="datePublished"><i class="icon-calendar icon"></i>2019-03-28</time>
</a>
</header>
<div class="article-entry" itemprop="articleBody">
<p><img src="/2019/03/28/未收天子河湟地,不拟回头望故乡/crusades.jpeg" alt="图片"></p>