-
Notifications
You must be signed in to change notification settings - Fork 0
/
local-search.xml
189 lines (87 loc) · 169 KB
/
local-search.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>我的路由器之旅</title>
<link href="/2021/10/15/%E6%88%91%E7%9A%84%E8%B7%AF%E7%94%B1%E5%99%A8%E4%B9%8B%E6%97%85/"/>
<url>/2021/10/15/%E6%88%91%E7%9A%84%E8%B7%AF%E7%94%B1%E5%99%A8%E4%B9%8B%E6%97%85/</url>
<content type="html"><![CDATA[<p>水电网构成生活基本资源。私以为可以忍受暂时停水,但是断网是每一刻都浑身难受,特别是身处互联网时代。我对网络稳定,环境,延迟和速度都有着自我的一定追求。</p><h3 id="FAST-FW306R"><a href="#FAST-FW306R" class="headerlink" title="FAST FW306R"></a>FAST FW306R</h3><p>万毒之源,老家搬家的最早服役路由器,老家宽带为 100M 电信 FTTH,主路由也是 FAST 某忘记型号,四台 FW306R 作为 AP,全 100M 端口,无线仅 2.4G,802.11n 协议,近距离一般设备的连接协议速度为 72/144Mbps,实际能勉强覆盖七八十平米的一层楼。表面类肤材质设计,当年看起来觉得还不错。由于广东电信 100M 存在虚标,分配 100M 实际能跑 150M,因此路由器成为了瓶颈,把其中三台退役了,尚有一台在三楼服役中(建筑商偷工减料,到三楼面板仅为四芯网线)。现今某宝 20 包邮。</p><p><img src="https://cdn.jsdelivr.net/gh/zwczwc/res/2021/RouterJouney/FW306R.png"></p><h3 id="极路由-1S"><a href="#极路由-1S" class="headerlink" title="极路由 1S"></a>极路由 1S</h3><p>本科校园网用锐捷认证,大一用笔记本连接认证后分享热点,严重降低笔记本使用寿命。后来 100 块入手极路由 1S,100M 有线 + 2.4G 无线,应付辣鸡 4M 校园网和寝室的单人床位空间绰绰有余,陪伴度过了 4 年本科,爷青回。现在极路由公司已倒闭。</p><p><img src="https://cdn.jsdelivr.net/gh/zwczwc/res/2021/RouterJouney/Gee1S.png"></p><h3 id="MERCURY-D191G"><a href="#MERCURY-D191G" class="headerlink" title="MERCURY D191G"></a>MERCURY D191G</h3><p>MERCURY 和前面的 FAST 同为 TP-LINK 子公司,出售换壳减配性价比版本。有线 1000M 端口 + 无线 WIFI5,理论 1900M 速率,但是现实 3 天线的网卡少之又少,一般是双天线走 AC 协议 867Mbps,因此 1900M 纯属装逼用。从 PDD 1xx 元入手,性价比可以。外表六边形设计笨重占地方,当初被人各种嫌弃,网线插入端口卡手,现在回过头来想有点后悔购买。</p><p><img src="https://cdn.jsdelivr.net/gh/zwczwc/res/2021/RouterJouney/D191G.png"></p><h3 id="MERCURY-D196G"><a href="#MERCURY-D196G" class="headerlink" title="MERCURY D196G"></a>MERCURY D196G</h3><p>D191G 的换壳版本,方正些许,没那么占地方。多了一个端口,价格基本不变,一口气从 PDD 购入两台在老家使用,现在一台作为主路由负责拨号和 NAT 转换,另一台在自己房间当 AP 用。</p><p><img src="https://cdn.jsdelivr.net/gh/zwczwc/res/2021/RouterJouney/D196G.png"></p><h3 id="PHICOMM-N1"><a href="#PHICOMM-N1" class="headerlink" title="PHICOMM N1"></a>PHICOMM N1</h3><p>年轻人的第一台软路由(矿渣),刷入 OpenWrt 后在老家作为旁路由使用。采用 4 核 A53 主频 1.5Ghz 的 CPU,28nm 制程,跑加密解密算法足够老家的小水管使用,UU 加速器也包含在 OpenWrt 的插件列表,因此满足了我的外网需求。省电,体积算是小巧,固件稳定,在 PDD 花的这 1xx 元挺值。</p><p><img src="https://cdn.jsdelivr.net/gh/zwczwc/res/2021/RouterJouney/N1.png"></p><h3 id="TP-LINK-AX5400"><a href="#TP-LINK-AX5400" class="headerlink" title="TP-LINK AX5400"></a>TP-LINK AX5400</h3><p>有感于香港的路由器价格之昂贵,从京东 3xx 元购入包邮直送香港。年轻人的第一台 WIFI6 路由器(误),支持 WiFi6 的 160Mhz 带宽,迎战未来。外表设计依旧是祖传的几万条天线,其实对我住的鸟笼屋一条就够了,实测 PCCW 1000M 宽带有线跑满千兆,无线跑 SpeedTest 峰值 800M左右,测试设备为 Samsung Note 20 Ultra,总的使用体验还是满意的。现在吃灰中,预测未来当 AP 使用。</p><p><img src="https://cdn.jsdelivr.net/gh/zwczwc/res/2021/RouterJouney/AX5400.png"></p><h3 id="ASUS-RT-AX86U"><a href="#ASUS-RT-AX86U" class="headerlink" title="ASUS RT-AX86U"></a>ASUS RT-AX86U</h3><p>现在主力路由器,某东 1499 入手,刷梅林和开 WiFi Boost 使用,以一机之力完成路由,AP,谷歌学术,外服游戏加速所有功能,而且无线改了澳大利亚地区,从原理上提升信号质量,摆放中央位置,能实现全屋的 5G 信号满格。CPU 4 核 A53 主频 1.8Ghz,满足现在 300M 的宽带,有个 2.5G 端口,这才是真正的战未来。(什么时候能加上光口,把 ISP 的辣鸡光猫退役了就更好了)缺点是发热量略大,在炎热的广东常年 CPU 温度接近70度,28nm 制程有点拉跨。</p><p><img src="https://cdn.jsdelivr.net/gh/zwczwc/res/2021/RouterJouney/AX86U.png"></p>]]></content>
</entry>
<entry>
<title>图片视频的 EXIF 编辑管理</title>
<link href="/2021/09/12/%E5%9B%BE%E7%89%87%E8%A7%86%E9%A2%91%E7%9A%84%20EXIF%20%E7%BC%96%E8%BE%91%E7%AE%A1%E7%90%86/"/>
<url>/2021/09/12/%E5%9B%BE%E7%89%87%E8%A7%86%E9%A2%91%E7%9A%84%20EXIF%20%E7%BC%96%E8%BE%91%E7%AE%A1%E7%90%86/</url>
<content type="html"><![CDATA[<p>整理旧手机的回忆杀相册,复制到新手机时发现日期错乱,需要修改照片的修改时间为 EXIF 这样手机相册才会根据 EXIF 信息显示正确照片时间线。</p><h3 id="图片"><a href="#图片" class="headerlink" title="图片"></a>图片</h3><p>Windows 默认资源管理器能改 date,但是不能精确到时分秒,因此需要第三方手段。</p><h4 id="Exif-date-editor"><a href="#Exif-date-editor" class="headerlink" title="Exif-date-editor"></a>Exif-date-editor</h4><p>用这个 repository,按需修改 datetime guess 的参数,可以猜出并修改对应的 EXIF date 或者手动修改。但是当图片体积过大时,有可能会失效。适用于 5MB 以下相片。</p><p><a href="https://github.com/gzzi/exif-date-editor">Exif-date-editor</a></p><h4 id="ACDSee"><a href="#ACDSee" class="headerlink" title="ACDSee"></a>ACDSee</h4><p>ACDSee 的修改非常精准。选中相片后在<code>批量</code>的下拉菜单中选择<code>调整时间标签</code>,要更改的日期为 <code>EXIF 日期和时间</code>,新时间标签为<code>上次修改日期与时间</code>。注意图片实质格式为 .jpg 才有效,因为 .png 是不带取 EXIF 信息的。有些图片后缀虽为 .jpg,但实质格式为 png,因此需要先转 png 为 jpg,ACDSee 也可以完成这批量转换操作。</p><p><img src="https://cdn.jsdelivr.net/gh/zwczwc/res/2021/GalleryEXIF/acdsee.png"></p><h3 id="视频"><a href="#视频" class="headerlink" title="视频"></a>视频</h3><p>直接 Windows 右键属性编辑吧</p>]]></content>
</entry>
<entry>
<title>关于北京 2008 的回想</title>
<link href="/2021/06/30/%E5%85%B3%E4%BA%8E%E5%8C%97%E4%BA%AC%202008%20%E7%9A%84%E5%9B%9E%E6%83%B3/"/>
<url>/2021/06/30/%E5%85%B3%E4%BA%8E%E5%8C%97%E4%BA%AC%202008%20%E7%9A%84%E5%9B%9E%E6%83%B3/</url>
<content type="html"><![CDATA[<p>人总会怀念过去</p><p>深夜整理网抑云,瞥见 <code>张惠妹,孙楠 - 永远的朋友(国).mp3</code> ,是2008年北京奥运会的歌曲,遥远而又熟悉的旋律响起,不禁花点时间再上网回顾。作曲是 Giorgio Moroder,1988年汉城奥运会的经典曲目 <code>Hand in Hand</code> 也是出自他手。孙楠和张惠妹的演绎恰如其分。MV 囊括了体育和中华文化的元素,也有 <code>同一个世界同一个梦想</code> 的点睛之笔。因此,我持与很多人相同的观点,认为这首比 <code>我和你</code> 更适合作为奥运会主题歌,既然是象征着奋发体育精神的奥运会,主题曲就应该是激扬豪迈的。(虽然此曲也并不是那么激情豪迈)</p><script src="https://cdn.jsdelivr.net/npm/dplayer@1/dist/DPlayer.min.js"></script><div id="mmedia-WPuncUXXatajqrNW"></div><script> var WPuncUXXatajqrNW_options = JSON.parse('{\"video\":{\"url\":\"https://raw.githubusercontent.com/zwczwc/res/master/video/Forever%20Friends.mp4\"}}'); WPuncUXXatajqrNW_options.container = document.getElementById("mmedia-WPuncUXXatajqrNW"); const dp_WPuncUXXatajqrNW = new DPlayer(WPuncUXXatajqrNW_options); </script><p>说起当年的奥运歌曲,可能更多人会想起那时在电视上无限循环播放的 <code>北京欢迎你</code> 。简单好听的旋律汇聚了当时两岸三地的明星巨星。 虽然不知道还有多少现在还活在大众视线里,但是起码那时,起码在 MV 里,感受到大家同心的真诚祝福献唱。更不用说之后举世瞩目的开幕式和各个奥运赛场的精彩比赛传奇。特别喜欢 04:31 开始的间奏, 现代与传统的碰撞却完美交融,这个地方已经做好准备拥抱希望与未来。08年自己还在读小学什么都不懂,而如今只能通过视频回想,以现在的自己再次追溯回忆,在电脑屏幕前空自流泪,只是很怀念当时的氛围,多么想回去08年再一次亲身心潮澎湃地感受。</p><script src="https://cdn.jsdelivr.net/npm/dplayer@1/dist/DPlayer.min.js"></script><div id="mmedia-DinATjzWqyLhCUno"></div><script> var DinATjzWqyLhCUno_options = JSON.parse('{\"video\":{\"url\":\"https://raw.githubusercontent.com/zwczwc/res/master/video/Beijing%20Welcomes%20You.mp4\"}}'); DinATjzWqyLhCUno_options.container = document.getElementById("mmedia-DinATjzWqyLhCUno"); const dp_DinATjzWqyLhCUno = new DPlayer(DinATjzWqyLhCUno_options); </script><p>摘抄一下评论区</p><blockquote><p>那时候电视还是家庭主要娱乐方式</p><p>那时候这些明星风华正茂</p><p>那时候国家世界瞩目</p><p>那时候手机还是按键</p><p>那时候电脑还是箱子</p><p>那时候…</p><p>那时候现在看起来不算好</p><p>但是我怀念那时候</p><p>不为别的</p><p>那时候我正年少</p></blockquote><blockquote><p>现在我们确实比当初强太多了,但是各种解构主义,消费主义,泛娱乐化的出现,归根结底是我们没有找到一个方向</p><p>总结来说,以前就是看着他们吃香的喝辣的,我们想着:会有的,以后都会有的。现在就是我们也过着差不多的生活,没人再想活的那么苟且,却找不回整个民族的底色</p><p>真的要回去吗?我们的选择当然是不回头,现实容不下我们回头,历史发展的规律也不会因为怀念就可以更改</p></blockquote><p>续听 1988 年汉城奥运会的 <code>Hand in Hand</code>,波澜壮阔的经典铭刻至今。我想奥运会的意义在于团结凝聚,把世界连成一起。而这个不仅仅是对于中国,更是对于这个星球上的全人类。当下世界分裂对抗,社会浮躁,东京奥运会举办在即,疫情在之蒙蔽上不稳定的因素,不禁让人陷入迷茫……</p><script src="https://cdn.jsdelivr.net/npm/dplayer@1/dist/DPlayer.min.js"></script><div id="mmedia-yjhQzAXaCRdxLoXt"></div><script> var yjhQzAXaCRdxLoXt_options = JSON.parse('{\"video\":{\"url\":\"https://raw.githubusercontent.com/zwczwc/res/master/video/Hand%20in%20Hand.mp4\"}}'); yjhQzAXaCRdxLoXt_options.container = document.getElementById("mmedia-yjhQzAXaCRdxLoXt"); const dp_yjhQzAXaCRdxLoXt = new DPlayer(yjhQzAXaCRdxLoXt_options); </script>]]></content>
</entry>
<entry>
<title>简易搭建 Django 后台做 Python 爬虫的过程问题</title>
<link href="/2020/02/23/%E7%AE%80%E6%98%93%E6%90%AD%E5%BB%BA%20Django%20%E5%90%8E%E5%8F%B0%E5%81%9A%20Python%20%E7%88%AC%E8%99%AB%E7%9A%84%E8%BF%87%E7%A8%8B%E9%97%AE%E9%A2%98/"/>
<url>/2020/02/23/%E7%AE%80%E6%98%93%E6%90%AD%E5%BB%BA%20Django%20%E5%90%8E%E5%8F%B0%E5%81%9A%20Python%20%E7%88%AC%E8%99%AB%E7%9A%84%E8%BF%87%E7%A8%8B%E9%97%AE%E9%A2%98/</url>
<content type="html"><![CDATA[<h4 id="Notepad-配置-Python"><a href="#Notepad-配置-Python" class="headerlink" title="Notepad++ 配置 Python"></a>Notepad++ 配置 Python</h4><p><a href="https://www.cnblogs.com/xier/p/10658087.html">https://www.cnblogs.com/xier/p/10658087.html</a></p><h4 id="Beautiful-soup-文档"><a href="#Beautiful-soup-文档" class="headerlink" title="Beautiful soup 文档"></a>Beautiful soup 文档</h4><p><a href="https://beautifulsoup.readthedocs.io/zh_CN/v4.4.0/#">Beautiful Soup 4.4.0 文档</a></p><h4 id="写-csv"><a href="#写-csv" class="headerlink" title="写 csv"></a>写 csv</h4><p><a href="https://blog.csdn.net/lbj1260200629/article/details/89600055">Python 将数据写入CSV文件</a></p><h4 id="写-csv-乱码"><a href="#写-csv-乱码" class="headerlink" title="写 csv 乱码"></a>写 csv 乱码</h4><p><a href="https://www.cnblogs.com/adampei-bobo/p/8615978.html">python3-csv写入中文乱码</a></p><h4 id="百度搜索-url-参数解释"><a href="#百度搜索-url-参数解释" class="headerlink" title="百度搜索 url 参数解释"></a>百度搜索 url 参数解释</h4><p><a href="https://www.cnblogs.com/happyday56/p/8952359.html">百度搜索URL参数你知道多少</a></p><h4 id="链接重定向问题"><a href="#链接重定向问题" class="headerlink" title="链接重定向问题"></a>链接重定向问题</h4><p><a href="https://blog.csdn.net/xunalove/article/details/78550498">【百度爬虫系列 II】关键字搜索url结果汇总(给定关键字和页数)</a></p><h4 id="pip-配置国内源"><a href="#pip-配置国内源" class="headerlink" title="pip 配置国内源"></a>pip 配置国内源</h4><p><a href="https://www.cnblogs.com/schut/p/10410087.html">https://www.cnblogs.com/schut/p/10410087.html</a></p><h4 id="服务器运行指令"><a href="#服务器运行指令" class="headerlink" title="服务器运行指令"></a>服务器运行指令</h4><blockquote><p>python manage.py makemigrations</p><p>python manage.py migrate</p><p>python manage.py runserver 127.0.0.1:8000</p><p>// 网址</p><p><a href="http://127.0.0.1:8000/page/index_i.html#">http://127.0.0.1:8000/page/index_i.html#</a></p></blockquote><h4 id="Django-安装版本"><a href="#Django-安装版本" class="headerlink" title="Django 安装版本"></a>Django 安装版本</h4><p>Django 默认安装最新版本:</p><p>pip install django</p><p>Django 后面接版本号就可以了:</p><p>pip install django==1.11.7</p><p>如果使用 pip install 安装库比较慢,可以用豆瓣的镜像:</p><blockquote><p>pip install django==1.11.7 -i <a href="http://pypi.douban.com/simple">http://pypi.douban.com/simple</a> –trusted-host pypi.douban.com</p></blockquote><h4 id="用-pip-安装库报错:Microsoft-visual-c-14-0-is-required"><a href="#用-pip-安装库报错:Microsoft-visual-c-14-0-is-required" class="headerlink" title="用 pip 安装库报错:Microsoft visual c++ 14.0 is required"></a>用 pip 安装库报错:Microsoft visual c++ 14.0 is required</h4><p>下载安装包安装即可:</p><p><a href="https://964279924.ctfile.com/fs/1445568-239446865">Microsoft visual c++ 14.0</a></p><h4 id="Git的-PyCharm-使用"><a href="#Git的-PyCharm-使用" class="headerlink" title="Git的 PyCharm 使用"></a>Git的 PyCharm 使用</h4><p><a href="https://www.jianshu.com/p/52a266648842">如何在Pycharm中使用GitHub,一文带你深入</a></p><p><a href="https://blog.csdn.net/weixin_44018338/article/details/98881164">git在工作中的正确使用方式—git merge篇</a></p><h4 id="Git-教程"><a href="#Git-教程" class="headerlink" title="Git 教程"></a>Git 教程</h4><p><a href="https://blog.csdn.net/qq_36150631/article/details/81038485">Git使用教程,最详细,最傻瓜,最浅显,真正手把手教</a></p><h4 id="git-merge-最简洁用法"><a href="#git-merge-最简洁用法" class="headerlink" title="git merge 最简洁用法"></a>git merge 最简洁用法</h4><p><a href="https://blog.csdn.net/zl1zl2zl3/article/details/94019526">https://blog.csdn.net/zl1zl2zl3/article/details/94019526</a></p><h4 id="商用视频与图片素材的版权问题"><a href="#商用视频与图片素材的版权问题" class="headerlink" title="商用视频与图片素材的版权问题"></a>商用视频与图片素材的版权问题</h4><p>mixkit.co 视频插画 免费下载并且商用<br>Pexels.com 图片视频 免费且商用<br>pixabay.com 免费下载商用无需注明出处<br>videezy.com 视频 版权归创作者(一般免费下载的可以商用但需要注明出处,付费则无需注明)<br>freesound.org 音效 免费且商用需署名并附上链接<br>audionautix.com 背景音乐 可以商用<br>YouTube Voice 声音素材 (YouTube上无版权问题)<br>Adobe Voice 音效 (不允许打包二次出售)</p><h4 id="百度舆情"><a href="#百度舆情" class="headerlink" title="百度舆情"></a>百度舆情</h4><p><a href="http://yuqing.baidu.com/saas/intro/newindex">http://yuqing.baidu.com/saas/intro/newindex</a></p><h4 id="新闻网站排行榜"><a href="#新闻网站排行榜" class="headerlink" title="新闻网站排行榜"></a>新闻网站排行榜</h4><p><a href="https://www.idataapi.cn/leaderboard/list">https://www.idataapi.cn/leaderboard/list</a></p><h4 id="舆情监测系统问答"><a href="#舆情监测系统问答" class="headerlink" title="舆情监测系统问答"></a>舆情监测系统问答</h4><p><a href="https://www.zhihu.com/question/28406057">请问有哪些不错的舆情监测系统?</a></p><h4 id="个人如何监测舆情"><a href="#个人如何监测舆情" class="headerlink" title="个人如何监测舆情"></a>个人如何监测舆情</h4><p><a href="https://www.zhihu.com/question/27198392">https://www.zhihu.com/question/27198392</a></p><h4 id="第谷搜索"><a href="#第谷搜索" class="headerlink" title="第谷搜索"></a>第谷搜索</h4><p><a href="http://www.digudata.com/search/?platform=News">http://www.digudata.com/search/?platform=News</a></p><h4 id="python去除空格和换行符"><a href="#python去除空格和换行符" class="headerlink" title="python去除空格和换行符"></a>python去除空格和换行符</h4><p><a href="https://www.cnblogs.com/royfans/p/7473695.html">https://www.cnblogs.com/royfans/p/7473695.html</a></p><p><a href="https://www.cnblogs.com/fandx/p/9311755.html">https://www.cnblogs.com/fandx/p/9311755.html</a></p><h4 id="python-json"><a href="#python-json" class="headerlink" title="python json"></a>python json</h4><p><a href="https://python.freelycode.com/contribution/detail/1450">在Python中使用JSON</a></p><h4 id="open-函数"><a href="#open-函数" class="headerlink" title="open 函数"></a>open 函数</h4><p>open 函数写文件时不存在则创建文件,但是如果目录不存在的话会报错,因为需要判断并创建目录</p><h4 id="python-创建目录-文件夹"><a href="#python-创建目录-文件夹" class="headerlink" title="python 创建目录 / 文件夹"></a>python 创建目录 / 文件夹</h4><p><a href="https://blog.csdn.net/qq_41019121/article/details/90717040">https://blog.csdn.net/qq_41019121/article/details/90717040</a></p><h4 id="垃圾bug,Python-OSError-Errno-22-Invalid-argument-的出现和解决"><a href="#垃圾bug,Python-OSError-Errno-22-Invalid-argument-的出现和解决" class="headerlink" title="垃圾bug,Python OSError: [Errno 22] Invalid argument:的出现和解决"></a>垃圾bug,Python OSError: [Errno 22] Invalid argument:的出现和解决</h4><p><a href="https://www.cnblogs.com/yanhuidj/p/11351561.html">https://www.cnblogs.com/yanhuidj/p/11351561.html</a></p><h4 id="挺好的一个爬虫教程"><a href="#挺好的一个爬虫教程" class="headerlink" title="挺好的一个爬虫教程"></a>挺好的一个爬虫教程</h4><p><a href="https://blog.csdn.net/wenxuhonghe/article/details/90047081">Python 网络爬虫实战:爬取人民日报新闻文章</a></p><h4 id="爬虫数据替换"><a href="#爬虫数据替换" class="headerlink" title="爬虫数据替换"></a>爬虫数据替换</h4><p><a href="https://segmentfault.com/q/1010000007818995?_ea=1463237">https://segmentfault.com/q/1010000007818995?_ea=1463237</a></p><h4 id="鱼塘热榜,聚类数据搜索"><a href="#鱼塘热榜,聚类数据搜索" class="headerlink" title="鱼塘热榜,聚类数据搜索"></a>鱼塘热榜,聚类数据搜索</h4><p><a href="https://mo.fish/main/home/hot">https://mo.fish/main/home/hot</a></p><h4 id="mysql-的迁移创建"><a href="#mysql-的迁移创建" class="headerlink" title="mysql 的迁移创建"></a>mysql 的迁移创建</h4><p><a href="https://blog.csdn.net/qq_42581772/article/details/83098025">Django 数据库操作mySQL + Django</a></p><p><a href="https://www.cnblogs.com/ginvip/p/6894690.html">django基础之数据库操作</a></p><h4 id="Django-MySQL中文报错:django-db-utils-InternalError"><a href="#Django-MySQL中文报错:django-db-utils-InternalError" class="headerlink" title="Django + MySQL中文报错:django.db.utils.InternalError"></a>Django + MySQL中文报错:django.db.utils.InternalError</h4><p><a href="https://www.geek-share.com/detail/2757153055.html">https://www.geek-share.com/detail/2757153055.html</a></p><h4 id="git-回退-commit"><a href="#git-回退-commit" class="headerlink" title="git 回退 commit"></a>git 回退 commit</h4><p><a href="https://blog.csdn.net/bingguang1993/article/details/82629407">git撤销commit</a></p><h4 id="python-获取项目根目录"><a href="#python-获取项目根目录" class="headerlink" title="python 获取项目根目录"></a>python 获取项目根目录</h4><p><a href="https://segmentfault.com/q/1010000005135583">python如何获取当前工程根目录</a></p><h4 id="Django-No-changes-detected-when-“makemigrations”-坑爹"><a href="#Django-No-changes-detected-when-“makemigrations”-坑爹" class="headerlink" title="Django No changes detected when “makemigrations”(坑爹)"></a>Django No changes detected when “makemigrations”(坑爹)</h4><p>需要删除数据库重建,注意数据库和表格编码格式为 utf8,来支持中文</p><p><a href="https://blog.csdn.net/stephen_wong/article/details/46351505">Django. No changes detected when “makemigrations”</a></p><h4 id="静态文件读取需要在-static-目录下"><a href="#静态文件读取需要在-static-目录下" class="headerlink" title="静态文件读取需要在 static 目录下"></a>静态文件读取需要在 static 目录下</h4><p><a href="https://docs.djangoproject.com/zh-hans/3.0/howto/static-files/">管理静态文件(比如图片、JavaScript、CSS)</a></p><h4 id="MySQL:如何清空表中的数据"><a href="#MySQL:如何清空表中的数据" class="headerlink" title="MySQL:如何清空表中的数据"></a>MySQL:如何清空表中的数据</h4><p><a href="https://blog.csdn.net/qq_29229567/article/details/82743645">https://blog.csdn.net/qq_29229567/article/details/82743645</a></p><h4 id="Django-–-models-中导入数据重复的解决办法"><a href="#Django-–-models-中导入数据重复的解决办法" class="headerlink" title="Django – models 中导入数据重复的解决办法"></a>Django – models 中导入数据重复的解决办法</h4><p><a href="https://blog.csdn.net/weixin_34404393/article/details/85833383">https://blog.csdn.net/weixin_34404393/article/details/85833383</a></p><h4 id="python-的字符串截取"><a href="#python-的字符串截取" class="headerlink" title="python 的字符串截取"></a>python 的字符串截取</h4><p><a href="https://www.cnblogs.com/xunbu7/p/8074417.html">https://www.cnblogs.com/xunbu7/p/8074417.html</a></p><h4 id="Python-中-datetime-库的用法"><a href="#Python-中-datetime-库的用法" class="headerlink" title="Python 中 datetime 库的用法"></a>Python 中 datetime 库的用法</h4><p><a href="https://www.cnblogs.com/huigebj/p/11259449.html">https://www.cnblogs.com/huigebj/p/11259449.html</a></p><p>导入模块时 import datetime 即可</p><h4 id="python-中判断字典中是否存在某个键"><a href="#python-中判断字典中是否存在某个键" class="headerlink" title="python 中判断字典中是否存在某个键"></a>python 中判断字典中是否存在某个键</h4><p><a href="https://www.cnblogs.com/xmnote/p/9334880.html">https://www.cnblogs.com/xmnote/p/9334880.html</a></p><h4 id="pandas-时间使用-比-datetime-好用"><a href="#pandas-时间使用-比-datetime-好用" class="headerlink" title="pandas 时间使用 (比 datetime 好用)"></a>pandas 时间使用 (比 datetime 好用)</h4><p><a href="https://www.cnblogs.com/zhangyafei/p/10513893.html">Pandas系列(六)-时间序列详解</a></p><p><a href="https://www.cnblogs.com/ggzhangxiaochao/p/9094355.html">pandas获取当前时间</a></p><p><a href="https://www.jianshu.com/p/3b56e77b8e95">Pandas里的日期转字符串</a></p><h4 id="Django-——-filter查询的使用-数据库查询过滤筛选"><a href="#Django-——-filter查询的使用-数据库查询过滤筛选" class="headerlink" title="Django —— filter查询的使用 ( 数据库查询过滤筛选)"></a>Django —— filter查询的使用 ( 数据库查询过滤筛选)</h4><p><a href="https://www.cnblogs.com/jeepzp/p/8418627.html">Django——filter查询的使用</a></p><h4 id="百度咨询搜索的时间范围参数"><a href="#百度咨询搜索的时间范围参数" class="headerlink" title="百度咨询搜索的时间范围参数"></a>百度咨询搜索的时间范围参数</h4><p><a href="https://ask.csdn.net/questions/748535">怎样生成带自定义时间限制的百度搜索url</a></p><h4 id="python-时间字符串和时间戳之间的转换"><a href="#python-时间字符串和时间戳之间的转换" class="headerlink" title="python 时间字符串和时间戳之间的转换"></a>python 时间字符串和时间戳之间的转换</h4><p><a href="https://blog.csdn.net/qq_37193537/article/details/78987949">https://blog.csdn.net/qq_37193537/article/details/78987949</a></p><h4 id="order-by-函数"><a href="#order-by-函数" class="headerlink" title="order_by 函数"></a>order_by 函数</h4><p>用来排序</p><blockquote><p>books = BookInfo.objects.all().order_by(‘-id’) # ‘id’表示升序; ‘-id’表示降序。</p><p>books = BookInfo.objects.order_by(‘-id’) # .all()可以省略。 默认查询所有。可以结合filter 等函数一起使用 。</p></blockquote><h4 id="数据库查询返回值-filter-的-values-和-values-list-的区别"><a href="#数据库查询返回值-filter-的-values-和-values-list-的区别" class="headerlink" title="数据库查询返回值 filter 的 values() 和 values_list 的区别"></a>数据库查询返回值 filter 的 values() 和 values_list 的区别</h4><p><a href="https://www.cnblogs.com/sppython/p/7596950.html">django中filter的values_list条件使用</a></p><h4 id="raise-ValueError-“unconverted-data-remains-s”"><a href="#raise-ValueError-“unconverted-data-remains-s”" class="headerlink" title="raise ValueError(“unconverted data remains: %s” %)"></a>raise ValueError(“unconverted data remains: %s” %)</h4><p>对参数的修改最好在一开始获取到参数的时候,报这个错的原因是因为对于后面的请求重复获取并重复修改了参数,导致参数长度不一致,格式转换错误</p><h4 id="django-使用-HttpResponse-返回-json-数据为中文"><a href="#django-使用-HttpResponse-返回-json-数据为中文" class="headerlink" title="django 使用 HttpResponse 返回 json 数据为中文"></a>django 使用 HttpResponse 返回 json 数据为中文</h4><p><a href="https://www.cnblogs.com/fanhua999/p/9773317.html">https://www.cnblogs.com/fanhua999/p/9773317.html</a></p><h4 id="接口测试时保存-Forbidden-CSRF-cookie-not-set"><a href="#接口测试时保存-Forbidden-CSRF-cookie-not-set" class="headerlink" title="接口测试时保存 Forbidden (CSRF cookie not set.)"></a>接口测试时保存 Forbidden (CSRF cookie not set.)</h4><p><a href="https://blog.csdn.net/qq_43245972/article/details/87883108">https://blog.csdn.net/qq_43245972/article/details/87883108</a></p><h4 id="django-的-post-请求传数组到后台接收"><a href="#django-的-post-请求传数组到后台接收" class="headerlink" title="django 的 post 请求传数组到后台接收"></a>django 的 post 请求传数组到后台接收</h4><p>需要前台固定好请求格式,content-type 为 application/json,然后在请求 body 中是 raw 的 json 格式的文本</p><p>然后在后台用 json.loads(request.body) 得到 json 对象,再对 json 对象进行各种操作</p><p><a href="https://www.cnblogs.com/zhangdewang/p/9222952.html">django中使用POST方法 获取POST数据</a></p><h4 id="使用-jieba-分词与-wordcloud-词云分析"><a href="#使用-jieba-分词与-wordcloud-词云分析" class="headerlink" title="使用 jieba 分词与 wordcloud 词云分析"></a>使用 jieba 分词与 wordcloud 词云分析</h4><p><a href="https://zhuanlan.zhihu.com/p/39437488">jieba分词过滤停顿词、标点符号及统计词频</a></p>]]></content>
</entry>
<entry>
<title>CMMI 的学习</title>
<link href="/2019/12/23/CMMI%20%E7%9A%84%E5%AD%A6%E4%B9%A0/"/>
<url>/2019/12/23/CMMI%20%E7%9A%84%E5%AD%A6%E4%B9%A0/</url>
<content type="html"><![CDATA[<h4 id="CMMI-是什么?"><a href="#CMMI-是什么?" class="headerlink" title="CMMI 是什么?"></a>CMMI 是什么?</h4><p>Capability Maturity Model Integration 能力成熟度模型综合</p><p>是一种过程改进方法,可以用来评价一个组织的衡量软件能力成熟度</p><p>这里的学习针对 V1.3,2020开始使用 V2.0</p><h4 id="等级简述"><a href="#等级简述" class="headerlink" title="等级简述"></a>等级简述</h4><p>CMMI 分五级,<strong>等级越高越好</strong>,绝大部分申请的组织是做到 CMMI3</p><p>5 个成熟度等级分别为:</p><ol><li>初始级</li><li>受管理级</li><li>已定义级</li><li>定量管理级</li><li>持续优化级</li></ol><p>每个等级包含几个到几十个 PA(过程域 Process Area),该级别的全部 PA 达到要求即达到该级别</p><p>PA 达到要求即该PA包含的几个 Goal(目标)都达到要求了</p><p>Goal 达到要求即该Goal包含的几个 Practice(实践)都达到要求了</p><h4 id="初始级(Initial)"><a href="#初始级(Initial)" class="headerlink" title="初始级(Initial)"></a>初始级(Initial)</h4><p>环境不稳定,成功依赖个人能力</p><p>能成功,但是项目经常超成本和进度</p><p>过度承诺,危机时放弃过程,不能重复成功</p><h4 id="受管理级(Managed)"><a href="#受管理级(Managed)" class="headerlink" title="受管理级(Managed)"></a>受管理级(Managed)</h4><p>即使在时间压力下,依然能够保留现有的实践</p><p>包含的 PA</p><ul><li>需求管理 REQM</li><li>项目计划 PP</li><li>项目跟踪与控制 PMC</li><li>供应商合同管理 SAM</li><li>度量分析 MA</li><li>产品与过程质量保证 PPQA</li><li>配置管理 CM</li></ul><h4 id="已定义级(Defined)"><a href="#已定义级(Defined)" class="headerlink" title="已定义级(Defined)"></a>已定义级(Defined)</h4><p>建立标准的,且不断得到改进的工作方式</p><p>2 级和 3 级的关键区别在于</p><ul><li>标准,过程和规程的使用范围</li><li>3 级的过程比 2 级的描述更具体和严格</li></ul><p>包含的 PA</p><ul><li>需求开发 RD</li><li>技术解决方案 TS</li><li>产品集成 PI</li><li>验证 VER</li><li>确认 VAL</li><li>组织过程焦点 OPF</li><li>组织过程定义 OPD</li><li>组织培训 OT</li><li>集成项目管理 IPM</li><li>风险管理 RSKM</li><li>决策分析与解决方案 DAR</li></ul><h4 id="定量管理级(Quantitatively-Managed)"><a href="#定量管理级(Quantitatively-Managed)" class="headerlink" title="定量管理级(Quantitatively Managed)"></a>定量管理级(Quantitatively Managed)</h4><p>不仅有标准的工作方式,还有量化的工作标准</p><p>与 3 级的最大区别是,4 级可以对过程性能进行预测</p><p>包含的 PA</p><ul><li>组织过程性能 OPP</li><li>量化项目管理 QPM</li></ul><h4 id="持续优化级(Optimizing)"><a href="#持续优化级(Optimizing)" class="headerlink" title="持续优化级(Optimizing)"></a>持续优化级(Optimizing)</h4><p>以量化为手段,以解决本质问题为核心的持续改进</p><p>与 4 级本质区别,5 级解决根本问题,4 级解决特殊问题</p><p>包含的 PA</p><ul><li>组织创新与部署 OID</li><li>原因分析与解决方案 CAR</li></ul><h4 id="过程域评估"><a href="#过程域评估" class="headerlink" title="过程域评估"></a>过程域评估</h4><p>SCAMPI method for performing Class A appraisals</p><p>因为是 A 级评估,所以需要 SCAMPI 方法来评估</p><p>每一个 PA 都包括</p><ul><li>Purpose Statement</li><li>Introductory Notes</li><li>Related Process Areas</li><li>Specific Goal and Practice Summary</li><li>Specific Goals and Specific Practices</li><li>Generic Goals and Generic Practices //通用目标和通用实践会出现在多个 pa 中</li></ul><p>PA 以下有 Three Categories,划分为</p><ul><li>Required //包含 Specific Goals 和 Generic Goals</li><li>Expected //包含 Specific Practices 和 Generic Practices</li><li>Informative //包含 Example Work Products,两种实践的子实践 Subpractices, Generic Practice Elaborations, Purpose Statement,Introductory Notes,Related Process Areas</li></ul><p>下面罗列 GP 和各个 PA 的 SG</p><h4 id="Generic-Goals"><a href="#Generic-Goals" class="headerlink" title="Generic Goals"></a>Generic Goals</h4><p>GG1 Achieve Specific Goals</p><ul><li>GP1.1 Perform Specific Practices</li></ul><p>GG2 Institutionalize a Managed Process 管理的过程制度化</p><ul><li><p>GP2.1 Establish an Organizational Policy</p></li><li><p>GP2.2 Plan the Process</p></li><li><p>GP2.3 Provide Resources</p></li><li><p>GP2.4 Assign Responsibility</p></li><li><p>GP2.5 Train People</p></li><li><p>GP2.6 Control Work Products</p></li><li><p>GP2.7 Identify and Involve Relevant Stakeholders</p></li><li><p>GP2.8 Monitor and Contril the Process</p></li><li><p>GP2.9 Objectively Evaluate Adherence 客观评估实际工作率</p></li><li><p>GP2.10 Review Status with Higher Lever Management</p></li></ul><p>GG3 Institutionalize a Defined Process 确定的过程制度化</p><ul><li>GP3.1 Establish a Defined Process</li><li>GP3.2 Collect Process Related Experiences</li></ul><h4 id="Requirements-Development-Goals"><a href="#Requirements-Development-Goals" class="headerlink" title="Requirements Development Goals"></a>Requirements Development Goals</h4><p>SG1 Develop Customer Requirements</p><ul><li><p>SP1.1 Elicit Needs 获取需要</p></li><li><p>SP1.2 Transform Stakeholder Needs into Customer Requirements 利益相关者需求转换为客户需求</p></li></ul><p>SG2 Develop Product Requirements</p><ul><li><p>SP 2.1 Establish Product and Product Component Requirements 组件</p></li><li><p>SP 2.2 Allocate Product Component Requirements </p></li><li><p>SP 2.3 Identify Interface Requirements</p></li></ul><p>SG3 Analyze and Validate Requirements</p><ul><li><p>SP 3.1 Establish Operational Concepts and Scenarios 建立操作概念和场景</p></li><li><p>SP 3.2 Establish a Definition of Required Functionality and Quality Attributes 建立所需功能和质量属性的定义</p></li><li><p>SP 3.3 Analyze Requirements </p></li><li><p>SP 3.4 Analyze Requirements to Achieve Balance </p></li><li><p>SP 3.5 Validate Requirements 验证需求</p></li></ul><h4 id="Requirements-Management-Goals"><a href="#Requirements-Management-Goals" class="headerlink" title="Requirements Management Goals"></a>Requirements Management Goals</h4><p>SG1 Manage Requirements</p><ul><li><p>SP 1.1 Understand Requirements </p></li><li><p>SP 1.2 Obtain Commitment to Requirements 获得对需求的承诺 </p></li><li><p>SP 1.3 Manage Requirements Changes </p></li><li><p>SP 1.4 Maintain Bidirectional Traceability of Requirements 维护双向追踪性</p></li><li><p>SP 1.5 Ensure Alignment Between Project Work and Requirements 确保工作和需求的一致性</p></li></ul><h4 id="Project-Planning-Goals"><a href="#Project-Planning-Goals" class="headerlink" title="Project Planning Goals"></a>Project Planning Goals</h4><p>SG1 Establish Estimates</p><ul><li><p>SP 1.1 Estimate the Scope of the Project 作用域</p></li><li><p>SP 1.2 Establish Estimates of Work Product and Task Attributes </p></li><li><p>SP 1.3 Define Project Lifecycle Phases </p></li><li><p>SP 1.4 Estimate Effort and Cost </p></li></ul><p>SG2 Develop a Project Plan</p><ul><li><p>SP 2.1 Establish the Budget and Schedule </p></li><li><p>SP 2.2 Identify Project Risks </p></li><li><p>SP 2.3 Plan Data Management </p></li><li><p>SP 2.4 Plan the Project’s Resources </p></li><li><p>SP 2.5 Plan Needed Knowledge and Skills </p></li><li><p>SP 2.6 Plan Stakeholder Involvement 计划利益相关者的参与</p></li><li><p>SP 2.7 Establish the Project Plan </p></li></ul><p>SG3 Obtain Commitment to the Plan</p><ul><li><p>SP 3.1 Review Plans That Affect the Project 审查影响到项目的计划</p></li><li><p>SP 3.2 Reconcile Work and Resource Levels 协调工作和资源级别</p></li><li><p>SP 3.3 Obtain Plan Commitment 获得计划承诺</p></li></ul><h4 id="Project-Monitoring-and-Control-Goals"><a href="#Project-Monitoring-and-Control-Goals" class="headerlink" title="Project Monitoring and Control Goals"></a>Project Monitoring and Control Goals</h4><p>SG1 Monitor the Project Against Plan</p><ul><li><p>SP 1.1 Monitor Project Planning Parameters </p></li><li><p>SP 1.2 Monitor Commitments </p></li><li><p>SP 1.3 Monitor Project Risks </p></li><li><p>SP 1.4 Monitor Data Management </p></li><li><p>SP 1.5 Monitor Stakeholder Involvement </p></li><li><p>SP 1.6 Conduct Progress Reviews </p></li><li><p>SP 1.7 Conduct Milestone Reviews </p></li></ul><p>SG2 Manage Corrective Action to Closure</p><ul><li><p>SP 2.1 Analyze Issues </p></li><li><p>SP 2.2 Take Corrective Action 采取校正行动</p></li><li><p>SP 2.3 Manage Corrective Actions</p></li></ul><h4 id="Risk-Management-Goals"><a href="#Risk-Management-Goals" class="headerlink" title="Risk Management Goals"></a>Risk Management Goals</h4><p>SG1 Prepare for Risk Management</p><ul><li><p>SP 1.1 Determine Risk Sources and Categories </p></li><li><p>SP 1.2 Define Risk Parameters </p></li><li><p>SP 1.3 Establish a Risk Management Strategy</p></li></ul><p>SG2 Identify and Analyze Risks</p><ul><li><p>SP 2.1 Identify Risks </p></li><li><p>SP 2.2 Evaluate, Categorize, and Prioritize Risks 评估,分类,安排风险的优先顺序</p></li></ul><p>SG3 Mitigate Risks</p><ul><li><p>SP 3.1 Develop Risk Mitigation Plans 开发风险缓解计划</p></li><li><p>SP 3.2 Implement Risk Mitigation Plans 实现风险缓解计划</p></li></ul><h4 id="Supplier-Agreement-Management-Goals"><a href="#Supplier-Agreement-Management-Goals" class="headerlink" title="Supplier Agreement Management Goals"></a>Supplier Agreement Management Goals</h4><p>SG1 Establish Supplier Agreements</p><ul><li><p>SP 1.1 Determine Acquisition Type 决定购置类型</p></li><li><p>SP 1.2 Select Suppliers </p></li><li><p>SP 1.3 Establish Supplier Agreements</p></li></ul><p>SG2 Satisfy Supplier Agreements</p><ul><li><p>SP 2.1 Execute the Supplier Agreement </p></li><li><p>SP 2.2 Accept the Acquired Product </p></li><li><p>SP 2.3 Ensure Transition of Products 确保产品转换</p></li></ul><h4 id="Configuration-Management-Goals"><a href="#Configuration-Management-Goals" class="headerlink" title="Configuration Management Goals"></a>Configuration Management Goals</h4><p>SG1 Establish Baselines</p><ul><li><p>SP 1.1 Identify Configuration Items </p></li><li><p>SP 1.2 Establish a Configuration Management System </p></li><li><p>SP 1.3 Create or Release Baselines</p></li></ul><p>SG2 Track and Contril Changes</p><ul><li><p>SP 2.1 Track Change Requests </p></li><li><p>SP 2.2 Control Configuration Items</p></li></ul><p>SG3 Establish Integrity</p><ul><li><p>SP 3.1 Establish Configuration Management Records 建立配置管理记录</p></li><li><p>SP 3.2 Perform Configuration Audits 执行配置审核</p></li></ul><h4 id="Process-and-Product-Quality-Assurance-Goals"><a href="#Process-and-Product-Quality-Assurance-Goals" class="headerlink" title="Process and Product Quality Assurance Goals"></a>Process and Product Quality Assurance Goals</h4><p>SG1 Objectively Evaluate Processes and Work Products 客观</p><ul><li><p>SP 1.1 Objectively Evaluate Processes </p></li><li><p>SP 1.2 Objectively Evaluate Work Products</p></li></ul><p>SG2 Provide Objective Insight</p><ul><li><p>SP 2.1 Communicate and Resolve Noncompliance Issues 沟通和解决违约行为事件</p></li><li><p>SP 2.2 Establish Records</p></li></ul><h4 id="Measurement-and-Analysis-Goals"><a href="#Measurement-and-Analysis-Goals" class="headerlink" title="Measurement and Analysis Goals"></a>Measurement and Analysis Goals</h4><p>SG1 Align Measurement and Analysis Activities 调整测量和分析活动</p><ul><li><p>SP 1.1 Establish Measurement Objectives </p></li><li><p>SP 1.2 Specify Measures </p></li><li><p>SP 1.3 Specify Data Collection and Storage Procedures 指定数据收集和存储过程</p></li><li><p>SP 1.4 Specify Analysis Procedures </p></li></ul><p>SG2 Provide Measurement Results</p><ul><li><p>SP 2.1 Obtain Measurement Data </p></li><li><p>SP 2.2 Analyze Measurement Data </p></li><li><p>SP 2.3 Store Data and Results </p></li><li><p>SP 2.4 Communicate Results </p></li></ul><h4 id="Decision-Analysis-and-Resolution-Goals"><a href="#Decision-Analysis-and-Resolution-Goals" class="headerlink" title="Decision Analysis and Resolution Goals"></a>Decision Analysis and Resolution Goals</h4><p>SG1 Evaluate Alternatives 评估选择</p><ul><li><p>SP 1.1 Establish Guidelines for Decision Analysis </p></li><li><p>SP 1.2 Establish Evaluation Criteria 建立评价标准</p></li><li><p>SP 1.3 Identify Alternative Solutions </p></li><li><p>SP 1.4 Select Evaluation Methods </p></li><li><p>SP 1.5 Evaluate Alternative Solutions</p></li><li><p>SP 1.6 Select Solutions</p></li></ul><h4 id="Technical-Solution-Goals"><a href="#Technical-Solution-Goals" class="headerlink" title="Technical Solution Goals"></a>Technical Solution Goals</h4><p>SG1 Select Product Component Solutions</p><ul><li><p>SP 1.1 Develop Alternative Solutions and Selection Criteria </p></li><li><p>SP 1.2 Select Product Component Solutions</p></li></ul><p>SG2 Develop the Design</p><ul><li><p>SP 2.1 Design the Product or Product Component </p></li><li><p>SP 2.2 Establish a Technical Data Package </p></li><li><p>SP 2.3 Design Interfaces Using Criteria </p></li><li><p>SP 2.4 Perform Make, Buy, or Reuse Analyses 执行制造、购买或重用分析</p></li></ul><p> SG3 Implement the Product Design</p><ul><li><p>SP 3.1 Implement the Design</p></li><li><p>SP 3.2 Develop Product Support Documentation 开发产品技术支持文档</p></li></ul><h4 id="Product-Integration-Goals"><a href="#Product-Integration-Goals" class="headerlink" title="Product Integration Goals"></a>Product Integration Goals</h4><p>SG1 Prepare for Product Integration</p><ul><li><p>SP 1.1 Establish an Integration Strategy 集成策略</p></li><li><p>SP 1.2 Establish the Product Integration Environment 产品集成环境 </p></li><li><p>SP 1.3 Establish Product Integration Procedures and Criteria 集成过程和适用范围</p></li></ul><p>SG2 Ensure Interface Compatibility</p><ul><li><p>SP 2.1 Review Interface Descriptions for Completeness 审核接口描述完整性</p></li><li><p>SP 2.2 Manage Interfaces</p></li></ul><p>SG3 Assemble Product Components and Deliver the Product</p><ul><li><p>SP 3.1 Confirm Readiness of Product Components for Integration 确认产品组件已准备好进行集成</p></li><li><p>SP 3.2 Assemble Product Components 组装产品组件</p></li><li><p>SP 3.3 Evaluate Assembled Product Components 评估</p></li><li><p>SP 3.4 Package and Deliver the Product or Product Component 打包和传交付</p></li></ul><h4 id="Verification-Goals"><a href="#Verification-Goals" class="headerlink" title="Verification Goals"></a>Verification Goals</h4><p>SG1 Prepare for Verification</p><ul><li><p>SP 1.1 Select Work Products for Verification </p></li><li><p>SP 1.2 Establish the Verification Environment </p></li><li><p>SP 1.3 Establish Verification Procedures and Criteria</p></li></ul><p>SG2 Perform Peer Reviews</p><ul><li><p>SP 2.1 Prepare for Peer Reviews</p></li><li><p>SP 2.2 Conduct Peer Reviews 开展同行评审</p></li><li><p>SP 2.3 Analyze Peer Review Data</p></li></ul><p>SG3 Verify Selected Eork Products</p><ul><li><p>SP 3.1 Perform Verification </p></li><li><p>SP 3.2 Analyze Verification Results</p></li></ul><h4 id="Validation-Goals"><a href="#Validation-Goals" class="headerlink" title="Validation Goals"></a>Validation Goals</h4><p>SG1 Prepare for Validation</p><ul><li><p>SP 1.1 Select Products for Validation </p></li><li><p>SP 1.2 Establish the Validation Environment </p></li><li><p>SP 1.3 Establish Validation Procedures and Criteria</p></li></ul><p>SG2 Validate Product or Product Components</p><ul><li><p>SP 2.1 Perform Validation </p></li><li><p>SP 2.2 Analyze Validation Results</p></li></ul><h4 id="Organizational-Process-Focus-Goals"><a href="#Organizational-Process-Focus-Goals" class="headerlink" title="Organizational Process Focus Goals"></a>Organizational Process Focus Goals</h4><p>SG1 Determine Process Improvement Opportunities</p><ul><li><p>SP 1.1 Establish Organizational Process Needs </p></li><li><p>SP 1.2 Appraise the Organization‟s Processes 评估组织过程</p></li><li><p>SP 1.3 Identify the Organization’s Process Improvements</p></li></ul><p>SG2 Plan and Implement Process Actions</p><ul><li><p>SP 2.1 Establish Process Action Plans </p></li><li><p>SP 2.2 Implement Process Action Plans</p></li></ul><p>SG3 Deploy Organizayional Process Assets and Incorporate Experiences 部署组织流程资产并整合经验</p><ul><li><p>SP 3.1 Deploy Organizational Process Assets </p></li><li><p>SP 3.2 Deploy Standard Processes </p></li><li><p>SP 3.3 Monitor the Implementation </p></li><li><p>SP 3.4 Incorporate Experiences into Organizational Process Assets 整合经验成为组织过程资产</p></li></ul><h4 id="Organizational-Process-Definition-Goals"><a href="#Organizational-Process-Definition-Goals" class="headerlink" title="Organizational Process Definition Goals"></a>Organizational Process Definition Goals</h4><p>SG1 Establish Organizational Process Assets</p><ul><li><p>SP 1.1 Establish Standard Processes </p></li><li><p>SP 1.2 Establish Lifecycle Model Descriptions </p></li><li><p>SP 1.3 Establish Tailoring Criteria and Guidelines 制定裁剪标准和指南</p></li><li><p>SP 1.4 Establish the Organization‟s Measurement Repository </p></li><li><p>SP 1.5 Establish the Organization‟s Process Asset Library </p></li><li><p>SP 1.6 Establish Work Environment Standards </p></li><li><p>SP 1.7 Establish Rules and Guidelines for Teams </p></li></ul><h4 id="Integrated-Project-Management-Goals"><a href="#Integrated-Project-Management-Goals" class="headerlink" title="Integrated Project Management Goals"></a>Integrated Project Management Goals</h4><p>SG1 Use the Project’s Defined Process</p><ul><li><p>SP 1.1 Establish the Project‟s Defined Process </p></li><li><p>SP 1.2 Use Organizational Process Assets for Planning Project Activities </p></li><li><p>SP 1.3 Establish the Project’s Work Environment </p></li><li><p>SP 1.4 Integrate Plans </p></li><li><p>SP 1.5 Manage the Project Using Integrated Plans </p></li><li><p>SP 1.6 Establish Teams </p></li><li><p>SP 1.7 Contribute to Organizational Process Assets </p></li></ul><p>SG2 Coordinate and Collaborte with Relevant Stakeholders 与相关利益相关者协调和合作</p><ul><li><p>SP 2.1 Manage Stakeholder Involvement</p></li><li><p>SP 2.2 Manage Dependencies </p></li><li><p>SP 2.3 Resolve Coordination Issues</p></li></ul><h4 id="Organizational-Training-Goals"><a href="#Organizational-Training-Goals" class="headerlink" title="Organizational Training Goals"></a>Organizational Training Goals</h4><p>SG1 Establish an Organizational Training Capablity</p><ul><li><p>SP 1.1 Establish Strategic Training Needs </p></li><li><p>SP 1.2 Determine Which Training Needs Are the Responsibility of the Organization </p></li><li><p>SP 1.3 Establish an Organizational Training Tactical Plan 组织培训战术性计划</p></li><li><p>SP 1.4 Establish a Training Capability </p></li></ul><p>SG2 Provide Training</p><ul><li><p>SP 2.1 Deliver Training </p></li><li><p>SP 2.2 Establish Training Records </p></li><li><p>SP 2.3 Assess Training Effectiveness 评估培训效果</p></li></ul><p>OPP QPM CAR OPM为更高的成熟度过程域,这里暂时略过 </p><h4 id="资料"><a href="#资料" class="headerlink" title="资料"></a>资料</h4><p><a href="https://blog.csdn.net/sjsm2007/article/details/19477815">基础知识扫盲</a> </p><p><a href="https://zhuanlan.zhihu.com/p/78316850">cmmi 是什么</a> </p><p><a href="https://zhuanlan.zhihu.com/p/78333021">为什么需要cmmi </a> </p><p>一系列CMMI评审访谈 </p><p><a href="https://blog.csdn.net/weixin_43128990/article/details/100149927">https://blog.csdn.net/weixin_43128990/article/details/100149927</a> </p><p><a href="https://wenku.baidu.com/view/2a52f92d1fb91a37f111f18583d049649b660e03.html">https://wenku.baidu.com/view/2a52f92d1fb91a37f111f18583d049649b660e03.html</a> </p><p><a href="https://blog.csdn.net/kalision/article/details/8185974">访谈问题</a> </p><p><a href="https://wenku.baidu.com/view/6b88f69f846a561252d380eb6294dd88d1d23d74.html">CMMI基础知识考试试题和答案</a> </p><p><a href="https://blog.csdn.net/weixin_44126446/article/details/89399050">一篇就懂的CMMI认证三级评估准备及其注意事项</a></p><p><a href="https://blog.csdn.net/doudou5555/article/details/53196672">CMMI3认证过程记录</a></p><p><a href="https://blog.csdn.net/dylanren/article/details/78664011">一次CMMI虚假改进,评估的案例</a></p><h4 id="Bruce-Hofman-课堂"><a href="#Bruce-Hofman-课堂" class="headerlink" title="Bruce Hofman 课堂"></a>Bruce Hofman 课堂</h4><p><strong>criteria 和 threshold</strong></p><p>criteria 是标准,按照标准做的纠正措施是合理的,比如裁剪,是合理的</p><p>threshold 是阈值,超过阈值采取的措施的紧急不正常的,如果没超过阈值,just do nothing</p><p>中国人的思维是总是在事情还没发生就采取纠正措施,那么阈值这个概念就没有意义了,如果非要采取行动,为什么当初就不把阈值设置得低一点呢</p><p><strong>status 和 performance</strong></p><p>performance 是带有单位的,status 只能看到过去,而 performance 能看到未来</p><p><strong>measurement analysis</strong></p><p>由 information need 推出 objectives 目标 ( objectives 是一段阐述,what…who…why… 而不是一个简单的数值目标)</p><p>objectives 不等于 goals</p><p>由 objectives 得到 measurement needs,最后根据标准流程的 performance 能找出更有价值的 goal</p>]]></content>
</entry>
<entry>
<title>在 2019 的 Flutter 学习</title>
<link href="/2019/05/07/%E5%9C%A8%202019%20%E7%9A%84%20Flutter%20%E5%AD%A6%E4%B9%A0/"/>
<url>/2019/05/07/%E5%9C%A8%202019%20%E7%9A%84%20Flutter%20%E5%AD%A6%E4%B9%A0/</url>
<content type="html"><![CDATA[<h3 id="资料"><a href="#资料" class="headerlink" title="资料"></a>资料</h3><h4 id="文档"><a href="#文档" class="headerlink" title="文档"></a>文档</h4><p><a href="https://flutter.dev/docs">Flutter documentation</a></p><p><a href="https://flutter.cn/docs/get-started/install">Flutter中文文档</a></p><p><a href="https://book.flutterchina.club/">《Flutter实战》电子书</a></p><h4 id="Dart-语言入门"><a href="#Dart-语言入门" class="headerlink" title="Dart 语言入门"></a>Dart 语言入门</h4><p><a href="https://www.jianshu.com/p/06aebcad0543">30分钟掌握Dart语言</a></p><h4 id="Awesome-flutter"><a href="#Awesome-flutter" class="headerlink" title="Awesome-flutter"></a>Awesome-flutter</h4><p><a href="https://github.com/Solido/awesome-flutter">https://github.com/Solido/awesome-flutter</a></p><h4 id="很好用的图标库-Fontawesome-icons"><a href="#很好用的图标库-Fontawesome-icons" class="headerlink" title="很好用的图标库 Fontawesome icons"></a>很好用的图标库 Fontawesome icons</h4><p><a href="https://fontawesome.com/icons?d=gallery">https://fontawesome.com/icons?d=gallery</a></p><h4 id="登录注册界面"><a href="#登录注册界面" class="headerlink" title="登录注册界面"></a>登录注册界面</h4><p><a href="https://github.com/huextrat/TheGorgeousLogin">https://github.com/huextrat/TheGorgeousLogin</a></p><h4 id="录音器,能返回-wav"><a href="#录音器,能返回-wav" class="headerlink" title="录音器,能返回 .wav"></a>录音器,能返回 .wav</h4><p><a href="https://github.com/39499740/recorder_wav/tree/master/example">https://github.com/39499740/recorder_wav/tree/master/example</a></p><p>源代码其实是经过pcm转换成wav再删除pcm,因为语音识别接口要用的是pcm,所以改了一下源代码,不要删除pcm</p><h4 id="介绍一个Flutter-App的功能,功能分析得挺好的"><a href="#介绍一个Flutter-App的功能,功能分析得挺好的" class="headerlink" title="介绍一个Flutter App的功能,功能分析得挺好的"></a>介绍一个Flutter App的功能,功能分析得挺好的</h4><p><a href="https://blog.csdn.net/u013718120/article/details/86621278">基于 Flutter 视频客户端 Vistor【已开源】</a></p><h4 id="Flutter的一个资源教程列表"><a href="#Flutter的一个资源教程列表" class="headerlink" title="Flutter的一个资源教程列表"></a>Flutter的一个资源教程列表</h4><p><a href="http://www.devio.org/tags/#Flutter">http://www.devio.org/tags/#Flutter</a></p><h4 id="比较通俗的讲解学flutter过程"><a href="#比较通俗的讲解学flutter过程" class="headerlink" title="比较通俗的讲解学flutter过程"></a>比较通俗的讲解学flutter过程</h4><p><a href="https://blog.csdn.net/qq_30447263/article/details/85241991">Flutter七日总结</a></p><h4 id="挺好看的底部导航栏"><a href="#挺好看的底部导航栏" class="headerlink" title="挺好看的底部导航栏"></a>挺好看的底部导航栏</h4><p><a href="https://github.com/imaNNeoFighT/circular_bottom_navigation">https://github.com/imaNNeoFighT/circular_bottom_navigation</a></p><h4 id="基于flutter实现的在线视频播放app"><a href="#基于flutter实现的在线视频播放app" class="headerlink" title="基于flutter实现的在线视频播放app"></a>基于flutter实现的在线视频播放app</h4><p><a href="https://github.com/shmy/dd_app">https://github.com/shmy/dd_app</a></p><h4 id="分享链接内容的插件share-extend"><a href="#分享链接内容的插件share-extend" class="headerlink" title="分享链接内容的插件share_extend"></a>分享链接内容的插件share_extend</h4><p><a href="https://github.com/zhouteng0217/ShareExtend">https://github.com/zhouteng0217/ShareExtend</a></p><h4 id="播放器GPlayer(基于ijkplayer)"><a href="#播放器GPlayer(基于ijkplayer)" class="headerlink" title="播放器GPlayer(基于ijkplayer)"></a>播放器GPlayer(基于ijkplayer)</h4><p><a href="https://github.com/tcking/GPlayer">https://github.com/tcking/GPlayer</a></p><h4 id="样例视频下载,兔子起床"><a href="#样例视频下载,兔子起床" class="headerlink" title="样例视频下载,兔子起床"></a>样例视频下载,兔子起床</h4><p><a href="https://www.sample-videos.com/">https://www.sample-videos.com/</a></p><h4 id="一个组件库"><a href="#一个组件库" class="headerlink" title="一个组件库"></a>一个组件库</h4><p><<a href="https://github.com/lishuhao/sy_flutter_widgets">https://github.com/lishuhao/sy_flutter_widgets</a></p><h4 id="讯飞语音评测"><a href="#讯飞语音评测" class="headerlink" title="讯飞语音评测"></a>讯飞语音评测</h4><p><a href="https://doc.xfyun.cn/rest_api/%E8%AF%AD%E9%9F%B3%E8%AF%84%E6%B5%8B.html">https://doc.xfyun.cn/rest_api/%E8%AF%AD%E9%9F%B3%E8%AF%84%E6%B5%8B.html</a></p><h4 id="Http-请求库-dio"><a href="#Http-请求库-dio" class="headerlink" title="Http 请求库 dio"></a>Http 请求库 dio</h4><p><a href="https://pub.flutter-io.cn/packages/dio">https://pub.flutter-io.cn/packages/dio</a></p><h4 id="音频声音播放,较短的"><a href="#音频声音播放,较短的" class="headerlink" title="音频声音播放,较短的"></a>音频声音播放,较短的</h4><p><a href="https://github.com/Canardoux/tau">https://github.com/Canardoux/tau</a></p><h4 id="SnackBar-material风格"><a href="#SnackBar-material风格" class="headerlink" title="SnackBar,material风格"></a>SnackBar,material风格</h4><p><a href="https://www.jianshu.com/p/fbc8236fc8db">https://www.jianshu.com/p/fbc8236fc8db</a></p><h4 id="AppBar使用介绍,顶端栏"><a href="#AppBar使用介绍,顶端栏" class="headerlink" title="AppBar使用介绍,顶端栏"></a>AppBar使用介绍,顶端栏</h4><p><a href="https://www.jianshu.com/p/77f8b7ee8460">Flutter AppBar(顶端栏)</a></p><h4 id="好看的登录按钮"><a href="#好看的登录按钮" class="headerlink" title="好看的登录按钮"></a>好看的登录按钮</h4><p><a href="https://blog.csdn.net/u011272795/article/details/83043932">https://blog.csdn.net/u011272795/article/details/83043932</a></p><h4 id="Dart介绍,写得生动"><a href="#Dart介绍,写得生动" class="headerlink" title="Dart介绍,写得生动"></a>Dart介绍,写得生动</h4><p><a href="https://www.jianshu.com/p/d41952e51120">https://www.jianshu.com/p/d41952e51120</a></p><h4 id="Django介绍"><a href="#Django介绍" class="headerlink" title="Django介绍"></a>Django介绍</h4><p><a href="https://www.jianshu.com/p/0dea2dce9dc1">Django简介、及其优点</a></p><p><a href="https://blog.csdn.net/weixin_42134789/article/details/80753010">django的优缺点总结 - Python Web开发面试必备</a></p><h4 id="Material-Design的详细规范"><a href="#Material-Design的详细规范" class="headerlink" title="Material Design的详细规范"></a>Material Design的详细规范</h4><p><a href="https://www.uisdc.com/comprehensive-material-design-note">https://www.uisdc.com/comprehensive-material-design-note</a></p><h4 id="App内嵌WebView"><a href="#App内嵌WebView" class="headerlink" title="App内嵌WebView"></a>App内嵌WebView</h4><p><a href="https://pub.flutter-io.cn/packages/webview_flutter">https://pub.flutter-io.cn/packages/webview_flutter</a></p><h4 id="跑马灯轮播实现"><a href="#跑马灯轮播实现" class="headerlink" title="跑马灯轮播实现"></a>跑马灯轮播实现</h4><p><a href="https://github.com/serenader2014/flutter_carousel_slider">https://github.com/serenader2014/flutter_carousel_slider</a></p><h4 id="讲Flutter挺好的"><a href="#讲Flutter挺好的" class="headerlink" title="讲Flutter挺好的"></a>讲Flutter挺好的</h4><p><a href="https://blog.csdn.net/m0_37667770/article/details/80903890">Flutter三天学习基础——-一天搞定项目</a></p><h3 id="Q-amp-A"><a href="#Q-amp-A" class="headerlink" title="Q & A"></a>Q & A</h3><h4 id="导入新的-flutter-项目卡死在-Initializing-gradle"><a href="#导入新的-flutter-项目卡死在-Initializing-gradle" class="headerlink" title="导入新的 flutter 项目卡死在 Initializing gradle"></a>导入新的 flutter 项目卡死在 Initializing gradle</h4><p><a href="https://www.jianshu.com/p/407d3ca7037e">https://www.jianshu.com/p/407d3ca7037e</a></p><p>1.打开安卓视图中 <code>gradle->wrapper->gradle-wrapper.properties</code>,最后一行改为</p><figure class="highlight apache"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs apache"><span class="hljs-attribute">distributionUrl</span>=https\://services.gradle.org/distributions/gradle-<span class="hljs-number">4</span>.<span class="hljs-number">10</span>.<span class="hljs-number">2</span>-<span class="hljs-literal">all</span>.zip<br></code></pre></td></tr></table></figure><p>2.</p><p>打开Flutter SDK:flutter\packages\flutter_tools\gradle\flutter.gradle</p><p>注释掉 google() 和 jcenter(),下面添加阿里云代理</p><figure class="highlight roboconf"><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><code class="hljs roboconf">maven{ <span class="hljs-attribute">url 'https</span>://maven<span class="hljs-variable">.aliyun</span><span class="hljs-variable">.com</span>/repository/google' }<br> maven{ url 'https://maven<span class="hljs-variable">.aliyun</span><span class="hljs-variable">.com</span>/repository/jcenter' }<br> maven{url 'http://maven<span class="hljs-variable">.aliyun</span><span class="hljs-variable">.com</span>/nexus/content/groups/public'}<br></code></pre></td></tr></table></figure><p>注:项目路径不能有中文</p><h4 id="启动页(闪屏页)设置"><a href="#启动页(闪屏页)设置" class="headerlink" title="启动页(闪屏页)设置"></a>启动页(闪屏页)设置</h4><p><a href="https://chengww.com/archives/flutter-splash.html#%E9%A1%B5%E9%9D%A2%E5%88%9B%E5%BB%BA">https://chengww.com/archives/flutter-splash.html#%E9%A1%B5%E9%9D%A2%E5%88%9B%E5%BB%BA</a></p><h4 id="添加资源图片异常"><a href="#添加资源图片异常" class="headerlink" title="添加资源图片异常"></a>添加资源图片异常</h4><p>异常原因:assets 前面多了个空格<br>解决方案:去除 assets 前面的一个空格,注意整体的标签对齐</p><h4 id="路由导航用法"><a href="#路由导航用法" class="headerlink" title="路由导航用法"></a>路由导航用法</h4><p><a href="https://blog.csdn.net/f917386389/article/details/88784461">Flutter之路由及导航(页面跳转以及传递数据)</a></p><p><a href="https://www.jianshu.com/p/cb0af52376ba">flutter页面间跳转和传参-Navigator的使用</a></p><h4 id="ListView子项写法"><a href="#ListView子项写法" class="headerlink" title="ListView子项写法"></a>ListView子项写法</h4><p><a href="https://blog.csdn.net/sinat_17775997/article/details/82083361">Flutter 中 ListView 的使用</a></p><p><a href="https://github.com/zhibuyu/Flutter_Stocks/blob/master/lib/news/FinanceNewsPage.dart">https://github.com/zhibuyu/Flutter_Stocks/blob/master/lib/news/FinanceNewsPage.dart</a></p><p>Flutter里面列表的初始化类似于Java,要先new</p><p>比如List<String> items = new List<String>();</p><p>然后再item.add();</p><p>有时候闪电标志的热重载不行,这时要绿色重新run一遍,再不行就从菜单栏tools中找到flutter clean执行</p><h4 id="圆形头像制作"><a href="#圆形头像制作" class="headerlink" title="圆形头像制作"></a>圆形头像制作</h4><p><a href="https://blog.csdn.net/qq_32319999/article/details/80352069">https://blog.csdn.net/qq_32319999/article/details/80352069</a></p><h4 id="Material-design-字体?"><a href="#Material-design-字体?" class="headerlink" title="Material design 字体?"></a>Material design 字体?</h4><p>Material design的英文字体为Roboto,中文字体为Noto,就是思源黑体</p><h4 id="gridview-总是溢出-overflow"><a href="#gridview-总是溢出-overflow" class="headerlink" title="gridview 总是溢出 overflow"></a>gridview 总是溢出 overflow</h4><p>原因是 childAspectRatio 这个属性,默认子项为网格正方形,控件摆放不成正方形就会溢出</p><h4 id="更新-Dialog-状态"><a href="#更新-Dialog-状态" class="headerlink" title="更新 Dialog 状态"></a>更新 Dialog 状态</h4><p><a href="https://blog.csdn.net/yumi0629/article/details/81939936">Flutter更新showDialog中的内容</a></p><h4 id="底部弹出对话框的状态设置更新"><a href="#底部弹出对话框的状态设置更新" class="headerlink" title="底部弹出对话框的状态设置更新"></a>底部弹出对话框的状态设置更新</h4><p><a href="https://blog.csdn.net/qq_36071410/article/details/88016218">flutter 底部弹窗 showModalBottomSheet 自定义样式和回调</a></p><p><a href="https://blog.csdn.net/mengks1987/article/details/85108150">Flutter showBottomSheet</a></p><h4 id="Json用法"><a href="#Json用法" class="headerlink" title="Json用法"></a>Json用法</h4><p>一是手动建立</p><p><a href="https://juejin.im/post/5b5d782ae51d45191c7e7fb3">https://juejin.im/post/5b5d782ae51d45191c7e7fb3</a></p><p>二是调用库json_serializable</p><p><a href="https://www.jianshu.com/p/e010041f0ec0/">https://www.jianshu.com/p/e010041f0ec0/</a></p><p>要是想直接拿json里面的某一个数据,甚至可以像下面那样做,一层一层调用Map,取出想要的值</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs css">print(response<span class="hljs-selector-class">.data</span><span class="hljs-selector-attr">[<span class="hljs-string">'data'</span>]</span><span class="hljs-selector-attr">[<span class="hljs-string">'read_word'</span>]</span><span class="hljs-selector-attr">[<span class="hljs-string">'rec_paper'</span>]</span><span class="hljs-selector-attr">[<span class="hljs-string">'read_word'</span>]</span><span class="hljs-selector-attr">[<span class="hljs-string">'total_score'</span>]</span>);<br></code></pre></td></tr></table></figure><p>另外注意一下json的格式,如果已经是json的string形式,就不用再decode了,因为decode的目的就是得到json的string,不需要再第二次decode了,坑死人了这</p><h4 id="流文件"><a href="#流文件" class="headerlink" title="流文件"></a>流文件</h4><p><a href="https://blog.csdn.net/s1120080286/article/details/83239453">Flutter系列之Dart文件IO操作</a></p><h4 id="Django-port占用"><a href="#Django-port占用" class="headerlink" title="Django port占用"></a>Django port占用</h4><p><a href="https://www.jianshu.com/p/7ceebb422d09">解决Django运行报错</a></p><h4 id="wav-格式要求太严格,头部文件需要处理,用-mp3-好点,还经过了压缩"><a href="#wav-格式要求太严格,头部文件需要处理,用-mp3-好点,还经过了压缩" class="headerlink" title="wav 格式要求太严格,头部文件需要处理,用 mp3 好点,还经过了压缩"></a>wav 格式要求太严格,头部文件需要处理,用 mp3 好点,还经过了压缩</h4><p><a href="https://blog.csdn.net/mp624183768/article/details/79633840">二进制文件处理 WAV文件格式解析【利用python 将wav文件音量变小】</a></p><p>响应的形式,一是流stream,二是字节byte</p><h4 id="如何用库"><a href="#如何用库" class="headerlink" title="如何用库"></a>如何用库</h4><p>下载他的demo,里面有很多功能演示,删减代码,缩减到只有自己想要的功能,再迁移到自己的项目上。</p><h4 id="主题切换功能实现"><a href="#主题切换功能实现" class="headerlink" title="主题切换功能实现"></a>主题切换功能实现</h4><p><a href="https://blog.csdn.net/u013718120/article/details/85259429">Flutter以两种方式实现App主题切换</a></p><p>主要是参考黑人视频的EventBus做法,全局只有一个MaterialApp,其它page的根widget为Scaffold</p><h4 id="分析非功能需求"><a href="#分析非功能需求" class="headerlink" title="分析非功能需求"></a>分析非功能需求</h4><p><a href="https://blog.csdn.net/jjm1437/article/details/53911262">需求分析师如何做好非功能性需求</a></p><p><a href="https://www.jianshu.com/p/d9d02e4174bf">软件产品质量模型介绍</a></p><h4 id="Django部署教程"><a href="#Django部署教程" class="headerlink" title="Django部署教程"></a>Django部署教程</h4><p><a href="https://blog.csdn.net/mnhn456/article/details/80594714">https://blog.csdn.net/mnhn456/article/details/80594714</a></p><h4 id="Charts-图表"><a href="#Charts-图表" class="headerlink" title="Charts 图表"></a>Charts 图表</h4><p><a href="https://google.github.io/charts/flutter/gallery.html">https://google.github.io/charts/flutter/gallery.html</a></p><p><a href="https://github.com/google/charts/tree/master/charts_flutter">https://github.com/google/charts/tree/master/charts_flutter</a></p><h4 id="布局讲解"><a href="#布局讲解" class="headerlink" title="布局讲解"></a>布局讲解</h4><p>CrossAxisAlignment,children在交叉轴方向的对齐方式,布局时很重要</p><p><a href="https://www.jianshu.com/p/0ce74751d970">Flutter 布局(七)- Row、Column详解</a></p>]]></content>
</entry>
<entry>
<title>搭建 Confluence Wiki</title>
<link href="/2019/01/20/%E6%90%AD%E5%BB%BA%20Confluence%20Wiki/"/>
<url>/2019/01/20/%E6%90%AD%E5%BB%BA%20Confluence%20Wiki/</url>
<content type="html"><![CDATA[<h3 id="参考网址"><a href="#参考网址" class="headerlink" title="参考网址"></a>参考网址</h3><p>旧版的confluence安装教程</p><p><a href="https://blog.csdn.net/u014307117/article/details/78841705">https://blog.csdn.net/u014307117/article/details/78841705</a></p><p>新版的confluence安装教程</p><p><a href="https://blog.csdn.net/weixin_41004350/article/details/80590421">https://blog.csdn.net/weixin_41004350/article/details/80590421</a></p><p>先安装个lrzsz来方便传文件</p><figure class="highlight cmake"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cmake">yum <span class="hljs-keyword">install</span> -y lrzsz<br></code></pre></td></tr></table></figure><p>confluence安装最好还是在本地windows主机去官网的archives找到完整的bin安装包链接后用迅雷下载,再用rz命令远程上传到服务器,服务器用wget下载极慢</p><h3 id="MySQL-安装"><a href="#MySQL-安装" class="headerlink" title="MySQL 安装"></a>MySQL 安装</h3><p>因为自己来手动安装 MySQL 很麻烦,因此最好是在云服务器上安装系统时候选择带有 MySQL 的镜像安装,就不用下面麻烦的 MySQL 安装步骤,安装好后可以到镜像的安装说明中找到 MySQL 登录账号的默认密码。MySQL 版本用 5.7</p><p>比如下面这个镜像和说明</p><p><a href="http://support.websoft9.com/docs/mysql-image-guide/">http://support.websoft9.com/docs/mysql-image-guide/</a></p><h4 id="MySQL-数据库创建"><a href="#MySQL-数据库创建" class="headerlink" title="MySQL 数据库创建"></a>MySQL 数据库创建</h4><p>MySQL 版本需要用 5.7,在腾讯云上面用 5.6 不行,用 yum 方式安装,国外速度慢的话更换网易 163 的源。</p><p>更换 163 源</p><p><a href="https://www.cnblogs.com/zuizui1204/p/7729585.html">https://www.cnblogs.com/zuizui1204/p/7729585.html</a></p><p>或者换成阿里云的源</p><p><a href="https://blog.csdn.net/qq_36428437/article/details/60153209?utm_source=blogxgwz10">https://blog.csdn.net/qq_36428437/article/details/60153209?utm_source=blogxgwz10</a></p><p>安装好 MySQL 后预先创建好数据库</p><figure class="highlight sql"><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><code class="hljs sql"><span class="hljs-keyword">create</span> database confluence <span class="hljs-type">character</span> <span class="hljs-keyword">set</span> UTF8;<br><span class="hljs-keyword">grant</span> <span class="hljs-keyword">all</span> <span class="hljs-keyword">on</span> confluence.<span class="hljs-operator">*</span> <span class="hljs-keyword">to</span> confluence@"%" identified <span class="hljs-keyword">by</span> "confluence";<br><span class="hljs-keyword">grant</span> <span class="hljs-keyword">all</span> <span class="hljs-keyword">on</span> confluence.<span class="hljs-operator">*</span> <span class="hljs-keyword">to</span> confluence@"localhost" identified <span class="hljs-keyword">by</span> "confluence";<br>FLUSH PRIVILEGES;<br></code></pre></td></tr></table></figure><h4 id="MySQL-数据库配置"><a href="#MySQL-数据库配置" class="headerlink" title="MySQL 数据库配置"></a>MySQL 数据库配置</h4><p>在 <code>/etc/my.cnf</code> 中配置如下参数,保存后重启 MySQL 服务</p><figure class="highlight sql"><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><code class="hljs sql">[mysqld]<br>datadir<span class="hljs-operator">=</span><span class="hljs-operator">/</span>var<span class="hljs-operator">/</span>lib<span class="hljs-operator">/</span>mysql<br>socket<span class="hljs-operator">=</span><span class="hljs-operator">/</span>var<span class="hljs-operator">/</span>lib<span class="hljs-operator">/</span>mysql<span class="hljs-operator">/</span>mysql.sock<br><span class="hljs-type">character</span><span class="hljs-operator">-</span><span class="hljs-keyword">set</span><span class="hljs-operator">-</span>server<span class="hljs-operator">=</span>utf8<br><span class="hljs-keyword">collation</span><span class="hljs-operator">-</span>server<span class="hljs-operator">=</span>utf8_bin<br><span class="hljs-keyword">default</span><span class="hljs-operator">-</span>storage<span class="hljs-operator">-</span>engine<span class="hljs-operator">=</span>INNODB<br>max_allowed_packet<span class="hljs-operator">=</span><span class="hljs-number">256</span>M<br>innodb_log_file_size<span class="hljs-operator">=</span><span class="hljs-number">2</span>GB<br>transaction<span class="hljs-operator">-</span>isolation<span class="hljs-operator">=</span>READ<span class="hljs-operator">-</span>COMMITTED<br>symbolic<span class="hljs-operator">-</span>links<span class="hljs-operator">=</span><span class="hljs-number">0</span><br>sql_mode<span class="hljs-operator">=</span>NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES <br>[mysqld_safe]<br>log<span class="hljs-operator">-</span>error<span class="hljs-operator">=</span><span class="hljs-operator">/</span>var<span class="hljs-operator">/</span>log<span class="hljs-operator">/</span>mysqld.log<br>pid<span class="hljs-operator">-</span>file<span class="hljs-operator">=</span><span class="hljs-operator">/</span>var<span class="hljs-operator">/</span>run<span class="hljs-operator">/</span>mysqld<span class="hljs-operator">/</span>mysqld.pid<br></code></pre></td></tr></table></figure><p>有可能遇到密码强度太低导致语句执行失败</p><p><a href="https://blog.csdn.net/kuluzs/article/details/51924374">https://blog.csdn.net/kuluzs/article/details/51924374</a></p><p>网页配置 Confluence 并测试数据库连接时有可能说 MySQL 排序规则应该为 utf8_bin,解决方法是手动更改</p><p><a href="https://segmentfault.com/q/1010000017240490/a-1020000017240760">https://segmentfault.com/q/1010000017240490/a-1020000017240760</a></p><h4 id="MySQL-的语句"><a href="#MySQL-的语句" class="headerlink" title="MySQL 的语句"></a>MySQL 的语句</h4><p><code>service mysqld start</code></p><p><code>service mysqld stop</code></p><p><code>service mysqld restart</code></p><h4 id="卸载语句"><a href="#卸载语句" class="headerlink" title="卸载语句"></a>卸载语句</h4><figure class="highlight awk"><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><code class="hljs awk"><span class="hljs-regexp">/etc/i</span>nit.d/confluence stop<br><span class="hljs-regexp">/opt/</span>atlassian<span class="hljs-regexp">/confluence/u</span>ninstall<br>rm -rf <span class="hljs-regexp">/opt/</span>atlassian<br>rm -rf <span class="hljs-regexp">/var/</span>atlassian<br>drop database wiki <span class="hljs-regexp">//</span>登录数据库<br></code></pre></td></tr></table></figure><h4 id="创建空间无限-Loading-解决"><a href="#创建空间无限-Loading-解决" class="headerlink" title="创建空间无限 Loading 解决"></a>创建空间无限 Loading 解决</h4><p><a href="https://confluence.atlassian.com/confkb/create-space-dialog-loads-indefinitely-586875930.html">https://confluence.atlassian.com/confkb/create-space-dialog-loads-indefinitely-586875930.html</a></p><h4 id="提高-Java-虚拟机内存"><a href="#提高-Java-虚拟机内存" class="headerlink" title="提高 Java 虚拟机内存"></a>提高 Java 虚拟机内存</h4><p><a href="https://cloud.tencent.com/info/ddc90ac3950f2d2dd3c5d7e7ca2f7661.html">https://cloud.tencent.com/info/ddc90ac3950f2d2dd3c5d7e7ca2f7661.html</a></p>]]></content>
</entry>
<entry>
<title>实训 Andorid 项目的学习资料收集</title>
<link href="/2018/11/19/%E5%AE%9E%E8%AE%AD%20Andorid%20%E9%A1%B9%E7%9B%AE%E7%9A%84%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99%E6%94%B6%E9%9B%86/"/>
<url>/2018/11/19/%E5%AE%9E%E8%AE%AD%20Andorid%20%E9%A1%B9%E7%9B%AE%E7%9A%84%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99%E6%94%B6%E9%9B%86/</url>
<content type="html"><![CDATA[<p>⚠️ 杂乱无章链接且极大可能打不开</p><h3 id="服务器搭建"><a href="#服务器搭建" class="headerlink" title="服务器搭建"></a>服务器搭建</h3><p>系统环境:</p><p>阿里云 轻量应用服务器 CentOS7.3 x64 宝塔Linux面板5.2 </p><p>应用环境:</p><p>可以使用宝塔一键部署</p><p>MySQL 5.5 </p><h3 id="Windows-上的-Tomcat-部署"><a href="#Windows-上的-Tomcat-部署" class="headerlink" title="Windows 上的 Tomcat 部署"></a>Windows 上的 Tomcat 部署</h3><p><a href="https://blog.csdn.net/gyshun/article/details/80920227">Tomcat8安装及配置步骤</a></p><h3 id="Tomcat-安装时出现-Failed-to-install-Tomcat8-service"><a href="#Tomcat-安装时出现-Failed-to-install-Tomcat8-service" class="headerlink" title="Tomcat 安装时出现 Failed to install Tomcat8 service"></a>Tomcat 安装时出现 Failed to install Tomcat8 service</h3><p><a href="https://blog.csdn.net/qq_35193403/article/details/51626437">https://blog.csdn.net/qq_35193403/article/details/51626437</a></p><h3 id="BottomNavigationView-Fragment-viewpager的APP界面基本结构设计实现"><a href="#BottomNavigationView-Fragment-viewpager的APP界面基本结构设计实现" class="headerlink" title="BottomNavigationView Fragment viewpager的APP界面基本结构设计实现"></a>BottomNavigationView Fragment viewpager的APP界面基本结构设计实现</h3><p><a href="https://blog.csdn.net/shine_qstm/article/details/78864982">BottomNavigationView+ViewPager+Fragment+TabLayout 常见设计问题解决</a></p><h3 id="简易后台"><a href="#简易后台" class="headerlink" title="简易后台"></a>简易后台</h3><p><a href="https://blog.csdn.net/f917386389/article/details/77770885">Android开发者如何搭建服务器</a></p><p><a href="https://www.jianshu.com/p/4fa6872c5917">如何给自己的Android应用快速搭建测试后台?</a></p><p><a href="https://blog.csdn.net/ljf_study/article/details/77102619?utm_source=blogxgwz0">一步一步的搭建Tomcat服务器 + servlet + android客户端</a></p><p><a href="https://blog.csdn.net/a_running_wolf/article/details/52579178">【一步一个脚印】Tomcat+MySQL为自己的APP打造服务器(3-1)Android 和 Service 的交互之GET方式</a></p><h3 id="后台接口写法"><a href="#后台接口写法" class="headerlink" title="后台接口写法"></a>后台接口写法</h3><p><a href="https://blog.csdn.net/xiaoyu940601/article/details/54950673">Android笔记:Android后台接口教程一(从零开始学习Android后台接口)Android 前后台通信</a></p><p><a href="https://blog.csdn.net/qq_30908729/article/details/79911737?utm_source=blogxgwz3">android如何调用后台接口</a></p><p><a href="https://blog.csdn.net/xiaoyu940601/article/details/54972937?utm_source=blogxgwz0">Android笔记: Android后台接口教程二Android 客户端与服务端交互Android 前后台通信 post方式</a></p><h3 id="理解-WEB-服务器,Apache-和-Tomcat-的关系"><a href="#理解-WEB-服务器,Apache-和-Tomcat-的关系" class="headerlink" title="理解 WEB 服务器,Apache 和 Tomcat 的关系"></a>理解 WEB 服务器,Apache 和 Tomcat 的关系</h3><p><a href="https://blog.csdn.net/Maxiao1204/article/details/79894708">https://blog.csdn.net/Maxiao1204/article/details/79894708</a></p><h3 id="ServLet的介绍本质理解"><a href="#ServLet的介绍本质理解" class="headerlink" title="ServLet的介绍本质理解"></a>ServLet的介绍本质理解</h3><p><a href="https://www.zhihu.com/question/21416727/answer/339012081">servlet的本质是什么,它是如何工作的?</a></p><h3 id="Servlet-的配置,WEB-3-0-以后不用在-web-xml-中配置,直接通过注解实现"><a href="#Servlet-的配置,WEB-3-0-以后不用在-web-xml-中配置,直接通过注解实现" class="headerlink" title="Servlet 的配置,WEB 3.0 以后不用在 web.xml 中配置,直接通过注解实现"></a>Servlet 的配置,WEB 3.0 以后不用在 web.xml 中配置,直接通过注解实现</h3><p><a href="https://www.cnblogs.com/qthh/p/6528685.html"><a href="https://www.cnblogs.com/qthh/p/6528685.html">使用Servlet+JDBC 开发java web应用</a></a></p><h3 id="Servlet-写法"><a href="#Servlet-写法" class="headerlink" title="Servlet 写法"></a>Servlet 写法</h3><p><a href="https://blog.csdn.net/xiaoyu940601/article/details/54950673">Android笔记:Android后台接口教程一(从零开始学习Android后台接口)Android 前后台通信</a></p><p><a href="https://blog.csdn.net/qq_42000631/article/details/82429957">【超越梦想】Android+Servlet搭建自己的app(2)——JDBC</a></p><p><a href="https://blog.csdn.net/mr_megamind/article/details/71404618">自己动手——快速搭建Java应用服务器</a></p><p><a href="https://blog.csdn.net/a_running_wolf/article/details/51763344">【一步一个脚印】Tomcat+MySQL为自己的APP打造服务器(2-3)Servlet连接MySQL数据库</a></p><p><a href="https://www.cnblogs.com/qthh/p/6528685.html/">[使用Servlet+JDBC 开发java web应用]</a></p><h3 id="Android-和-Servlet-通过-JSON-完成登录"><a href="#Android-和-Servlet-通过-JSON-完成登录" class="headerlink" title="Android 和 Servlet 通过 JSON 完成登录"></a>Android 和 Servlet 通过 JSON 完成登录</h3><p><a href="https://www.cnblogs.com/xiaoxiaoyibu/p/8592828.html">https://www.cnblogs.com/xiaoxiaoyibu/p/8592828.html</a></p><h3 id="利用-Servlet-访问数据库返回-JSON-数据"><a href="#利用-Servlet-访问数据库返回-JSON-数据" class="headerlink" title="利用 Servlet 访问数据库返回 JSON 数据"></a>利用 Servlet 访问数据库返回 JSON 数据</h3><p><a href="https://www.cnblogs.com/boguse/p/6769092.html?utm_source=itdadao&utm_medium=referral">https://www.cnblogs.com/boguse/p/6769092.html?utm_source=itdadao&utm_medium=referral</a></p><h3 id="用-GSON-解析-JSON-数组"><a href="#用-GSON-解析-JSON-数组" class="headerlink" title="用 GSON 解析 JSON 数组"></a>用 GSON 解析 JSON 数组</h3><p><a href="https://www.cnblogs.com/jianyungsun/p/6647203.html">https://www.cnblogs.com/jianyungsun/p/6647203.html</a></p><h3 id="AS开新项目下不了东西"><a href="#AS开新项目下不了东西" class="headerlink" title="AS开新项目下不了东西"></a>AS开新项目下不了东西</h3><p>因为墙太厚了,AS默认不连接代理,开了 Shadowsocks 后在AS改成auto detect proxy 就可以通过代理下载了</p><h3 id="ButterKnife-的文档"><a href="#ButterKnife-的文档" class="headerlink" title="ButterKnife 的文档"></a>ButterKnife 的文档</h3><p><a href="https://www.jianshu.com/p/63e1690c83e5">Butterknife 8.5.1使用-全面,一定要看</a></p><p>Butterknife与Recycleview,Viewholder的配合使用 参考菜鸟手机助手里面的源码实现</p><p><a href="https://github.com/conghuahuadan/CNiaoPlay/blob/master/app/src/main/java/com/chhd/cniaoplay/ui/adapter/RecommendAdapter.java">https://github.com/conghuahuadan/CNiaoPlay/blob/master/app/src/main/java/com/chhd/cniaoplay/ui/adapter/RecommendAdapter.java</a></p><h3 id="手机截屏带壳App"><a href="#手机截屏带壳App" class="headerlink" title="手机截屏带壳App"></a>手机截屏带壳App</h3><p>带壳截图</p><h3 id="notifyDataSetChanged不起作用的原因"><a href="#notifyDataSetChanged不起作用的原因" class="headerlink" title="notifyDataSetChanged不起作用的原因"></a>notifyDataSetChanged不起作用的原因</h3><p>在于数据没有被刷新,我的 BUG 在于传入 adapter 的是一个 string,重新赋值是指向另一块内存地址,原先内存的地址的值没有被改变,即数据没有被刷新,解决方法是通过 java 反射,参考下面</p><p><a href="https://blog.csdn.net/a925907195/article/details/46975171">Java里不改变内存的指向而改变String的值</a></p><p>对于List之类的集合,则先调用clear,再调用 addAll(),这样能确保始终指向同一块内存,最后才用 notifyDataSetChanged。</p><h3 id="notifyDataSetChanged-方法调用出现IllegalStateException-问题的解决"><a href="#notifyDataSetChanged-方法调用出现IllegalStateException-问题的解决" class="headerlink" title="notifyDataSetChanged() 方法调用出现IllegalStateException 问题的解决"></a>notifyDataSetChanged() 方法调用出现IllegalStateException 问题的解决</h3><p>线程安全问题,异常如下,notifyDataSetChanged() 不要在子线程中调用</p><p>Cannot call this method while RecyclerView is computing a layout or scrolling android.support.v7.widget.RecyclerView.assertNotInLayoutOrScroll</p><p>解决思路是用 handler,通知主线程 handlerMessage 来调用 notifyDataSetChanged</p><p><a href="https://blog.csdn.net/hierophantzw/article/details/46929519">https://blog.csdn.net/hierophantzw/article/details/46929519</a></p><h3 id="JSoup检索不到想要的元素不生效"><a href="#JSoup检索不到想要的元素不生效" class="headerlink" title="JSoup检索不到想要的元素不生效"></a>JSoup检索不到想要的元素不生效</h3><p>网站那边可能做了反爬虫</p><ol><li>加 User-Agent,伪装成浏览器</li><li>Chrome 的检查的 copy selector 不一定准确,自己手动写 selector</li></ol><h3 id="Glide加载圆形图片到-Imageview"><a href="#Glide加载圆形图片到-Imageview" class="headerlink" title="Glide加载圆形图片到 Imageview"></a>Glide加载圆形图片到 Imageview</h3><p>Glide 的4.0以后才有</p><figure class="highlight reasonml"><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><code class="hljs reasonml"><span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">Glide</span>.</span></span><span class="hljs-keyword">with</span>(this).load(url).<br>apply(<span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">RequestOptions</span>.</span></span>bitmap<span class="hljs-constructor">Transform(<span class="hljs-params">new</span> CircleCrop()</span>)).<br>into(imageView);<br></code></pre></td></tr></table></figure><p><a href="https://blog.csdn.net/qq_36523667/article/details/79492928">Glide4.0后支持圆形图片及其使用方式</a></p><h3 id="SlideAdapter(RecycleView-高级版)"><a href="#SlideAdapter(RecycleView-高级版)" class="headerlink" title="SlideAdapter(RecycleView 高级版)"></a><strong>SlideAdapter</strong>(RecycleView 高级版)</h3><p>一句代码搞定 RecycleView 侧滑菜单、添加头部底部、加载更多 , 像 Glide 一样简洁的链式调用轻松实现 Adapter</p><p><a href="https://github.com/yhaolpz/SlideAdapter">https://github.com/yhaolpz/SlideAdapter</a></p><h3 id="PNG-压缩"><a href="#PNG-压缩" class="headerlink" title="PNG 压缩"></a>PNG 压缩</h3><p><a href="https://tinypng.com/">https://tinypng.com/</a></p><h3 id="Android-开发博客"><a href="#Android-开发博客" class="headerlink" title="Android 开发博客"></a>Android 开发博客</h3><p><a href="https://rengwuxian.com/">https://rengwuxian.com/</a></p><h3 id="Android-开发好的文章"><a href="#Android-开发好的文章" class="headerlink" title="Android 开发好的文章"></a>Android 开发好的文章</h3><p><a href="https://juejin.im/post/5c00ec39e51d4555ec0394f6">Gradle build 编译只要1s</a></p><p><a href="https://juejin.im/post/5c09f9daf265da61193ba4f2">Android程序调试竟简单如斯</a></p><p><a href="https://juejin.im/post/5bd5b96751882526986e744f">手把手教你用RecyclerView实现猫眼电影选择效果</a></p><h3 id="面试的一个教程,写得很好"><a href="#面试的一个教程,写得很好" class="headerlink" title="面试的一个教程,写得很好"></a>面试的一个教程,写得很好</h3><p><a href="https://juejin.im/post/5bf212a46fb9a049de6cf57c">给扔物线 HenCoder Plus 学员的一次分享文字版</a></p><h3 id="一个实用的-WebView-浏览页面,可直接使用"><a href="#一个实用的-WebView-浏览页面,可直接使用" class="headerlink" title="一个实用的 WebView 浏览页面,可直接使用"></a>一个实用的 WebView 浏览页面,可直接使用</h3><p><a href="https://juejin.im/post/5a7d8744f265da4e7a784c8c">https://juejin.im/post/5a7d8744f265da4e7a784c8c</a></p><h3 id="Material-Design-超级详细教程"><a href="#Material-Design-超级详细教程" class="headerlink" title="Material Design 超级详细教程"></a>Material Design 超级详细教程</h3><p><a href="https://www.uisdc.com/comprehensive-material-design-note">重磅教程!帮你全面彻底搞定Material design的学习笔记</a></p><h3 id="Android-Datepicker-的使用及其属性"><a href="#Android-Datepicker-的使用及其属性" class="headerlink" title="Android Datepicker 的使用及其属性"></a>Android Datepicker 的使用及其属性</h3><p>[<a href="https://www.cnblogs.com/xqxacm/p/4567809.html">安卓开发_浅谈DatePicker日期选择器</a></p><p><a href="https://blog.csdn.net/lmq121210/article/details/78247371">android datePicker属性</a></p>]]></content>
</entry>
<entry>
<title>Android 平台下的播放器框架资料收藏</title>
<link href="/2018/09/13/Android%20%E5%B9%B3%E5%8F%B0%E4%B8%8B%E7%9A%84%E6%92%AD%E6%94%BE%E5%99%A8%E6%A1%86%E6%9E%B6%E8%B5%84%E6%96%99%E6%94%B6%E8%97%8F/"/>
<url>/2018/09/13/Android%20%E5%B9%B3%E5%8F%B0%E4%B8%8B%E7%9A%84%E6%92%AD%E6%94%BE%E5%99%A8%E6%A1%86%E6%9E%B6%E8%B5%84%E6%96%99%E6%94%B6%E8%97%8F/</url>
<content type="html"><![CDATA[<p>实习时做短视频优化查到比较多关于Android平台下的播放器框架资料,先把链接贴上来,迟点再整理。(懒= =)</p><h2 id="Andorid视频播放"><a href="#Andorid视频播放" class="headerlink" title="Andorid视频播放"></a>Andorid视频播放</h2><p><a href="https://blog.csdn.net/pangpang123654/article/details/78125038">硬解码与软解码的选择</a></p><p><a href="https://blog.csdn.net/Guofengpu/article/details/51544454">MediaCodec介绍</a></p><p><a href="https://blog.csdn.net/hejjunlin/article/details/53729575">MediaCodec,讲得好</a></p><p><a href="http://www.cnblogs.com/roger-yu/p/5635494.html">MediaCodec中文文档</a></p><p><a href="http://sparkgis.com/2018/07/10/android-mediaplayer-%E5%92%8C-mediacodec-%E7%9A%84%E5%8C%BA%E5%88%AB%E5%92%8C%E8%81%94%E7%B3%BB%EF%BC%88%E4%B8%80%EF%BC%89/">Android MediaPlayer 和 MediaCodec 的区别和联系</a></p><h2 id="Exoplayer"><a href="#Exoplayer" class="headerlink" title="Exoplayer"></a>Exoplayer</h2><p><a href="https://github.com/google/ExoPlayer">官网</a></p><p><a href="https://google.github.io/ExoPlayer/">官方指南</a></p><p><a href="http://google.github.io/ExoPlayer/doc/reference/">官方类参考</a></p><h2 id="ExoPlayer播放器对比"><a href="#ExoPlayer播放器对比" class="headerlink" title="ExoPlayer播放器对比"></a>ExoPlayer播放器对比</h2><p><a href="https://academy.realm.io/posts/360andev-effie-barak-switching-exoplayer-better-video-android/">官方介绍</a></p><p><a href="https://juejin.im/post/5a9f5726f265da239f06e874">掘金的主流播放器对比</a></p><p><a href="https://blog.csdn.net/pangpang123654/article/details/78256361">ExoPlayer VS IjkPlayer</a></p><p><a href="https://www.jianshu.com/p/74dbee4e0148">android平台视频框架小调研</a></p><h2 id="Exoplayer使用"><a href="#Exoplayer使用" class="headerlink" title="Exoplayer使用"></a>Exoplayer使用</h2><p><a href="https://qiita.com/niusounds/items/cce4ff69f5911908259b#%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%ABexoplayer%E3%82%92%E8%BF%BD%E5%8A%A0%E3%81%99%E3%82%8B">岛国码农介绍</a></p><p><a href="https://codelabs.developers.google.com/codelabs/exoplayer-intro/#4">谷歌CodeLabs</a></p><h2 id="Exoplayer过程分析"><a href="#Exoplayer过程分析" class="headerlink" title="Exoplayer过程分析"></a>Exoplayer过程分析</h2><p><a href="http://yummylau.com/2018/06/01/%E5%A4%9A%E5%AA%92%E4%BD%93_2018-06-01_ExoPlayer%E7%B3%BB%E5%88%97%E4%B8%80%E4%B9%8B%E5%A4%9A%E5%AA%92%E4%BD%93%E8%B5%84%E6%BA%90%E5%8A%A0%E8%BD%BD/">多媒体加载</a></p><p><a href="http://yummylau.com/2018/06/02/%E5%A4%9A%E5%AA%92%E4%BD%93_2018-06-02_ExoPlayer%E7%B3%BB%E5%88%97%E4%BA%8C%E4%B9%8B%E5%B8%A6%E5%AE%BD%E9%A2%84%E6%B5%8B/">带宽预测</a></p><h2 id="Exoplayer缓存Cache"><a href="#Exoplayer缓存Cache" class="headerlink" title="Exoplayer缓存Cache"></a>Exoplayer缓存Cache</h2><p><a href="https://blog.csdn.net/john_chedan/article/details/80692483">缓存实现</a></p><p><a href="https://www.programcreek.com/java-api-examples/index.php?api=com.google.android.exoplayer2.upstream.cache.LeastRecentlyUsedCacheEvictor">缓存大小设置</a></p><p><a href="https://stackoverflow.com/questions/42073937/exoplayer-generalize-simplecache-behaviour">时效性变化的url处理</a></p><h2 id="Exoplayer源码修改"><a href="#Exoplayer源码修改" class="headerlink" title="Exoplayer源码修改"></a>Exoplayer源码修改</h2><p><a href="https://blog.csdn.net/u010302327/article/details/79788705">https://blog.csdn.net/u010302327/article/details/79788705</a></p><h2 id="IJKplayer"><a href="#IJKplayer" class="headerlink" title="IJKplayer"></a>IJKplayer</h2><p><a href="https://github.com/Bilibili/ijkplayer">官网</a></p><p><a href="https://www.jianshu.com/p/55fbfd5b564a">小结</a></p><p><a href="https://www.jianshu.com/p/220b00d00deb">问题集锦</a></p><h2 id="IJKplayer编译"><a href="#IJKplayer编译" class="headerlink" title="IJKplayer编译"></a>IJKplayer编译</h2><p><a href="https://www.jianshu.com/p/bd289e25d272">编译so支持HTTPS</a></p><p><a href="https://www.jianshu.com/p/2c1413486b01">编译so1</a></p><p><a href="https://blog.csdn.net/zy987654zy/article/details/53126457">编译so2</a></p><h2 id="IJKplayer关于卡顿的Github-Issue"><a href="#IJKplayer关于卡顿的Github-Issue" class="headerlink" title="IJKplayer关于卡顿的Github Issue"></a>IJKplayer关于卡顿的Github Issue</h2><p><a href="https://github.com/Bilibili/ijkplayer/issues/3179">https://github.com/Bilibili/ijkplayer/issues/3179</a></p><p><a href="https://github.com/Bilibili/ijkplayer/issues/3048">https://github.com/Bilibili/ijkplayer/issues/3048</a></p><p><a href="https://github.com/Bilibili/ijkplayer/issues/4094">https://github.com/Bilibili/ijkplayer/issues/4094</a></p><p><a href="https://github.com/Bilibili/ijkplayer/issues/4319">https://github.com/Bilibili/ijkplayer/issues/4319</a></p><p><a href="https://github.com/Bilibili/ijkplayer/issues/3493">https://github.com/Bilibili/ijkplayer/issues/3493</a></p>]]></content>
</entry>
<entry>
<title>Android 实习笔记</title>
<link href="/2018/09/12/Andorid%20%E5%AE%9E%E4%B9%A0%E7%AC%94%E8%AE%B0/"/>
<url>/2018/09/12/Andorid%20%E5%AE%9E%E4%B9%A0%E7%AC%94%E8%AE%B0/</url>
<content type="html"><![CDATA[<p>⚠️ 杂乱无章链接且极大可能打不开</p><h4 id="版本控制"><a href="#版本控制" class="headerlink" title="版本控制"></a>版本控制</h4><p>Git 是流行的代码版本控制系统,Gerrit是代码审核系统,实现Web界面上的代码版本控制。</p><p>git checkout 撤销修改,让工作区文件回到最近一次 git commit 或 git add 时的状态</p><h4 id="JAVA多线程访问同一个可变变量,需增加同步机制"><a href="#JAVA多线程访问同一个可变变量,需增加同步机制" class="headerlink" title="JAVA多线程访问同一个可变变量,需增加同步机制"></a>JAVA多线程访问同一个可变变量,需增加同步机制</h4><p>JVM中存在一个主内存(Java Heap Memory),Java 中所有变量都储存在主内存中,对于所有线程都是共享的。</p><p>每个线程都有自己的工作内存 (Working Memory),工作内存中保存的是主存中某些变量的拷贝,线程对所有变量的操作都是在工作内存中进行</p><p>线程之间无法相互直接访问,变量传递均需要通过主内存完成。</p><p>根据上述内存模型的定义,要在多个线程间安全的同步共享数据就必须使用锁机制,将某线程中更新的数据从其工作内存中刷新至主内存,并确保其他线程从主内存获取此数据更新后的值再使用</p><h4 id="使用-System-arraycopy-进行数组复制"><a href="#使用-System-arraycopy-进行数组复制" class="headerlink" title="使用 System.arraycopy() 进行数组复制"></a>使用 System.arraycopy() 进行数组复制</h4><p>在将一个数组对象复制成另外一个数组对象时,不要自己使用循环复制,可以使用JAVA提供的System.arraycopy() 功能来复制数据对象,避免出错,效率更高</p><h4 id="aar库文件和-jar库文件的区别"><a href="#aar库文件和-jar库文件的区别" class="headerlink" title=".aar库文件和.jar库文件的区别"></a>.aar库文件和.jar库文件的区别</h4><p>aar 文件是建立在 jar 文件的基础之上, aar 是 jar 文件的一个变种。本质上没有什么区别,都是压缩包,<strong>只是能包含的内容不一样</strong>。</p><ul><li>jar 只包含了 class 文件与清单文件。虽然也能包含资源文件,但不过是文本资源和图片资源,不能包含 Android 平台下的 drawable 以及各种 xml 文件.</li><li>aar 包括的东西更多一些,包含所有资源文件、第三方库文件、so 文件、class 以及 res 资源文件全部包含。</li></ul><h4 id="Android接口回调机制"><a href="#Android接口回调机制" class="headerlink" title="Android接口回调机制"></a>Android接口回调机制</h4><p>接口回调的意思即,注册之后并不立马执行,而在某个时机触发执行 。</p><p>回调方法就是一个通过方法指针来调用的方法(接口),如果我将这个方法的指针(地址,引用)通过形参传递到另一个类的某个方法里(setCallBack 注册),那么当这个类调用该方法里面我所传入的指针时,就能调用我这边的方法。 </p><p>整个过程就是我传入方法 A 的地址,你接收,并在某个时刻回调我这边的 A 方法。由于 Java 没办法操作指针,于是它用接口来实现。 </p><p>主要步骤如下:</p><ul><li>定义接口 Callback ,包含回调方法 callback();</li><li>B 类提供注册的方法,并设定在某个条件下会回调接口方法;</li><li>A 类提供接口的实现方法,并注册到 B 类,把方法地址传进去。</li></ul><p>这样,在需要的时候,可用 CamCallback 接口成员调用 callback() 方法,完成回调了。</p><p>例子:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><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></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">BService</span> </span>{<br> <br><span class="hljs-keyword">private</span> OnParserCallBack callBack;<br> <span class="hljs-comment">//B类中定义接口定义回调方法</span><br><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">OnParserCallBack</span> </span>{<br><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">OnParserComplete</span><span class="hljs-params">(List<HoursWeatherBean> list,</span></span><br><span class="hljs-params"><span class="hljs-function">PMBean pmBean, WeatherBean weatherBean)</span></span>;<br>}<br><span class="hljs-comment">//注册用于接收A类传递过来数据</span><br><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setCallBack</span><span class="hljs-params">(OnParserCallBack callback)</span> </span>{<br><span class="hljs-keyword">this</span>.callBack = callback;<br>}<br><br><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">removeCallback</span><span class="hljs-params">()</span></span>{<br>callBack = <span class="hljs-keyword">null</span>;<br>}<br> <br> <span class="hljs-comment">//dosomething()</span><br> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">getCityWeather</span><span class="hljs-params">()</span> </span>{<br><span class="hljs-keyword">if</span>(callBack!=<span class="hljs-keyword">null</span>){<br> <span class="hljs-comment">//这里使用的是A类传递的数据</span><br>callBack.OnParserComplete(list, pmBean, weatherBean);<br><br>}<br> <br>}<br> <br> <br><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Amain</span></span>{<br> <span class="hljs-keyword">private</span> BService mbService;<br> <span class="hljs-comment">//注册</span><br> mbService.setCallBack(<span class="hljs-keyword">new</span> OnParserCallBack(){<br> <span class="hljs-comment">//回调方法</span><br><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">OnParserComplete</span><span class="hljs-params">(List<HoursWeatherBean> list, PMBean pmBean,</span></span><br><span class="hljs-params"><span class="hljs-function">WeatherBean weatherBean)</span> </span>{<br><span class="hljs-comment">//接收数据后开始用于显示</span><br>setHourViews(list);<br>setPmViews(pmBean);<br>setWeather(weatherBean);<br>}<br> });<br> mbService.getCityWeather();<br>}<br></code></pre></td></tr></table></figure><p>另外的网页参考:</p><p><a href="http://www.apkbus.com/thread-589290-1-1.html">http://www.apkbus.com/thread-589290-1-1.html</a></p><p><a href="https://www.jianshu.com/p/f05730ab5d05">https://www.jianshu.com/p/f05730ab5d05</a></p><h4 id="EditText-不换行"><a href="#EditText-不换行" class="headerlink" title="EditText 不换行"></a>EditText 不换行</h4><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs xml">android:singleLine="true"<br></code></pre></td></tr></table></figure><h4 id="Java-中-int-转-String-的三种方式"><a href="#Java-中-int-转-String-的三种方式" class="headerlink" title="Java 中 int 转 String 的三种方式"></a>Java 中 int 转 String 的三种方式</h4><ol><li>a+”“ 这种效率最低</li><li>String.valueOf(a)</li><li>Integer.toString(a)</li></ol><h4 id="牛逼的-material-dialogs"><a href="#牛逼的-material-dialogs" class="headerlink" title="牛逼的 material-dialogs"></a>牛逼的 material-dialogs</h4><p><a href="https://github.com/afollestad/material-dialogs">https://github.com/afollestad/material-dialogs</a></p><h4 id="解决支持库版本兼容问题"><a href="#解决支持库版本兼容问题" class="headerlink" title="解决支持库版本兼容问题"></a>解决支持库版本兼容问题</h4><p>如果引用的第三方库的支持库版本低于(或者不一致)app build.gradle 中的支持库版本,可能会出现如下问题:</p><p>all com.android.support libraries must use the exact same version specification(mixing versions can lead to runtime crashes)</p><p>去改第三方库所用的支持库版本比较麻烦,如果用的库很多的话工作量很大。这个时候我们可以考虑强制让所有模块都用相同的支持库版本。</p><p>在 app build.gradle 中添加:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs java">configurations.all {<br> resolutionStrategy.eachDependency { DependencyResolveDetails details -><br> def requested = details.<span class="hljs-function">requested</span><br><span class="hljs-function"> <span class="hljs-title">if</span> <span class="hljs-params">(requested.group == <span class="hljs-string">'com.android.support'</span>)</span> </span>{<br> <span class="hljs-keyword">if</span> (!requested.name.startsWith(<span class="hljs-string">"multidex"</span>)) {<br> details.useVersion <span class="hljs-string">'26.0.1'</span><br> }<br> }<br> }<br>}<br><br></code></pre></td></tr></table></figure><h4 id="TextView滚动设置"><a href="#TextView滚动设置" class="headerlink" title="TextView滚动设置"></a>TextView滚动设置</h4><p>只要在布局的 xml 文件中设置 TextView 的属性:</p><figure class="highlight avrasm"><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><code class="hljs avrasm"><span class="hljs-symbol">android:</span>maxLines = <span class="hljs-string">"AN_INTEGER"</span><br><br><span class="hljs-symbol">android:</span>scrollbars = <span class="hljs-string">"vertical"</span><br></code></pre></td></tr></table></figure><p>然后在代码中用:</p><figure class="highlight haxe"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs haxe">yourTextView.setMovementMethod(<span class="hljs-keyword">new</span> <span class="hljs-type">ScrollingMovementMethod</span>())<br></code></pre></td></tr></table></figure><p>它可以自由的滚动了。</p><h4 id="Android-文件下载三种基本方式"><a href="#Android-文件下载三种基本方式" class="headerlink" title="Android 文件下载三种基本方式"></a>Android 文件下载三种基本方式</h4><h5 id="1-自己封装-URLConnection-连接请求类"><a href="#1-自己封装-URLConnection-连接请求类" class="headerlink" title="1.自己封装 URLConnection 连接请求类"></a>1.自己封装 URLConnection 连接请求类</h5><p>这种方式在 Android 刚兴起的时候,很少下载封装框架,就自己封装了。虽然一般的文件都能下载,但这种方式缺点很多,不稳定或者各种各样的问题会出现。 </p><h5 id="2-Android-自定的下载管理(会在-notification-显示下载的进度,同时可以暂停、重新连接等)"><a href="#2-Android-自定的下载管理(会在-notification-显示下载的进度,同时可以暂停、重新连接等)" class="headerlink" title="2.Android 自定的下载管理(会在 notification 显示下载的进度,同时可以暂停、重新连接等)"></a>2.Android 自定的下载管理(会在 notification 显示下载的进度,同时可以暂停、重新连接等)</h5><p>这种方式其实就是交给了 Android 系统的另一个 app 去下载管理。这样的好处不会消耗该APP 的 CPU 资源。缺点是:控制起来很不灵活。 </p><p><a href="https://www.jianshu.com/p/46fd1c253701">https://www.jianshu.com/p/46fd1c253701</a></p><p><a href="https://www.cnblogs.com/gooder2-android/p/8966045.html">https://www.cnblogs.com/gooder2-android/p/8966045.html</a></p><h5 id="3-使用第三方-okhttp-网络请求框架"><a href="#3-使用第三方-okhttp-网络请求框架" class="headerlink" title="3.使用第三方 okhttp 网络请求框架"></a>3.使用第三方 okhttp 网络请求框架</h5><p>okhttp 是一个很有名气的开源框架,目前已经很多大公司都直接使用它作为网络请求库(七牛云 SDK, 阿里云 SDK)。 且里面集成了很多优势,包括 okio (一个 I/O 框架,优化内存与 CPU)。</p><p>综合来看,第三种方案是最佳的,是目前最流行的下载方案。</p><p>第三方框架还研究了封装 okhttp 的<a href="https://github.com/jeasonlzy/okhttp-OkGo">OKgo</a></p><p><a href="https://github.com/AriaLyy/Aria">Aria</a> </p><h4 id="Android-6-0-以上文件读写权限"><a href="#Android-6-0-以上文件读写权限" class="headerlink" title="Android 6.0 以上文件读写权限"></a>Android 6.0 以上文件读写权限</h4><p>除了在清单文件中声明权限,还需要在访问文件时动态申请权限</p><h5 id="1、AndroidManifest-xml-文件添加"><a href="#1、AndroidManifest-xml-文件添加" class="headerlink" title="1、AndroidManifest.xml 文件添加:"></a>1、AndroidManifest.xml 文件添加:</h5><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs xml"> <span class="hljs-tag"></<span class="hljs-name">application</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">uses-permission</span> <span class="hljs-attr">android:name</span>=<span class="hljs-string">"android.permission.READ_EXTERNAL_STORAGE"</span>/></span><br> <span class="hljs-tag"><<span class="hljs-name">uses-permission</span> <span class="hljs-attr">android:name</span>=<span class="hljs-string">"android.permission.WRITE_EXTERNAL_STORAGE"</span>/></span><br><span class="hljs-tag"></<span class="hljs-name">manifest</span>></span><br></code></pre></td></tr></table></figure><h5 id="2、onCreate-或其他访问文件位置添加授权"><a href="#2、onCreate-或其他访问文件位置添加授权" class="headerlink" title="2、onCreate() 或其他访问文件位置添加授权"></a>2、onCreate() 或其他访问文件位置添加授权</h5><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">checkPermission</span><span class="hljs-params">()</span> </span>{<br> <span class="hljs-comment">//检查权限(NEED_PERMISSION)是否被授权 PackageManager.PERMISSION_GRANTED表示同意授权</span><br> <span class="hljs-keyword">if</span> (ActivityCompat.checkSelfPermission(<span class="hljs-keyword">this</span>, Manifest.permission.WRITE_EXTERNAL_STORAGE)<br> != PackageManager.PERMISSION_GRANTED) {<br> <span class="hljs-comment">//用户已经拒绝过一次,再次弹出权限申请对话框需要给用户一个解释</span><br> <span class="hljs-keyword">if</span> (ActivityCompat.shouldShowRequestPermissionRationale(<span class="hljs-keyword">this</span>, Manifest.permission<br> .WRITE_EXTERNAL_STORAGE)) {<br> Toast.makeText(<span class="hljs-keyword">this</span>, <span class="hljs-string">"请开通相关权限,否则无法正常使用本应用!"</span>, Toast.LENGTH_SHORT).show();<br> }<br> <span class="hljs-comment">//申请权限</span><br> ActivityCompat.requestPermissions(<span class="hljs-keyword">this</span>, <span class="hljs-keyword">new</span> String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_WRITE_EXTERNAL_STORAGE);<br><br> } <span class="hljs-keyword">else</span> {<br> Toast.makeText(<span class="hljs-keyword">this</span>, <span class="hljs-string">"授权成功!"</span>, Toast.LENGTH_SHORT).show();<br> Log.e(TAG_SERVICE, <span class="hljs-string">"checkPermission: 已经授权!"</span>);<br> }<br>}<br></code></pre></td></tr></table></figure><p> 没有第二步的话需要自己去手机的应用程序设置手动允许权限。</p><h4 id="Android-7-0-FileProvider-问题"><a href="#Android-7-0-FileProvider-问题" class="headerlink" title="Android 7.0 FileProvider 问题"></a>Android 7.0 FileProvider 问题</h4><p><a href="https://blog.csdn.net/growing_tree/article/details/71190741">https://blog.csdn.net/growing_tree/article/details/71190741</a></p><h4 id="lambda-表达式"><a href="#lambda-表达式" class="headerlink" title="lambda 表达式"></a>lambda 表达式</h4><p>Java的新特性,目的是使得代码更加简洁,只有一个待实现方法的接口,都可以使用 Lambda表达式的写法,例如</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">// λ</span><br><span class="hljs-keyword">return</span> (<span class="hljs-keyword">new</span> Runnable(){<br> <span class="hljs-meta">@Override</span><br> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">run</span><span class="hljs-params">()</span></span>{<br> }<br>});<br></code></pre></td></tr></table></figure><p>转成 Lanbda 表达式就是</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">return</span> ()->{};<br></code></pre></td></tr></table></figure><p>如需为您的项目启用 Java 8 语言功能和 Jack,请在模块层级的 build.gradle 文件中输入以下内容: </p><figure class="highlight dts"><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><code class="hljs dts"><span class="hljs-class">android </span>{<br> ...<br> <span class="hljs-class">defaultConfig </span>{<br> ...<br> <span class="hljs-class">jackOptions </span>{<br> enabled true<br> }<br> }<br> <span class="hljs-class">compileOptions </span>{<br> sourceCompatibility JavaVersion.VERSION_1_8<br> targetCompatibility JavaVersion.VERSION_1_8<br> }<br>}<br></code></pre></td></tr></table></figure><h4 id="Jsoup-安卓端的爬虫"><a href="#Jsoup-安卓端的爬虫" class="headerlink" title="Jsoup 安卓端的爬虫"></a>Jsoup 安卓端的爬虫</h4><p>加库后用三行代码,即可获得应用名到应用包名的转换。感谢酷安</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs java">Document doc = Jsoup.connect(<span class="hljs-string">"https://www.coolapk.com/search?q="</span>+pack_name).get();<br>Elements res =doc.select(<span class="hljs-string">"#game_left > div > a:nth-child(2)"</span>);<br>String ss = res.attr(<span class="hljs-string">"href"</span>).substring(<span class="hljs-number">5</span>);<br></code></pre></td></tr></table></figure><h4 id="解决网络请求多线程的骚操作"><a href="#解决网络请求多线程的骚操作" class="headerlink" title="解决网络请求多线程的骚操作"></a>解决网络请求多线程的骚操作</h4><p>问题是:如何让主线程等待子线程获得网络数据后再继续运行? </p><p>设网络数据为全局变量 x,再设一个全局 flag 变量。设全局变量是为了让变量可访问,但不知会否引起安全和效率问题。</p><p>主线程设置 flag 变量的死循环,子线程执行网络请求,成功修改 x 完毕再修改 flag 变量,使得主线程离开死循环继续执行。这时,主线程就能使用到存储了网络数据的 x 变量。(机智)</p><p><a href="https://bbs.csdn.net/topics/391838191">https://bbs.csdn.net/topics/391838191</a></p><h4 id="AsyncTask-优点缺点"><a href="#AsyncTask-优点缺点" class="headerlink" title="AsyncTask 优点缺点"></a>AsyncTask 优点缺点</h4><p>优点:简单快捷</p><p>缺点:后台真正只有一个线程,多线程是串行执行的</p><p><a href="https://blog.csdn.net/evan123mg/article/details/52960339">https://blog.csdn.net/evan123mg/article/details/52960339</a></p><h4 id="Handler学习"><a href="#Handler学习" class="headerlink" title="Handler学习"></a>Handler学习</h4><p><a href="https://blog.csdn.net/u010177022/article/details/63278070">https://blog.csdn.net/u010177022/article/details/63278070</a></p><p><a href="https://blog.csdn.net/songmingzhan/article/details/78408383">https://blog.csdn.net/songmingzhan/article/details/78408383</a></p><p><a href="https://www.cnblogs.com/ryanleee/p/8204450.html">https://www.cnblogs.com/ryanleee/p/8204450.html</a></p><p><a href="https://www.cnblogs.com/android007/archive/2012/05/10/2494766.html">https://www.cnblogs.com/android007/archive/2012/05/10/2494766.html</a></p><p>避免内存泄漏</p><p><a href="https://www.cnblogs.com/JohnTsai/p/5259869.html">https://www.cnblogs.com/JohnTsai/p/5259869.html</a></p><h4 id="主线程给子线程传参数"><a href="#主线程给子线程传参数" class="headerlink" title="主线程给子线程传参数"></a>主线程给子线程传参数</h4><p><a href="https://blog.csdn.net/choubaoguai/article/details/23671441">https://blog.csdn.net/choubaoguai/article/details/23671441</a></p><ol><li><p>构造函数传递数据</p><p>定义一个线程类,扩展 Thread,增加一个成员变量,用来保存传进来的参数。新加一个拷贝构造函数,拷贝写入到成员变量。</p></li><li><p>变量和方法传递数据</p></li><li><p>回调函数</p></li></ol><h4 id="ADB-快捷从电脑安装apk到手机"><a href="#ADB-快捷从电脑安装apk到手机" class="headerlink" title="ADB 快捷从电脑安装apk到手机"></a>ADB 快捷从电脑安装apk到手机</h4><p>打开 cmd,输入指令,路径可以直接从资源管理器拖过去</p><figure class="highlight cmake"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cmake">adb <span class="hljs-keyword">install</span> -r 路径<br></code></pre></td></tr></table></figure><h4 id="注解:编译时注解和运行时注解"><a href="#注解:编译时注解和运行时注解" class="headerlink" title="注解:编译时注解和运行时注解"></a>注解:编译时注解和运行时注解</h4><p><a href="http://www.mamicode.com/info-detail-1317919.html">http://www.mamicode.com/info-detail-1317919.html</a></p><p><a href="http://www.importnew.com/1796.html">http://www.importnew.com/1796.html</a></p><h4 id="动态权限申请"><a href="#动态权限申请" class="headerlink" title="动态权限申请"></a>动态权限申请</h4><p><a href="https://github.com/mylhyl/AndroidAcp">https://github.com/mylhyl/AndroidAcp</a></p><h4 id="Android-存储路径"><a href="#Android-存储路径" class="headerlink" title="Android 存储路径"></a>Android 存储路径</h4><p>补充:对于现在市面上很多 Android 设备,自带了一个大的存储空间,一般是 8GB 或 16GB,并且又支持了 sdCard 扩展,对于这样的设备,使用 Enviroment.getExternalStorageDirectory() 方法只能获取到设备自带的存储空间,对于另外扩展的 sdCard 而言,需要修改路径。 </p><p>保存到应用的内部文件夹——在 “Android/Data/应用包名/…”路径下,卸载应用时也会一并清除</p><p>通过 getExternalFilesDir() 方法可以获取到 SDCard/Android/data/你的应用的包名/files/ 目录,一般放一些长时间保存的数据 </p><p>通过 getExternalCacheDir() 方法可以获取到 SDCard/Android/data/你的应用包名/cache/目录,一般存放临时缓存数据 </p><p>应用外部的话,可以用 Environment.getExternalStorageDirectory() 来索取到默认内置存储的根路径,即 “/storage/emulated/0”,这种情况下卸载应用时不会清除哦 </p><h4 id="Handler-理解源码分析"><a href="#Handler-理解源码分析" class="headerlink" title="Handler 理解源码分析"></a>Handler 理解源码分析</h4><p><a href="https://blog.csdn.net/lishuangling21/article/details/70767586">https://blog.csdn.net/lishuangling21/article/details/70767586</a></p><h4 id="获取-Android-手机里所有已安装的APP"><a href="#获取-Android-手机里所有已安装的APP" class="headerlink" title="获取 Android 手机里所有已安装的APP"></a>获取 Android 手机里所有已安装的APP</h4><p><a href="https://blog.csdn.net/lishuangling21/article/details/50789715">https://blog.csdn.net/lishuangling21/article/details/50789715</a></p><h4 id="Eclipse-copy-风格的快捷键"><a href="#Eclipse-copy-风格的快捷键" class="headerlink" title="Eclipse copy 风格的快捷键"></a>Eclipse copy 风格的快捷键</h4><p>ctrl+H 找有没有引用</p><p>ctrl+shift+R 进入文件的资源管理器路径</p><h4 id="项目恢复"><a href="#项目恢复" class="headerlink" title="项目恢复"></a>项目恢复</h4><p>资源管理器中右键模块→ GIT → Revert →找到相应的模块项目恢复即可</p><h4 id="工程资源清理"><a href="#工程资源清理" class="headerlink" title="工程资源清理"></a>工程资源清理</h4><p><a href="https://blog.csdn.net/caoxiao90/article/details/51057986">https://blog.csdn.net/caoxiao90/article/details/51057986</a></p><p>打开 AS,点击工具栏的 Analyze-Run Inspection by Name-输入 unused resources-选择要搜索的范围回车-查看搜索结果并删除无用的资源文件 </p><p>出来运行结果后,展开到最小条目后,双击打开文件,再在资源管理器右上方点击多重圆圈按钮 “Scroll from source”,定位到具体文件夹,注意最好要在 Android 视图方式打开,可以合并同类资源到同一个文件夹下面,然后直接删除文件夹可以一次性删除多个。删除时要选中 Safe search,会进行再次检查有没有 usage,最后才确认是否删除</p><p>在 Version Control 中可以找到改动,便于检查</p><p>确保效果和不出差错,善于利用 ctrl+H 找有没有引用和 ctrl+shift+R 进入文件的资源管理器路径</p><h4 id="【Android-珍藏】推荐10个炫酷的开源库"><a href="#【Android-珍藏】推荐10个炫酷的开源库" class="headerlink" title="【Android 珍藏】推荐10个炫酷的开源库"></a>【Android 珍藏】推荐10个炫酷的开源库</h4><p><a href="https://juejin.im/post/5b50898ef265da0fa21a7f0f">https://juejin.im/post/5b50898ef265da0fa21a7f0f</a></p><h4 id="ButterKnife-BindView-时报-Required-view-ID-was-not-found-异常"><a href="#ButterKnife-BindView-时报-Required-view-ID-was-not-found-异常" class="headerlink" title="ButterKnife@BindView 时报 Required view ID was not found 异常"></a>ButterKnife@BindView 时报 Required view ID was not found 异常</h4><p>解决思路:在 @BindView 前面加上 @Nullable 或者 @Optional</p><h4 id="BottomNavigationView-的相关网页"><a href="#BottomNavigationView-的相关网页" class="headerlink" title="BottomNavigationView 的相关网页"></a>BottomNavigationView 的相关网页</h4><p><a href="https://blog.csdn.net/yihuangol/article/details/74370289">https://blog.csdn.net/yihuangol/article/details/74370289</a></p><p><a href="https://blog.csdn.net/xiaoyangsavvy/article/details/70213537">https://blog.csdn.net/xiaoyangsavvy/article/details/70213537</a></p><h4 id="Fragment-使用"><a href="#Fragment-使用" class="headerlink" title="Fragment 使用"></a>Fragment 使用</h4><p><a href="https://www.jianshu.com/p/fd71d65f0ec6">https://www.jianshu.com/p/fd71d65f0ec6</a></p><h4 id="开发要点"><a href="#开发要点" class="headerlink" title="开发要点"></a>开发要点</h4><p>所有变量声明放在最外面,初始化看情况而定,List,arrarylist 这些可以声明时就初始化,直接 new…</p><h4 id="Butterknife-和-reclclerview-的综合用法"><a href="#Butterknife-和-reclclerview-的综合用法" class="headerlink" title="Butterknife 和 reclclerview 的综合用法"></a>Butterknife 和 reclclerview 的综合用法</h4><p><a href="https://www.aliyun.com/jiaocheng/15082.html">https://www.aliyun.com/jiaocheng/15082.html</a></p><h4 id="RecyclerView-点击事件接口回调"><a href="#RecyclerView-点击事件接口回调" class="headerlink" title="RecyclerView 点击事件接口回调"></a>RecyclerView 点击事件接口回调</h4><p><a href="https://blog.csdn.net/willba/article/details/72878345">https://blog.csdn.net/willba/article/details/72878345</a></p><p><a href="https://blog.csdn.net/weikai_/article/details/78936013">https://blog.csdn.net/weikai_/article/details/78936013</a></p><p><a href="https://blog.csdn.net/xieluoxixi/article/details/61924372">https://blog.csdn.net/xieluoxixi/article/details/61924372</a></p><p><a href="https://blog.csdn.net/dl10210950/article/details/52918019">https://blog.csdn.net/dl10210950/article/details/52918019</a></p><h4 id="获取-RecyclerView-的-Item-中的-EditText-的内容"><a href="#获取-RecyclerView-的-Item-中的-EditText-的内容" class="headerlink" title="获取 RecyclerView 的 Item 中的 EditText 的内容"></a>获取 RecyclerView 的 Item 中的 EditText 的内容</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs java">EditText TmpEditText= (EditText)mRecyclerView.getChildAt(position).findViewById(R.id.app_input);<br>String app_name= TmpEditText.getText().toString();<br></code></pre></td></tr></table></figure><h4 id="透明背景文字图片做法"><a href="#透明背景文字图片做法" class="headerlink" title="透明背景文字图片做法"></a>透明背景文字图片做法</h4><p>利用ppt,确定文字效果以后再复制,左上角找到选择性粘贴,选中 “PNG图片”,图片粘贴在PPT上面后再另存为图片保存为 PNG 格式,保存到资源文件管理器中</p><h4 id="RecyclerView-复用问题,坑大半天的问题"><a href="#RecyclerView-复用问题,坑大半天的问题" class="headerlink" title="RecyclerView 复用问题,坑大半天的问题"></a>RecyclerView 复用问题,坑大半天的问题</h4><p>onBindViewHolder 会有多次调用重绘,if-else 条件必须确保完整。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-meta">@Override</span><br><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onBindViewHolder</span><span class="hljs-params">(ViewHolder holder, <span class="hljs-keyword">int</span> position)</span> </span>{<br><br> holder.app_icon.setImageDrawable(app_list.get(position).getImage());<br> holder.app_name.setText(app_list.get(position).getName());<br> <span class="hljs-keyword">if</span> (app_list.get(position).getIsHasUpdate()==<span class="hljs-keyword">false</span>){<br> holder.isHasUpdate.setVisibility(View.GONE);<br> }<br> <span class="hljs-comment">//一定必须要加下面的else</span><br> <span class="hljs-keyword">else</span>{<br> holder.isHasUpdate.setVisibility(View.VISIBLE);<br> }<br>}<br></code></pre></td></tr></table></figure><p><a href="https://blog.csdn.net/csdn_aiyang/article/details/80094302">https://blog.csdn.net/csdn_aiyang/article/details/80094302</a></p><p><a href="https://blog.csdn.net/like_program/article/details/52517119">https://blog.csdn.net/like_program/article/details/52517119</a></p><h4 id="SwipeRefreshLayout-使用"><a href="#SwipeRefreshLayout-使用" class="headerlink" title="SwipeRefreshLayout 使用"></a>SwipeRefreshLayout 使用</h4><p><a href="https://www.jianshu.com/p/d23b42b6360b">https://www.jianshu.com/p/d23b42b6360b</a></p><p><a href="https://blog.csdn.net/yl104221034/article/details/50582644">https://blog.csdn.net/yl104221034/article/details/50582644</a></p><h4 id="ImageButton-背景透明"><a href="#ImageButton-背景透明" class="headerlink" title="ImageButton 背景透明"></a>ImageButton 背景透明</h4><p>xml里面设置 android:background=”@null”</p><h4 id="坑爹-RecyclerView-获取子-Item-位置问题"><a href="#坑爹-RecyclerView-获取子-Item-位置问题" class="headerlink" title="坑爹 RecyclerView 获取子 Item 位置问题"></a>坑爹 RecyclerView 获取子 Item 位置问题</h4><p>getChildAt 函数只能获取屏幕可见的子 Item</p><p><a href="https://blog.csdn.net/binbin960211892/article/details/78662388">https://blog.csdn.net/binbin960211892/article/details/78662388</a></p><p><a href="https://blog.csdn.net/higson/article/details/52819327">https://blog.csdn.net/higson/article/details/52819327</a></p><h4 id="跳转应用市场详情界面查看"><a href="#跳转应用市场详情界面查看" class="headerlink" title="跳转应用市场详情界面查看"></a>跳转应用市场详情界面查看</h4><p><a href="https://www.jianshu.com/p/a4a806567368">https://www.jianshu.com/p/a4a806567368</a></p><h4 id="文件搜索"><a href="#文件搜索" class="headerlink" title="文件搜索"></a>文件搜索</h4><p><a href="https://blog.csdn.net/qq_21194621/article/details/51627274">https://blog.csdn.net/qq_21194621/article/details/51627274</a></p><p><a href="https://blog.csdn.net/zzh12138/article/details/71077909">https://blog.csdn.net/zzh12138/article/details/71077909</a></p><p><a href="https://blog.csdn.net/sinat_33585352/article/details/80741648">https://blog.csdn.net/sinat_33585352/article/details/80741648</a></p><h4 id="计算-App-占用空间"><a href="#计算-App-占用空间" class="headerlink" title="计算 App 占用空间"></a>计算 App 占用空间</h4><p><a href="https://blog.csdn.net/bingqingsuimeng/article/details/51062300">https://blog.csdn.net/bingqingsuimeng/article/details/51062300</a></p><p><a href="https://blog.csdn.net/m6711154/article/details/52000041">https://blog.csdn.net/m6711154/article/details/52000041</a></p><h4 id="避免代码复用出现问题"><a href="#避免代码复用出现问题" class="headerlink" title="避免代码复用出现问题"></a>避免代码复用出现问题</h4><p>setVisibility 为不可见之后要注意判断后面还有没有复用,添加 if 判断重新设置为可见</p><h4 id="文件扫描搜索"><a href="#文件扫描搜索" class="headerlink" title="文件扫描搜索"></a>文件扫描搜索</h4><p><a href="https://blog.csdn.net/yuzhiqiang_1993/article/details/78140580">https://blog.csdn.net/yuzhiqiang_1993/article/details/78140580</a></p><h4 id="通过媒体库提供方式实现文件扫描搜索"><a href="#通过媒体库提供方式实现文件扫描搜索" class="headerlink" title="通过媒体库提供方式实现文件扫描搜索"></a>通过媒体库提供方式实现文件扫描搜索</h4><p><a href="https://www.jianshu.com/p/a6bdbefde77a">https://www.jianshu.com/p/a6bdbefde77a</a></p><p><a href="https://blog.csdn.net/zocki33250/article/details/48112669">https://blog.csdn.net/zocki33250/article/details/48112669</a></p><p><a href="https://blog.csdn.net/yaochangliang159/article/details/51878841">https://blog.csdn.net/yaochangliang159/article/details/51878841</a></p><h4 id="RecyclerView-完美实现拖拽,滑动删除,撤销删除"><a href="#RecyclerView-完美实现拖拽,滑动删除,撤销删除" class="headerlink" title="RecyclerView 完美实现拖拽,滑动删除,撤销删除"></a>RecyclerView 完美实现拖拽,滑动删除,撤销删除</h4><p><a href="https://blog.csdn.net/hymanme/article/details/50931082">https://blog.csdn.net/hymanme/article/details/50931082</a></p><h4 id="SurfaceView-用处,用法"><a href="#SurfaceView-用处,用法" class="headerlink" title="SurfaceView 用处,用法"></a>SurfaceView 用处,用法</h4><p><a href="http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2012/1201/656.html">http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2012/1201/656.html</a></p><p><a href="https://blog.csdn.net/ShanYu1198124123/article/details/52448586">https://blog.csdn.net/ShanYu1198124123/article/details/52448586</a></p><h4 id="SurfaceView-和-TextureView-对比"><a href="#SurfaceView-和-TextureView-对比" class="headerlink" title="SurfaceView 和 TextureView 对比"></a>SurfaceView 和 TextureView 对比</h4><p><a href="https://blog.csdn.net/hejjunlin/article/details/58582919">https://blog.csdn.net/hejjunlin/article/details/58582919</a></p><p>我的思路是用 MediaPlayer 和 TextureView 来结合实现。(VideoView底层用的也是MediaPlayer,至于为什么不用 SurfaceView 而用 TextureView,是因为 SurfaceView不能放在可滑动的控件中,至于具体原因和缺点如果不清楚可自行百度之,TextureView 正是为了解决这个问题而存在的。</p><p>在 Android 总播放视频可以直接使用<code>VideoView</code>,<code>VideoView</code>是通过继承自<code>SurfaceView</code>来实现的。<code>SurfaceView</code>的大概原理就是在现有<code>View</code>的位置上创建一个新的<code>Window</code>,内容的显示和渲染都在新的<code>Window</code>中。这使得<code>SurfaceView</code>的绘制和刷新可以在单独的线程中进行,从而大大提高效率。但是呢,由于<code>SurfaceView</code>的内容没有显示在<code>View</code>中而是显示在新建的<code>Window</code>中, 使得<code>SurfaceView</code>的显示不受<code>View</code>的属性控制,不能进行平移,缩放等变换,也不能放在其它<code>RecyclerView</code>或<code>ScrollView</code>中,一些<code>View</code>中的特性也无法使用。</p><h4 id="Mediaplayer换成Exoplayer的方法"><a href="#Mediaplayer换成Exoplayer的方法" class="headerlink" title="Mediaplayer换成Exoplayer的方法"></a>Mediaplayer换成Exoplayer的方法</h4><p>版本号 2.5版本以前为 r2.x.x,2.5版本以后为 2.x.x</p><p>了解两种播放器的状态转换和监听接口回调,多打日志观察回调过程。</p><p>学习接口的写法,就像这次项目的更换,在有 Mediaplayer 的地方换成 ExoPlayer 的对应方法即可。VideoPlayerController 的代码完全不用改。</p><h4 id="新优化集成问题"><a href="#新优化集成问题" class="headerlink" title="新优化集成问题"></a>新优化集成问题</h4><p>第一时间想到能否集成,集成开销,对 APK 包大小的影响,老机器版本兼容性,建立表格,拍摄小视频等确认效果对比。</p><h4 id="开源项目推荐的网址"><a href="#开源项目推荐的网址" class="headerlink" title="开源项目推荐的网址"></a>开源项目推荐的网址</h4><p><a href="https://www.ctolib.com/android/">https://www.ctolib.com/android/</a></p><h4 id="“-”-和-“equals”-有什么差别?"><a href="#“-”-和-“equals”-有什么差别?" class="headerlink" title="“==” 和 “equals” 有什么差别?"></a>“==” 和 “equals” 有什么差别?</h4><p>equals用于判断对象的内容是否相等,==运算符用于比较对象的引用是否一致</p><h4 id="Apk-反编译"><a href="#Apk-反编译" class="headerlink" title="Apk 反编译"></a>Apk 反编译</h4><p><a href="https://blog.csdn.net/s13383754499/article/details/78914592">https://blog.csdn.net/s13383754499/article/details/78914592</a></p><p><a href="https://www.cnblogs.com/spring87/p/4525647.html">https://www.cnblogs.com/spring87/p/4525647.html</a></p><h4 id="依赖源码不起作用?三大重置方法"><a href="#依赖源码不起作用?三大重置方法" class="headerlink" title="依赖源码不起作用?三大重置方法"></a>依赖源码不起作用?三大重置方法</h4><ul><li>clean project</li><li>Invalie Cache and restart</li><li>关掉instant run</li></ul><h4 id="CMD-Markdown编辑器"><a href="#CMD-Markdown编辑器" class="headerlink" title="CMD Markdown编辑器"></a>CMD Markdown编辑器</h4><p><a href="https://www.zybuluo.com/mdeditor">https://www.zybuluo.com/mdeditor</a></p><h4 id="So-文件兼容-CPU-架构"><a href="#So-文件兼容-CPU-架构" class="headerlink" title="So 文件兼容 CPU 架构"></a>So 文件兼容 CPU 架构</h4><p><a href="http://xuchongyang.com/2017/03/12/%E6%8E%A2%E5%AF%BB-Android-so-%E5%BA%93/">http://xuchongyang.com/2017/03/12/%E6%8E%A2%E5%AF%BB-Android-so-%E5%BA%93/</a></p><h4 id="Binary-XML-file-line-Error-inflating-class"><a href="#Binary-XML-file-line-Error-inflating-class" class="headerlink" title="Binary XML file line # : Error inflating class"></a>Binary XML file line # : Error inflating class</h4><p><a href="https://blog.csdn.net/huangxiaohu_coder/article/details/8497286">https://blog.csdn.net/huangxiaohu_coder/article/details/8497286</a></p><p><a href="https://blog.csdn.net/xiabing082/article/details/43487159">https://blog.csdn.net/xiabing082/article/details/43487159</a></p><h4 id="Complie-和-Provided-区别"><a href="#Complie-和-Provided-区别" class="headerlink" title="Complie 和 Provided 区别"></a>Complie 和 Provided 区别</h4><p>Provided只是IDE编译时依赖,但是不打包到APK,也就是说编译时通过,但是不保证手机安装APK后是否能运行。</p><h4 id="TextView-优化"><a href="#TextView-优化" class="headerlink" title="TextView 优化"></a>TextView 优化</h4><p><a href="http://codethink.me/2015/04/23/improving-comment-rendering-on-android/">http://codethink.me/2015/04/23/improving-comment-rendering-on-android/</a></p><h4 id="视频基础知识"><a href="#视频基础知识" class="headerlink" title="视频基础知识"></a>视频基础知识</h4><p><a href="https://blog.csdn.net/zhs4430169/article/details/76502217">https://blog.csdn.net/zhs4430169/article/details/76502217</a></p><h4 id="Android-性能优化"><a href="#Android-性能优化" class="headerlink" title="Android 性能优化"></a>Android 性能优化</h4><p><a href="https://www.jianshu.com/p/307ba8911799">https://www.jianshu.com/p/307ba8911799</a></p><h4 id="DNS-优化"><a href="#DNS-优化" class="headerlink" title="DNS 优化"></a>DNS 优化</h4><p><a href="https://my.oschina.net/sudujuncom/blog/874699">https://my.oschina.net/sudujuncom/blog/874699</a></p><h4 id="修改第三方库"><a href="#修改第三方库" class="headerlink" title="修改第三方库"></a>修改第三方库</h4><p>final 类型的不可继承修改</p><p>继承要修改的类,右键新类名可以 generate 构造函数。再 @Override 具体修改的函数,记得要 super 父类函数</p>]]></content>
</entry>
<entry>
<title>利用 DNS 隧道免认证上网</title>
<link href="/2018/07/10/%E5%88%A9%E7%94%A8%20DNS%20%E9%9A%A7%E9%81%93%E5%85%8D%E8%AE%A4%E8%AF%81%E4%B8%8A%E7%BD%91/"/>
<url>/2018/07/10/%E5%88%A9%E7%94%A8%20DNS%20%E9%9A%A7%E9%81%93%E5%85%8D%E8%AE%A4%E8%AF%81%E4%B8%8A%E7%BD%91/</url>
<content type="html"><![CDATA[<p>现在很多商场、饭店的商业WIFI采用了WEB Portal认证方式,但有些认证系统存在漏洞,可以利用 DNS 隧道绕过网关计费系统,实现上网。</p><h2 id="DNS运行机制"><a href="#DNS运行机制" class="headerlink" title="DNS运行机制"></a>DNS运行机制</h2><p>DNS(Domain Name System)是“域名系统”的英文缩写,是一种组织成域层次结构的计算机和网络服务命名系统,用于TCP/IP网络,提供将主机名和域名转换为IP地址的服务,举例就是把<code>www.qq.com</code>转换为IPV4地址119.147.15.13</p><p>DNS解析域名过程如下叙述:</p><ol><li>找浏览器缓存,当用户通过浏览器访问某域名时,浏览器首先会在自己的缓存中查找是否有该域名对应的IP地址(若曾经访问过该域名且没有清空缓存便存在)。</li><li>找系统缓存,当浏览器缓存中无域名对应IP则会自动检查用户计算机系统Hosts文件DNS缓存是否有该域名对应IP。</li><li>找路由器缓存,当浏览器及系统缓存中均无域名对应IP则进入路由器缓存中检查,以上三步均为客服端的DNS缓存。</li><li>找ISP的DNS缓存,当在用户客服端查找不到域名对应IP地址,则将进入ISP DNS缓存中进行查询。比如你用的是电信的网络,则会进入电信的DNS缓存服务器中进行查找。</li><li>查询根域名服务器,当以上均未完成,则进入根服务器进行查询。全球仅有13台根域名服务器,1个主根域名服务器,其余12为辅根域名服务器。根域名收到请求后会查看区域文件记录,若无则将其管辖范围内顶级域名(如.com)服务器IP告诉本地DNS服务器。</li><li>查询顶级域名服务器,顶级域名服务器收到请求后查看区域文件记录,若无则将其管辖范围内主域名服务器的IP地址告诉本地DNS服务器。</li><li>查询主域名服务器,主域名服务器接受到请求后查询自己的缓存,如果没有则进入下一级域名服务器进行查找,并重复该步骤直至找到正确纪录。</li><li>保存结果到缓存,本地域名服务器把返回的结果保存到缓存,以备下一次使用,同时将该结果反馈给客户端,客户端通过这个IP地址与web服务器建立链接。</li></ol><p><img src="https://raw.githubusercontent.com/zwczwc/res/master/2018/surfingViaDNSTunnel/DNSProcess.png"></p><h2 id="DNS隧道原理"><a href="#DNS隧道原理" class="headerlink" title="DNS隧道原理"></a>DNS隧道原理</h2><p>DNS隧道从名字上来看就是利用DNS查询过程建立起隧道,传输数据。概括地讲,所谓 tunnel 就是把下一层(比如IPv4层)的包封装到上一层(比如 SSH,HTTP)或者同一层(比如IPv6层)的协议中进行传输,从而实现网络之间的穿透。</p><p>很明显,这种实现有个前提,那就是:发送端和接收端必须各有一个解析这种包的程序或者内核模块才能实现正常通信。DNS隧道技术简单来说就是将网络流量封装成DNS流量,再通过DNS的正常走向将流量传出来.这里的流量封装通常由一个客户端来完成,而降封装的DNS流量还原成正常的流量将由一个服务端来完成。 </p><p><img src="https://raw.githubusercontent.com/zwczwc/res/master/2018/surfingViaDNSTunnel/Topology.png"></p><p>下面是利用DNS隧道连接外部网络时DNS解析的一个过程,由于防火墙并没有对dns协议做任何处理,所以我们可以通过这种方式向外网发送数据来穿透防火墙。</p><ol><li>向内部dns服务器发送一个查询xxx.com的请求,这个域名的控制权限是在自己手里的</li><li>内部dns服务器通过防火墙向根dns服务器发出查询请求</li><li>经过大量重定向后,DNS请求到达xxx.com的权威DNS服务器,该服务器处于自己的控制之下</li><li>请求查询的响应结果通过防火墙</li><li>响应结果返回到内部服务器</li><li>内部服务器将响应结果返回</li></ol><h2 id="Web-Portal的原理"><a href="#Web-Portal的原理" class="headerlink" title="Web Portal的原理"></a>Web Portal的原理</h2><p>Portal在英语中是入口的意思。Portal认证通常也称为Web认证,一般将Portal认证网站称为门户网站。未认证用户上网时,设备强制用户登录到特定站点,用户可以免费访问其中的服务。当用户需要使用互联网中的其它信息时,必须在门户网站进行认证,只有认证通过后才可以使用互联网资源。Portal业务可以为运营商提供方便的管理功能,门户网站可以开展广告、社区服务、个性化的业务等,使宽带运营商、设备提供商和内容服务提供商形成一个产业生态系统。</p><p>Portal的典型组网方式如下面拓扑图所示,它由五个基本要素组成:认证客户端、接入设备、Portal服务器、认证/计费服务器和安全策略服务器。</p><p><img src="https://raw.githubusercontent.com/zwczwc/res/master/2018/surfingViaDNSTunnel/webPortalTopology.png"></p><p>Portal认证的基本过程如下:</p><ol><li><p>客户机首先通过DHCP协议获取到IP地址(也可以使用静态IP地址),但是客户使用获取到的IP地址并不能登上Internet,在认证通过前只能访问特定的IP地址,这个地址通常是PORTAL服务器的IP地址。采用Portal认证的接入设备必须具备这个能力。一般通过修改接入设备的访问控制表(ACL)可以做到。</p></li><li><p>用户登录到Portal Server后,可以浏览上面的内容,比如广告、新闻等免费信息,同时用户还可以在网页上输入用户名和密码,它们会被WEB客户端应用程序传给 Portal Server,再由Portal Server与NAS之间交互来实现用户的认证。</p></li><li><p>Portal Server在获得用户的用户名和密码外,还会得到用户的IP地址,以它为索引来标识用户。然后Portal Server 与NAS之间用Portal协议直接通信,而NAS又与RADIUS 服务器直接通信完成用户的认证和上线过程。因为安全问题,通常支持安全性较强的CHAP式认证。</p></li></ol><h2 id="设备及环境软件"><a href="#设备及环境软件" class="headerlink" title="设备及环境软件"></a>设备及环境软件</h2><table><thead><tr><th>设备</th><th align="center">环境软件</th></tr></thead><tbody><tr><td>本地主机</td><td align="center">Windows10,iodine0.7,ShadowSocks代理,OpenVpn2.3.10,XShell6</td></tr><tr><td>腾讯云主机</td><td align="center">CentOS,OpenVpn,ShadowSocks代理,iodined</td></tr><tr><td>阿里云域名</td><td align="center">域名解析设置</td></tr></tbody></table><h2 id="方案设计"><a href="#方案设计" class="headerlink" title="方案设计"></a>方案设计</h2><p>一般情况下,连接上路由器后,不经过其它操作直接输入别的网址打开,主机的数据包将从TCP端口发出,这时路由器网关发现主机没有经过Portal认证,立刻就拦截这个端口发出的数据包,其它端口同理也拦截,最后重定向至认证页面要求用户进行认证。</p><p>然而,世间万事都有例外。即使在不经过Portal认证的情况下,UDP的53端口发出的数据包也不会被网关拦截,而在这个端口上运行的就是DNS协议,DNS的解析功能依然正常,因此设法利用这个端口,在本地将上网的数据包伪装成DNS数据包,本地DNS自然无法解析这个伪装的DNS数据包,利用域名解析解析到远程的自己搭建的服务器上,在远程服务器上再还原出真实的上网数据包完成各种上网请求,最后整理响应数据伪装成DNS响应数据包,返回主机上还原查看上网响应数据包。</p><h2 id="流程"><a href="#流程" class="headerlink" title="流程"></a>流程</h2><h3 id="域名解析配置"><a href="#域名解析配置" class="headerlink" title="域名解析配置"></a>域名解析配置</h3><p>在阿里云上申请了一个.top域名,进入到域名控制台中,点击“解析”进入到解析配置,为域名添加一条A记录和一条NS记录,详情如下图所示。 </p><p><img src="https://raw.githubusercontent.com/zwczwc/res/master/2018/surfingViaDNSTunnel/domainSetting.png"></p><p>其中A记录用来指定主机名或域名对应的IP地址记录,NS记录是域名服务器记录,用来指定该域名由哪个DNS服务器来进行解析。当本地域名服务器无法解析伪装的数据包后,便将数据包发送给NS记录指定的服务器aaa.coolcc.top,而aaa.coolcc.top的IP地址已经在A记录中给出了。</p><p>因此,这样配置后本地域名服务器会将伪装的DNS数据包发送到云主机上。</p><h3 id="云主机配置"><a href="#云主机配置" class="headerlink" title="云主机配置"></a>云主机配置</h3><p>在腾讯云上购买了体验云主机,配置为1 核 1 GB 1 Mbps,预装系统为CentOS 7.4 64位,可在控制台中查看到当前云主机概况,如下图所示。 </p><p><img src="https://raw.githubusercontent.com/zwczwc/res/master/2018/surfingViaDNSTunnel/cloudServer.png"></p><p>在控制台菜单中进入到<code>安全组</code>选项,新建安全组,设置为<code>放通所有端口</code>,便于DNS数据在UDP53端口的接收传送。回到云主机概况中,点此云主机的<code>更多</code>,进入到<code>配置安全组选项</code>,将此安全组配置给云主机。 </p><p><img src="https://raw.githubusercontent.com/zwczwc/res/master/2018/surfingViaDNSTunnel/newGroup.png"></p><p><img src="https://raw.githubusercontent.com/zwczwc/res/master/2018/surfingViaDNSTunnel/setGroup.png"></p><p>使用XShell连接云主机,新建会话,在主机一栏中填入云主机的公网IP,随后弹出登录验证界面,输入用户账号密码后即可登录使用管理云主机。</p><p><img src="https://raw.githubusercontent.com/zwczwc/res/master/2018/surfingViaDNSTunnel/xshellConnect.png"></p><p>登录云主机成功后就可以开始配置主机环境,安装DNS隧道所需软件,输入以下安装指令并依照提示安装即可</p><table><thead><tr><th><strong>软件</strong></th><th>安装指令</th><th>作用</th></tr></thead><tbody><tr><td>iodined</td><td>yum install iodine</td><td>建立DNS隧道</td></tr><tr><td>OpenVpn</td><td>yum install openvpn</td><td>虚拟网卡</td></tr><tr><td>ShadowSocks</td><td>yum install python-setuptools ; easy_install pip</td><td>系统代理</td></tr></tbody></table><p>安装完软件后需要配置软件,对于ShadowSocks,配置其代理设置,输入<code>vim /etc/shadowsocks.json</code>指令来创建配置文件,内容如下图,其中服务器地址填写的地址需要与云主机内网IP在同一个网段下,保存退出。随后输入<code>ssserver -c /etc/shadowsocks.json -d start</code>指令,表明用配置文件启动运行ShadowSocks服务。最后输入<code>iodined -c -f -P 12345678 172.16.99.1 zwc.coolcc.top</code>指令启动iodine,监听zwc.coolcc.top的DNS解析。 </p><p><img src="https://raw.githubusercontent.com/zwczwc/res/master/2018/surfingViaDNSTunnel/shadowSocksSetting.png"></p><p><img src="https://raw.githubusercontent.com/zwczwc/res/master/2018/surfingViaDNSTunnel/runShadowSocks.png"></p><p><img src="https://raw.githubusercontent.com/zwczwc/res/master/2018/surfingViaDNSTunnel/runIodine.png"></p><p>另外,可以上<a href="https://code.kryo.se/iodine/check-it/">https://code.kryo.se/iodine/check-it/</a>这个网站输入监听解析域名,上面例子就是zwc.coolcc.top,验证iodine工作是否正常。如下图,返回结果提示iodine工作没问题。 </p><p><img src="https://raw.githubusercontent.com/zwczwc/res/master/2018/surfingViaDNSTunnel/checkIodine.png"></p><h3 id="本地主机配置"><a href="#本地主机配置" class="headerlink" title="本地主机配置"></a>本地主机配置</h3><p>本地主机同样先安装好所需环境和软件,安装包都能在对应官网上找到下载,这里也不赘述详细安装过程了。注意的问题一是OpenVpn最好用2.3.10版本,因为一开始用2.3.13版本网络无法连通,换成2.3.10之后就好了,二是安装OpenVpn时只需要勾选安装T<code>AP Virtual Ethernet Adapter</code>一项即可,因为只需要用到OpenVpn生成的这个TAP网络适配器来沟通连接服务器的网卡。</p><p><img src="https://raw.githubusercontent.com/zwczwc/res/master/2018/surfingViaDNSTunnel/installOpenVPN.png"></p><p>安装完后启动iodine服务。以管理管身份运行cmd,在cmd中进入到iodine的32位或者64位目录下,输入<code>iodine -f -P 12345678 203.195.135.206 zwc.coolcc.top</code>指令启动iodine,与云主机建立DNS隧道,注意到输入参数为云主机的公网IP,12345678为云主机端的iodine程序设置的密码。成功建立后可以窗口如下图所示。</p><p><img src="https://raw.githubusercontent.com/zwczwc/res/master/2018/surfingViaDNSTunnel/runIodine1.png"></p><p>可以另开一个cmd测试一下此时本地主机与云主机的连通性,ping一下云主机之前设置的DNS服务器地址,效果如下图所示。</p><p><img src="https://raw.githubusercontent.com/zwczwc/res/master/2018/surfingViaDNSTunnel/ping.png"></p><p>现在要启用ShadowSocks代理,选项按照云主机的配置文件填写就可以了,如下图编辑服务器界面。最后右击任务栏ShadowSocks小图标,正式启用ShadowSocks系统代理,并把代理模式改成全局代理模式。 </p><p><img src="https://raw.githubusercontent.com/zwczwc/res/master/2018/surfingViaDNSTunnel/xshellConnect.png"></p><h2 id="结果"><a href="#结果" class="headerlink" title="结果"></a>结果</h2><p>去学校隔壁的麦当劳,连接上麦当劳的wifi,理所当然地弹出了Web的Portal认证页面</p><p><img src="https://raw.githubusercontent.com/zwczwc/res/master/2018/surfingViaDNSTunnel/McDonloadPortal.png"></p><p>无视麦当劳的认证界面,打开浏览器别的选项卡输入网址浏览,发现网页都能打开,说明我们的实验成功了。在百度搜索中输入IP,显示的IP为云主机的公网IP地址,属于腾讯云,说明我们的代理设置也成功了。但是在这种上网情况下,QQ微信等即时通讯软件是无法使用的,因为数据不走DNS解析通道,这也能解释有时候网页打不开但是QQ能上的现象,就是因为DNS解析的问题。</p><p><img src="https://raw.githubusercontent.com/zwczwc/res/master/2018/surfingViaDNSTunnel/queryIP.png"></p><p>现在测试一下采用这种方式的上网通信质量,打开老牌的网络测速网站SpeedTest,任选一个测速点测试本地主机与测速点的通信质量。在测速报告中可以看到下载上传速度都在1Mbps左右,网络质量不太好,打开网页和加载网络图片也感到明显卡顿,延迟高 </p><p><img src="https://raw.githubusercontent.com/zwczwc/res/master/2018/surfingViaDNSTunnel/testMbps.png"></p><p>网络质量不好的原因在于三方面,一是我们购置的云主机为最低配,网络带宽配置仅有1Mbps,从这么低的带宽自然无法得到良好的上网体验;二是网络的多重处理转发性,经历了本地主机软件的伪造DNS数据包处理,内部DNS服务器的转发,远程主机的接收还原这么多步骤后,才开始通过远程主机与互联网的连接真正处理网络请求数据,接收到响应数据之后还要重新逆执行前面的步骤,这样复杂的转发机制无疑加大的延迟,降低网络质量;三是UDP协议的不可靠性,虽然快捷但是不保证可靠,提升传输丢包的风险,再次影响了上网体验。 </p><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><p><a href="https://www.cnblogs.com/bonelee/p/8059464.html">iodine免费上网 </a></p><p><a href="https://qiuri.org/806.html">透过DNS Tunnel绕过校园网认证系统实现免费上网 </a></p><p><a href="https://blog.csdn.net/qq_35422558/article/details/78018089">UDP绕过校园网,纯手工搭建 </a></p>]]></content>
</entry>
<entry>
<title>微信红包抓包和原理分析</title>
<link href="/2018/06/12/%E5%BE%AE%E4%BF%A1%E7%BA%A2%E5%8C%85%E5%88%86%E6%9E%90/"/>
<url>/2018/06/12/%E5%BE%AE%E4%BF%A1%E7%BA%A2%E5%8C%85%E5%88%86%E6%9E%90/</url>
<content type="html"><![CDATA[<h2 id="抓包方式"><a href="#抓包方式" class="headerlink" title="抓包方式"></a>抓包方式</h2><p>抓取微信红包数据包的工具是 <strong>Wireshark</strong>。Wireshark 的功能无需赘述了,最强大<br>的网络封包协议分析软件,没有之一。</p><p>另外还有手机型号系统和微信版本的问题,尝试过安卓系统手机和高版本的微信,只抓到两个微信红包数据包,难以进行分析,最后确定是在苹果系统和微信 6.5版本环境下才能抓到理想的数据包。</p><p>抓取微信红包数据包的方式就是笔记本电脑通过 WIFI 连接路由器上网,然后利用笔记本电脑网<br>卡的双频收发功能,连接 WIFI 的同时开启热点,手机WIFI 连接电脑开启的热点上网,最后在<br>Wireshark 中监听开启笔记本热点的网络连接即可。注意到 Wireshark 的抓包能力过强,抓到网络<br>协议的多层数据包,信息量巨大繁杂,因此要在过滤器工具栏中添加 http 协议的过滤规则,方便抓包。</p><h2 id="抓包分析"><a href="#抓包分析" class="headerlink" title="抓包分析"></a>抓包分析</h2><p>关于微信红包,一般是发红包,收红包和查看红包这三个流程。</p><p>发红包</p><p><img src="https://raw.githubusercontent.com/zwczwc/res/master/2018/wechatRedPacketAnalysis/sendRedPacket.png"></p><p>收红包</p><p><img src="https://raw.githubusercontent.com/zwczwc/res/master/2018/wechatRedPacketAnalysis/receiveRedPacket.png"></p><p>查看红包</p><p><img src="https://raw.githubusercontent.com/zwczwc/res/master/2018/wechatRedPacketAnalysis/queryRedPacket.png"></p><p>每个数据包的Info一栏中的英文字段能直观地反应出这个数据包的作用,而高版本的微信再次巩固了安全性,对Info一栏进行了加密,变成复杂的英文数字组合。也可以看出<strong>红包的发起请求方法为POST</strong>,参数不会被保存,比起GET请求方法更加安全。在这些数据包中任意选中一个查看详情,发现主要交互域名为<strong>short.weixin.qq.com</strong>,实验时服务器的IP地址为同一个,为<strong>182.254.92.141</strong>。</p><p><img src="https://raw.githubusercontent.com/zwczwc/res/master/2018/wechatRedPacketAnalysis/mainDomain.png"></p><p><img src="https://raw.githubusercontent.com/zwczwc/res/master/2018/wechatRedPacketAnalysis/sameIPAddress.png"></p><h2 id="红包延迟"><a href="#红包延迟" class="headerlink" title="红包延迟"></a>红包延迟</h2><p>抢红包延迟可以分为<strong>网络传输延迟</strong>和<strong>用户终端延迟</strong>两类。</p><p>从数据包角度来看,网络传输延迟主要发生在收到红包和打开红包这两个会话的延迟,如下图时间所示,客户端点击收到的红包消息时请求服务器,直至收到服务器返回红包状态的响应,来回延迟大约为0.11s。客户端点击拆开红包时请求服务器,直至收到服务器返回红包已打开和金额详情的响应,来回延迟则大约为0.53s。可见拆开红包时涉及了红包金额分配算法运行和支付管理入账等安全操作,需要更多的时间,<strong>服务器回复客户端显然要比单纯回复红包是否被抢光的前一个请求慢得多。</strong> </p><p><img src="https://raw.githubusercontent.com/zwczwc/res/master/2018/wechatRedPacketAnalysis/networkLatency.png"></p><p>用户终端延迟则包括了<strong>用户操作延迟</strong>和<strong>用户终端UI延迟</strong>。用户操作延迟无可厚非就是看人的反应和点击速度快慢了,因人而异。用户终端UI延迟集中在屏幕的物理响应和UI绘制延迟,据网上资料显示,苹果手机凭借着优异的系统性能和屏幕响应机制,抢红包比安卓手机更占优势。 </p><p><a href="https://weibo.com/p/1001603814272596583142">参考</a></p><p>至于供应商流量环境和WIFI环境下的抢红包速度对比,一般而言,<strong>WIFI抢红包速度胜于流量</strong>。距离方面,无线传输距离越长,则耗费时间越长。WIFI环境下用户终端到路由器距离比流量环境下到基站距离短,减少了延迟,信号到达路由器或者基站后就能以有线光缆光速传输。设计标准方面,流量环境下的最佳技术LTE的目标时延为100ms,而WIFI在轻载之下可以达到10ms左右,速度相差了五倍。另外一个考虑因素是网络运营商建设,WIFI连接的有线网络运营商电信的骨干网建设优于流量运营商移动联通。腾讯的微信服务器和相关的红包服务器更有可能搭建在中国电信骨干网上。</p><h2 id="红包规律"><a href="#红包规律" class="headerlink" title="红包规律"></a>红包规律</h2><p>研究<strong>红包领取顺序与领取到的红包金额之间的关系</strong>。发红包设计方案如下:红包总额为20元,红包总数为20个,一共进行十轮红包发放,然后统计数据并分析,表格数据如下,黄色高亮为该轮最佳手气。</p><p><img src="https://raw.githubusercontent.com/zwczwc/res/master/2018/wechatRedPacketAnalysis/tableData.png"></p><p><img src="https://raw.githubusercontent.com/zwczwc/res/master/2018/wechatRedPacketAnalysis/xychart.png"></p><p>从散点图看出,绝大多数红包的金额大小<strong>分布在所有样本均值1附近</strong>。横坐标越大,纵坐标增大的概率越高,也就是说,最佳手气大多分布在领取顺序靠后的编号中,<strong>领取红包顺序越后,越容易领到最佳手气红包</strong>。因此,对于喜欢拼最佳手气的冒险主义者来说,不必见到红包就马上下手,静候片刻再拆开,或许能愿望成真,不过需要承担过于迟拆开导致红包被领光的风险。 </p><p><img src="https://raw.githubusercontent.com/zwczwc/res/master/2018/wechatRedPacketAnalysis/meanLineChart.png"></p><p>从均值折线图看出,均值随领取顺序变化波动较为剧烈,但总体还是<strong>围绕1上下波动变化的</strong>,也有可能是样本数据过少,个体偶然因素影响大,导致样本不够典型。因此,想利用上面“越后抢红包越容易拿最佳手气”这条规律的也不用沾沾自喜,白忙活一场抢红包大战下来,有可能抢到的跟别人的随缘抢也差不多,<strong>大家抢到的红包面额在概率上是大致均匀的</strong>。 </p><p><img src="https://raw.githubusercontent.com/zwczwc/res/master/2018/wechatRedPacketAnalysis/stdLineChart.png"></p><p>从标准差折线图看出,横坐标增大,纵坐标也增大,就是说<strong>标准差随着领取时间的增大而增大</strong>。标准差能够描述数据的离散程度,说明数据的稳定性,标准差越大,数据则波动得越剧烈。这也印证了前面的说法,往后容易领到大金额红包,为了把均值稳定在1附近,也容易领到小金额红包,因而这种极端值过多的情况使得标准差和方差增大。</p><p>总结,研究得到的微信红包规律性如下:<strong>微信红包是公平的,多次抢红包,领取到的金额是差不多的。每次领取顺序越前,领到的红包金额越是稳定在均值,领取顺序越后,领到的红包越是可能手气最佳或者手气最差。</strong></p><h2 id="红包算法"><a href="#红包算法" class="headerlink" title="红包算法"></a>红包算法</h2><p>根据资料,可认为微信红包满足的是<strong>截尾正态分布</strong>,算法即在截尾正态分布中取随机数,并用其求和数除以总价值,获得修正因子,再用修正因子乘上所有的随机数,得到红包价值。这种分布意味着:减少抽取红包大小分布的方差,让更多的人抽取的红包在均值附近,同时仍给一小部分人抽取大红包的机会,总体来说增加了红包抽取人的积极性和游戏的公平性。</p><p>并且为了防止最后领红包的人领时红包余额为0,红包机制可能为:当发红包者<准备红包>的时候,程序自动依照截尾分布产生了相应大小,相应个数的红包,然后随机发给抽取红包的人。同样,这样的一个随机过程有助于增加游戏的公平性,也减少了红包抽取人投机操作(亦即譬如故意等钱包半空的时候再抽取)的动机。 也即是说,不论先拿后拿,期望都是相同的。</p><p><a href="http://coderroc.com/article/%E6%95%B0%E5%AD%A6%E5%92%8C%E7%AE%97%E6%B3%95/%E5%BE%AE%E4%BF%A1%E7%BA%A2%E5%8C%85%E9%9A%8F%E6%9C%BA%E7%AE%97%E6%B3%95%E5%88%9D%E6%8E%A2.html">参考</a></p>]]></content>
</entry>
<entry>
<title>GitHub 静态页面自定义域名开启 Https</title>
<link href="/2018/06/02/GitHub%20%E9%9D%99%E6%80%81%E9%A1%B5%E9%9D%A2%E8%87%AA%E5%AE%9A%E4%B9%89%E5%9F%9F%E5%90%8D%E5%BC%80%E5%90%AF%20Https/"/>
<url>/2018/06/02/GitHub%20%E9%9D%99%E6%80%81%E9%A1%B5%E9%9D%A2%E8%87%AA%E5%AE%9A%E4%B9%89%E5%9F%9F%E5%90%8D%E5%BC%80%E5%90%AF%20Https/</url>
<content type="html"><![CDATA[<p>最近Github静态页面支持了自定义域名开启Https,本站顺势也可以换上小绿锁。</p><p> <a href="https://help.github.com/articles/setting-up-an-apex-domain/">官方支持页面</a></p><h2 id="优点"><a href="#优点" class="headerlink" title="优点"></a>优点</h2><ul><li>Https加密,防劫持</li><li>基于Https的CDN优化,加快网站加载时间</li><li>提供了额外防护DDoS攻击的服务</li><li>强迫症福利,地址栏旁边的 ”不安全“变成小绿锁</li></ul><h2 id="配置过程"><a href="#配置过程" class="headerlink" title="配置过程"></a>配置过程</h2><h3 id="域名解析"><a href="#域名解析" class="headerlink" title="域名解析"></a>域名解析</h3><p>如官方文档所言更新DNS解析地址,我这里的域名服务是阿里云提供的,原本是</p><table><thead><tr><th>记录类型</th><th>主机记录</th><th>记录值</th></tr></thead><tbody><tr><td>A</td><td>@</td><td>151.101.229.147</td></tr><tr><td>CNAME</td><td>www</td><td>zwczwc.github.io</td></tr></tbody></table><p>对A类型记录修改增加为官方提供的四个IP地址,在官方文档里有。最终结果为</p><table><thead><tr><th>记录类型</th><th>主机记录</th><th>记录值</th></tr></thead><tbody><tr><td>A</td><td>@</td><td>185.199.111.153</td></tr><tr><td>A</td><td>@</td><td>185.199.110.153</td></tr><tr><td>A</td><td>@</td><td>185.199.109.153</td></tr><tr><td>A</td><td>@</td><td>185.199.108.153</td></tr><tr><td>CNAME</td><td>www</td><td>zwczwc.github.io</td></tr></tbody></table><p>确认保存解析设置即可,很快就会生效。</p><h3 id="Github设置"><a href="#Github设置" class="headerlink" title="Github设置"></a>Github设置</h3><p>打开Github静态页面所在的Repository,点入最右边的<code>Settings</code>,定位到<code>Pages</code>一栏,勾上<code>Enforce HTTPS</code>。</p><p><img src="https://raw.githubusercontent.com/zwczwc/res/master/2018/githubHttps/enforceHttps.png"></p><p>发现无法勾上,旁边提示 <code>Not yet available for your site because the certificate has not finished being issued </code>,这时可以把上面填在<code>Custom domain</code>里的自定义域名清空,保存,然后重新填上自定义域名,再保存。</p><p>然后发现<code>Enforce HTTPS</code>可以勾选了,果断勾选上,然后证书很快就会签发成功,现在可以打开自定义域名看看效果了。</p><p><img src="https://raw.githubusercontent.com/zwczwc/res/master/2018/githubHttps/success.png"></p><p>大功告成!</p>]]></content>
</entry>
<entry>
<title>Hello World~</title>
<link href="/2000/01/01/Hello%20World~/"/>
<url>/2000/01/01/Hello%20World~/</url>
<content type="html"><![CDATA[<p>This is a post for testing purpose. Just ignore it. :)</p>]]></content>
</entry>
</search>