├── CNAME ├── img ├── close.png ├── favicon.ico ├── github.png ├── home-bg.jpg ├── open-bg.jpg ├── search.png ├── tags-bg.jpg ├── about-bg.jpg ├── contact-bg.jpg ├── ftp_server.png ├── image-gray.png ├── image-rgb.png ├── image-src.png ├── zzu_client.png ├── post-bg-java.jpg ├── post-bg-unix.jpg ├── post-bg-web.jpg ├── ustc_client.png ├── message_to_mail.png ├── post-bg-android.jpg ├── post-bg-iphone.jpg ├── post-bg-theory.jpg ├── ios-restrict-app.png └── post-bg-tranquil.jpg ├── codeboy.me.png ├── about ├── img │ ├── lyd.jpg │ ├── alipay.jpg │ └── tmall.png ├── fonts │ ├── fontawesome.eot │ ├── fontawesome.ttf │ ├── fontawesome.woff │ ├── timelineicons │ │ ├── ecoico.eot │ │ ├── ecoico.ttf │ │ ├── ecoico.woff │ │ ├── ecoico.svg │ │ └── ecoico.dev.svg │ └── fontawesome.svg ├── index.html ├── css │ ├── default.css │ └── component.css └── js │ └── modernizr.custom.js ├── .gitignore ├── search ├── img │ ├── cb-close.png │ └── cb-search.png ├── cb-search.json ├── css │ └── cb-search.css └── js │ ├── cb-search.js │ └── bootstrap3-typeahead.min.js ├── wechat ├── template └── create.sh ├── _layouts ├── default.html ├── page.html └── post.html ├── _posts ├── 2014-11-16-apache-user-authorized.md ├── 2015-05-08-js-rorate-image.md ├── 2015-07-10-java-operate.md ├── 2014-11-26-android-viewpager.md ├── 2015-07-11-jekyll-search.md ├── 2015-07-28-android-trick.md ├── 2014-11-06-java-trick-1.md ├── 2015-04-29-java-hashmap-trick.md ├── 2015-07-20-get-max-from-every-group.md ├── 2015-07-02-image-gray.md ├── 2015-01-06-ftp-no-download.md ├── 2015-06-28-android-unleak-hander.md ├── 2015-07-17-android-webview-optimize.md ├── 2015-05-04-android-ndk.md └── 2015-06-28-android-context.md ├── index.html ├── js ├── codeboy.min.js ├── jquery.tagcloud.js └── codeboy.js ├── feed.xml ├── _includes ├── head.html ├── nav.html └── footer.html ├── _config.yml ├── tags.html ├── apps.html ├── README.md ├── css ├── syntax.css ├── codeboy.min.css └── codeboy.css ├── open.html └── LICENSE /CNAME: -------------------------------------------------------------------------------- 1 | blogtest.codeboy.me 2 | -------------------------------------------------------------------------------- /img/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/androiddevelop/CodeboyBlog/HEAD/img/close.png -------------------------------------------------------------------------------- /codeboy.me.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/androiddevelop/CodeboyBlog/HEAD/codeboy.me.png -------------------------------------------------------------------------------- /img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/androiddevelop/CodeboyBlog/HEAD/img/favicon.ico -------------------------------------------------------------------------------- /img/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/androiddevelop/CodeboyBlog/HEAD/img/github.png -------------------------------------------------------------------------------- /img/home-bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/androiddevelop/CodeboyBlog/HEAD/img/home-bg.jpg -------------------------------------------------------------------------------- /img/open-bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/androiddevelop/CodeboyBlog/HEAD/img/open-bg.jpg -------------------------------------------------------------------------------- /img/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/androiddevelop/CodeboyBlog/HEAD/img/search.png -------------------------------------------------------------------------------- /img/tags-bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/androiddevelop/CodeboyBlog/HEAD/img/tags-bg.jpg -------------------------------------------------------------------------------- /about/img/lyd.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/androiddevelop/CodeboyBlog/HEAD/about/img/lyd.jpg -------------------------------------------------------------------------------- /img/about-bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/androiddevelop/CodeboyBlog/HEAD/img/about-bg.jpg -------------------------------------------------------------------------------- /img/contact-bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/androiddevelop/CodeboyBlog/HEAD/img/contact-bg.jpg -------------------------------------------------------------------------------- /img/ftp_server.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/androiddevelop/CodeboyBlog/HEAD/img/ftp_server.png -------------------------------------------------------------------------------- /img/image-gray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/androiddevelop/CodeboyBlog/HEAD/img/image-gray.png -------------------------------------------------------------------------------- /img/image-rgb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/androiddevelop/CodeboyBlog/HEAD/img/image-rgb.png -------------------------------------------------------------------------------- /img/image-src.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/androiddevelop/CodeboyBlog/HEAD/img/image-src.png -------------------------------------------------------------------------------- /img/zzu_client.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/androiddevelop/CodeboyBlog/HEAD/img/zzu_client.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | _site/ 2 | .sass-cache/ 3 | .idea/ 4 | *.iml 5 | wechat/content/* 6 | .jekyll-cache/* 7 | -------------------------------------------------------------------------------- /about/img/alipay.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/androiddevelop/CodeboyBlog/HEAD/about/img/alipay.jpg -------------------------------------------------------------------------------- /about/img/tmall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/androiddevelop/CodeboyBlog/HEAD/about/img/tmall.png -------------------------------------------------------------------------------- /img/post-bg-java.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/androiddevelop/CodeboyBlog/HEAD/img/post-bg-java.jpg -------------------------------------------------------------------------------- /img/post-bg-unix.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/androiddevelop/CodeboyBlog/HEAD/img/post-bg-unix.jpg -------------------------------------------------------------------------------- /img/post-bg-web.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/androiddevelop/CodeboyBlog/HEAD/img/post-bg-web.jpg -------------------------------------------------------------------------------- /img/ustc_client.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/androiddevelop/CodeboyBlog/HEAD/img/ustc_client.png -------------------------------------------------------------------------------- /img/message_to_mail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/androiddevelop/CodeboyBlog/HEAD/img/message_to_mail.png -------------------------------------------------------------------------------- /img/post-bg-android.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/androiddevelop/CodeboyBlog/HEAD/img/post-bg-android.jpg -------------------------------------------------------------------------------- /img/post-bg-iphone.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/androiddevelop/CodeboyBlog/HEAD/img/post-bg-iphone.jpg -------------------------------------------------------------------------------- /img/post-bg-theory.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/androiddevelop/CodeboyBlog/HEAD/img/post-bg-theory.jpg -------------------------------------------------------------------------------- /search/img/cb-close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/androiddevelop/CodeboyBlog/HEAD/search/img/cb-close.png -------------------------------------------------------------------------------- /img/ios-restrict-app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/androiddevelop/CodeboyBlog/HEAD/img/ios-restrict-app.png -------------------------------------------------------------------------------- /img/post-bg-tranquil.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/androiddevelop/CodeboyBlog/HEAD/img/post-bg-tranquil.jpg -------------------------------------------------------------------------------- /search/img/cb-search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/androiddevelop/CodeboyBlog/HEAD/search/img/cb-search.png -------------------------------------------------------------------------------- /about/fonts/fontawesome.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/androiddevelop/CodeboyBlog/HEAD/about/fonts/fontawesome.eot -------------------------------------------------------------------------------- /about/fonts/fontawesome.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/androiddevelop/CodeboyBlog/HEAD/about/fonts/fontawesome.ttf -------------------------------------------------------------------------------- /about/fonts/fontawesome.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/androiddevelop/CodeboyBlog/HEAD/about/fonts/fontawesome.woff -------------------------------------------------------------------------------- /about/fonts/timelineicons/ecoico.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/androiddevelop/CodeboyBlog/HEAD/about/fonts/timelineicons/ecoico.eot -------------------------------------------------------------------------------- /about/fonts/timelineicons/ecoico.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/androiddevelop/CodeboyBlog/HEAD/about/fonts/timelineicons/ecoico.ttf -------------------------------------------------------------------------------- /about/fonts/timelineicons/ecoico.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/androiddevelop/CodeboyBlog/HEAD/about/fonts/timelineicons/ecoico.woff -------------------------------------------------------------------------------- /wechat/template: -------------------------------------------------------------------------------- 1 | --- 2 | layout: null 3 | --- 4 | {% for post in site.posts %} 5 | {% if forloop.rindex == cb_page_index %} 6 | {{ post.content }} 7 | {% endif %} 8 | {% endfor %} 9 | -------------------------------------------------------------------------------- /_layouts/default.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {% include head.html %} 5 | 6 | 7 | 8 | {% include nav.html %} 9 | 10 | {{ content }} 11 | 12 | {% include footer.html %} 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /wechat/create.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 创建目录 4 | if [ ! -d content ] 5 | then 6 | mkdir content; 7 | fi 8 | 9 | # 生成文件 10 | position=1; 11 | for loop in `ls ../_posts` 12 | do 13 | id=${loop/.md/}; 14 | echo "$id $position"; 15 | content=`cat template`; 16 | content=${content/cb_page_index/$position} 17 | echo "${content}" > "content/$id" 18 | ((position++)); 19 | done 20 | -------------------------------------------------------------------------------- /search/cb-search.json: -------------------------------------------------------------------------------- 1 | --- 2 | layout: null 3 | --- 4 | { 5 | "code" : 0 , 6 | "data" : [ 7 | {% for post in site.posts %} 8 | { 9 | "title" : "{{ post.title }} - {% for tag in post.tags %}{% if forloop.rindex != 1 %}{{ tag }}_{% else %}{{ tag }}{% endif %}{% endfor %}", 10 | "url" : "{{ post.url }}" 11 | } 12 | {% if forloop.rindex != 1 %} 13 | , 14 | {% endif %} 15 | {% endfor %} 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /_posts/2014-11-16-apache-user-authorized.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: 'Apache下配置认证用户' 4 | date: '2014-11-16' 5 | header-img: "img/post-bg-unix.jpg" 6 | tags: 7 | - server 8 | author: 'Codeboy' 9 | --- 10 | 11 | 12 | 有时候我们需要给我apache服务器下制定的目录加上用户认证,方便一些而用户进行文件的浏览。配置如下: 13 | 14 | 1 设置用户 15 | ---- 16 | htpasswd -c file_path user_name 17 | 18 | 回车之后输入密码即可,请确保命令中的file _path有其他用户读的权限。 19 | 20 | 2 设置apache 21 | ---- 22 | 在/etc/apache2/apache2.conf或/etc/httpd/conf/httpd.conf中添加以下内容 23 | 24 | 25 | AuthName "Important Directory" #登录时提示的内容 26 | AuthType Basic #认证方式 27 | IndexOptions Charset=GB2312 #网页编码 28 | Options Indexes FollowSymLinks MultiViews #以目录形式展示 29 | AuthUserFile /opt/.apache_user #用户文件,1中file_path 30 | Require valid-user 31 | 32 | 33 | 若要隐藏服务器标示,请在配置文件中加入以下信息: 34 | 35 | ServerSignature Off 36 | ServerTokens Prod 37 | 38 | > 如有任何知识产权、版权问题或理论错误,还请指正。 39 | > 40 | > 转载请注明原作者及以上信息。 41 | -------------------------------------------------------------------------------- /_posts/2015-05-08-js-rorate-image.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: ' Js实现旋转的图片' 4 | date: '2015-05-08' 5 | header-img: "img/post-bg-web.jpg" 6 | tags: 7 | - web 8 | author: 'Codeboy' 9 | --- 10 | 11 | gif可以实现旋转的图片,但是怎么使用js实现的。自己想了一下,打算实现一下,整体思路也很简单,每隔一段时间,旋转一下图片,看起来就像在一直旋转一样。[实例地址](http://example.codeboy.me/rotate/) 12 | 13 | 旋转rotate.js的代码如下: 14 | 15 | /** 16 | * Created by YD on 5/7/15. 17 | * Base on Jquery 18 | */ 19 | var ele ; 20 | 21 | //自定义函数 22 | $.fn.extend({ 23 | rotate: function () { 24 | ele = this ; 25 | setInterval('singleRotate()',20); 26 | } 27 | }); 28 | 29 | //初始角度 30 | var degree = 0; 31 | 32 | //单次旋转 33 | function singleRotate() { 34 | //一次增加50度 35 | degree = degree + 50 * Math.PI / 180; 36 | ele.css("transform","rotate("+degree+"deg)"); 37 | } 38 | 39 | 代码中只需引用一下js就行了,我将其封装后放在了服务器上,大家可以直接引用 40 | 41 | 引用前记得引用jquery,最后在自己的代码中调用rotate方法即可: 42 | 43 | $(element).rotate(); 44 | 45 | 46 | 47 | > 如有任何知识产权、版权问题或理论错误,还请指正。 48 | > 49 | > 转载请注明原作者及以上信息。 50 | -------------------------------------------------------------------------------- /_layouts/page.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 | 5 | 6 |
7 |
8 |
9 |
10 |
11 |

{% if page.title %}{{ page.title }}{% else %}{{ site.title }}{% endif %}

12 |
13 | {{ page.description }} 14 |
15 |
16 |
17 |
18 |
19 | 20 | 21 |
22 |
23 |
24 |
25 | {{ content }} 26 |
27 |
28 |
29 |
-------------------------------------------------------------------------------- /_posts/2015-07-10-java-operate.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: 'a+=b 等价于 a=a+b ?' 4 | date: '2015-07-10' 5 | header-img: "img/home-bg.jpg" 6 | tags: 7 | - java 8 | author: 'Codeboy' 9 | --- 10 | 11 | **a += b**和**a = a + b**完全等价么(java)?可能很多人以为是一样的,其实并非等价的,下面看一下证据吧。 12 | 13 | public class Test { 14 | public static void main(String[] args) { 15 | int a = 0; 16 | float c = 2.0f; 17 | a += c; 18 | a = a + c; //① 19 | } 20 | } 21 | 22 | 上面的代码有问题么? 能够通过编译么? 答案是**否定的**。 23 | 24 | $ javac Test.java 25 | Test.java:6: error: possible loss of precision 26 | a = a + c; 27 | ^ 28 | required: int 29 | found: float 30 | 1 error 31 | 32 | 出现的问题是编译错误, 但是**a += c**却不会出现编译错误,能够正常通过编译。 33 | 34 | **为什么为这样呢?** 35 | 36 | 我们将**①**处代码去除后,顺利编译,可以使用jd-gui等工具看一下**a += c**的反编译后的代码: 37 | 38 | public class Test 39 | { 40 | public static void main(String[] paramArrayOfString) 41 | { 42 | int i = 0; 43 | float f = 2.0F; 44 | i = (int)(i + f); 45 | } 46 | } 47 | 48 | 看一下以下这句: 49 | 50 | i = (int)(i + f); 51 | 52 | 可以看出**a += c**在编译的时候做了强制类型转换。 53 | 54 | 结论: 55 | 对于 a += c 56 | 如果a的类型可以兼容b,则 (a += c) 等价于 (a = a + c) 57 | 否则,则会在a与c做完加法后进行强制转换。 58 | 59 | > 如有任何知识产权、版权问题或理论错误,还请指正。 60 | > 61 | > 转载请注明原作者及以上信息。 62 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | description: "编码生涯的点点滴滴" 4 | --- 5 | 6 | {% for post in paginator.posts %} 7 |
8 | 9 |

{{ post.title }} 10 |

11 | {% if post.subtitle %} 12 |

13 | {{ post.subtitle }} 14 |

15 | {% endif %} 16 |
17 | {{ post.content | strip_html | truncate:200 }} 18 |
19 |
20 |

Posted by {% if post.author %}{{ post.author }}{% else %}{{ site.title }}{% endif %} on {{ post.date | date: "%B %-d, %Y" }}

21 | 22 |
23 |
24 | {% endfor %} 25 | 26 | 27 | {% if paginator.total_pages > 1 %} 28 | 40 | {% endif %} 41 | -------------------------------------------------------------------------------- /js/codeboy.min.js: -------------------------------------------------------------------------------- 1 | $(function(){$("[data-toggle='tooltip']").tooltip()});$(document).ready(function(){$("table").wrap("
");$("table").addClass("table")});$(document).ready(function(){$('iframe[src*="youku.com"]').wrap('
');$('iframe[src*="youku.com"]').addClass("embed-responsive-item");$('iframe[src*="vimeo.com"]').wrap('
');$('iframe[src*="vimeo.com"]').addClass("embed-responsive-item")});jQuery(document).ready(function(b){var c=2500;if(b(window).width()>c){var a=b(".navbar-custom").height();b(window).on("scroll",{previousTop:0},function(){var d=b(window).scrollTop();if(d0&&b(".navbar-custom").hasClass("is-fixed")){b(".navbar-custom").addClass("is-visible")}else{b(".navbar-custom").removeClass("is-visible is-fixed")}}else{b(".navbar-custom").removeClass("is-visible");if(d>a&&!b(".navbar-custom").hasClass("is-fixed")){b(".navbar-custom").addClass("is-fixed")}}this.previousTop=d})}hljs.initHighlightingOnLoad();b("pre code").each(function(){if(b(this).attr("class")!=="language-nohighlight"){let content=b(this).html();if(content.split("\n").length<=4){return}let content2=content.replace(/\n/g,"\n
  • ");content2=content2.substring(0,content2.length-4);b(this).html("")}})}); -------------------------------------------------------------------------------- /about/fonts/fontawesome.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | This is a custom SVG font generated by IcoMoon. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /feed.xml: -------------------------------------------------------------------------------- 1 | --- 2 | layout: null 3 | --- 4 | 5 | 6 | 7 | {{ site.title | xml_escape }} 8 | {{ site.description | xml_escape }} 9 | {{ site.url }}{{ site.baseurl }}/ 10 | 11 | {{ site.time | date_to_rfc822 }} 12 | {{ site.time | date_to_rfc822 }} 13 | Jekyll v{{ jekyll.version }} 14 | {% for post in site.posts limit:10 %} 15 | 16 | {{ post.title | xml_escape }} 17 | {{ post.content | xml_escape }} 18 | {{ post.date | date_to_rfc822 }} 19 | {{ post.url | prepend: site.baseurl | prepend: site.url }} 20 | {{ post.url | prepend: site.baseurl | prepend: site.url }} 21 | {% for tag in post.tags %} 22 | {{ tag | xml_escape }} 23 | {% endfor %} 24 | {% for cat in post.categories %} 25 | {{ cat | xml_escape }} 26 | {% endfor %} 27 | 28 | {% endfor %} 29 | 30 | 31 | -------------------------------------------------------------------------------- /_posts/2014-11-26-android-viewpager.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: 'ViewPager自适应高度' 4 | date: '2014-11-26' 5 | header-img: "img/post-bg-android.jpg" 6 | tags: 7 | - android 8 | author: 'Codeboy' 9 | --- 10 | 11 | 在使用ViewPager的时候发现不能自适应高度,可以重写ViewPager的onMeasure来解决,代码如下: 12 | 13 | import android.content.Context; 14 | import android.support.v4.view.ViewPager; 15 | import android.util.AttributeSet; 16 | import android.view.View; 17 | 18 | /** 19 | * 自定义viewPager,实现ViewPager自定义高度 20 | * 21 | * @author Yuedong Li 22 | * 23 | */ 24 | public class CBViewPager extends ViewPager { 25 | 26 | public CBViewPager(Context context, AttributeSet attrs) { 27 | super(context, attrs); 28 | } 29 | 30 | public CBViewPager(Context context) { 31 | super(context); 32 | } 33 | 34 | /** 35 | * 将child高度传递给父类构造函数 36 | */ 37 | @Override 38 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 39 | 40 | int height = 0; 41 | // 下面遍历所有child的高度 42 | for (int i = 0; i < getChildCount(); i++) { 43 | View child = getChildAt(i); 44 | child.measure(widthMeasureSpec, 45 | MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); 46 | int h = child.getMeasuredHeight(); 47 | if (h > height) // 采用最大的view的高度。 48 | height = h; 49 | } 50 | 51 | heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, 52 | MeasureSpec.EXACTLY); 53 | 54 | super.onMeasure(widthMeasureSpec, heightMeasureSpec); 55 | } 56 | } 57 | 58 | 直接使用CBViewPager就可以了。 59 | 60 | > 如有任何知识产权、版权问题或理论错误,还请指正。 61 | > 62 | > 转载请注明原作者及以上信息。 63 | -------------------------------------------------------------------------------- /_posts/2015-07-11-jekyll-search.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: '给jekyll添加炫酷简洁的搜索' 4 | date: '2015-07-11' 5 | header-img: "img/post-bg-web.jpg" 6 | tags: 7 | - web 8 | author: 'Codeboy' 9 | --- 10 | 11 | 试试**双击Ctrl键**看看,或者点击**右下角搜索图标** 12 | 13 | 博客从wordpress的jekyll,jekyll的核心思想: 14 | 15 | 将纯文本转化为静态网站和博客 16 | 17 | jekyll是一个简单的免费的Blog生成工具,类似WordPress。但是和WordPress又有很大的不同,原因是jekyll只是一个生成静态网页的工具,不需要数据库支持。但是可以配合第三方服务,例如Disqus。最关键的是jekyll可以免费部署在Github上,而且可以绑定自己的域名。 18 | 19 | jekyll没有数据库支持,默认没有搜索功能,那么怎么添加炫酷简洁的搜索的功能呢?google一下,大部分都是使用插件之类的,起始我们可以直接在服务端产生索引,之后利用索引进行搜索。 20 | 21 | 受到spotlight的简洁启发,在目前小胖轩导航栏上已经没有空间了,于是打算做出一个类似于spotlight的搜索。下面先看一下操作步骤: 22 | 23 | ① 服务端生成文章索引 24 | ② 浏览器获取文章索引 25 | ③ 页面交互以及按键控制 26 | 27 | ### 服务器生成文章索引 28 | 29 | --- 30 | layout: null 31 | --- 32 | { 33 | "code" : 0 , 34 | "data" : [ 35 | {\% for post in site.posts \%} 36 | { 37 | "title" : "{{ post.title }} - {\% for tag in post.tags \%}{\% if forloop.rindex != 1 \%}{{ tag }}_{\% else \%}{{ tag }}{\% endif \%}{\% endfor \%}", 38 | "url" : "{{ post.url }}" 39 | } 40 | {\% if forloop.rindex != 1 \%} 41 | , 42 | {\% endif \%} 43 | {\% endfor \%} 44 | ] 45 | } 46 | 47 | > 1. 由于文章中的动态代码会被解析,所以做了替换,代码中%被替换成\%,使用中请去除%前面的转义符 48 | > 2. liquid语言对行敏感,如果需要把2个字符串拼接一起,那么字符串必须在同一行,否则字符串间将加入回车符 49 | 50 | 这段代码是一个双层循环,将文章的标题与标签组合,同时和url一起组合为json字符串,方便后续ajax调用。 51 | 52 | ### 浏览器获取文章索引 53 | 54 | 此处也即一个ajax调用,使用$.ajax或者$.getJson都可以,此处可以参考一下ajax的异步请求。 55 | 56 | ### 页面交互以及按键控制 57 | 58 | 为了能够有一个更好的交互,对搜索进行了很多的按键的操作: 59 | 60 | - PC下双击Ctrl键打开或者关闭搜索框 61 | - 搜索框展示时按下Esc键关闭搜索框 62 | 63 | 按键的检测在js中也是很容易进行,此处也不在列代码了。 64 | 65 | 为了移动端也可以很好的搜索,在页面的右下角加入搜索悬浮按钮,点击后打开搜索页面,而在搜索页面,右上角提供关闭按钮,这样整体下来就完美的实现了搜索。 66 | 67 | 68 | 69 | > 如有任何知识产权、版权问题或理论错误,还请指正。 70 | > 71 | > 转载请注明原作者及以上信息。 72 | -------------------------------------------------------------------------------- /_posts/2015-07-28-android-trick.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: 'Android开发及使用技巧' 4 | date: '2015-07-28' 5 | header-img: "img/post-bg-android.jpg" 6 | tags: 7 | - android 8 | author: 'Codeboy' 9 | --- 10 | 11 | ### 1. 查看wifi密码 12 | 13 | 查询连接的wifi密码,没问题,前提是手机已经root了,可以查看系统文件,android的wifi密码明文保存在一下文件中,使用root explorer查看即可。 14 | 15 | /data/misc/wifi/wpa_supplicant.conf 16 | 17 | 18 | ### 2. 查看activity堆栈情况 19 | 20 | adb shell dumpsys activity ---------------查看ActvityManagerService 所有信息 21 | adb shell dumpsys activity activities ----------查看Activity组件信息 22 | adb shell dumpsys activity services -----------查看Service组件信息 23 | adb shell dumpsys activity providers ----------产看ContentProvider组件信息 24 | adb shell dumpsys activity broadcasts --------查看BraodcastReceiver信息 25 | adb shell dumpsys activity intents --------------查看Intent信息 26 | adb shell dumpsys activity processes ---------查看进程信息 27 | 28 | 29 | ### 3. 查看apk中的AndroidManifest.xml文件 30 | 31 | 可以使用apktool对apk进行反编译,不过现在很多的apk都进行了加固,可以防止apktool进行反编译,我们可以使用google提供的aapt(Android Asset Packaging Tool)进行查看: 32 | 33 | aapt dump xmltree target.apk AndroidManifest.xml 34 | 35 | >其中target.apk为需要查看AndroidManifest.xml的apk包。 36 | 37 | 38 | ### 4. 查看android的log 39 | 40 | adb logcat 41 | 42 | "-s"选项 : 设置输出日志的标签, 只显示该标签的日志; 43 | 44 | "-f"选项 : 将日志输出到文件, 默认输出到标准输出流中, -f 参数执行不成功; 45 | 46 | "-r"选项 : 按照每千字节输出日志, 需要 -f 参数, 不过这个命令没有执行成功; 47 | 48 | "-n"选项 : 设置日志输出的最大数目, 需要 -r 参数, 这个执行 感觉 跟 adb logcat 效果一样; 49 | 50 | "-v"选项 : 设置日志的输出格式, 注意只能设置一项; 51 | 52 | "-c"选项 : 清空所有的日志缓存信息; 53 | 54 | "-d"选项 : 将缓存的日志输出到屏幕上, 并且不会阻塞; 55 | 56 | "-t"选项 : 输出最近的几行日志, 输出完退出, 不阻塞; 57 | 58 | "-g"选项 : 查看日志缓冲区信息; 59 | 60 | "-b"选项 : 加载一个日志缓冲区, 默认是 main, 下面详解; 61 | 62 | "-B"选项 : 以二进制形式输出日志; 63 | 64 | 65 | 66 | 持续更新... 67 | 68 | > 如有任何知识产权、版权问题或理论错误,还请指正。 69 | > 70 | > 转载请注明原作者及以上信息。 71 | -------------------------------------------------------------------------------- /search/css/cb-search.css: -------------------------------------------------------------------------------- 1 | @media screen and (min-width: 768px) { 2 | .dropdown-menu { 3 | position:relative; 4 | float: none; 5 | font-size: 20px; 6 | width: 70%; 7 | margin: 0 15%; 8 | } 9 | 10 | .cb-search-tool ul{ 11 | width: 70% ; 12 | white-space:nowrap; 13 | overflow:hidden; 14 | text-overflow: ellipsis; 15 | } 16 | 17 | 18 | .cb-search-content { 19 | width: 70%; 20 | margin: 0 15%; 21 | position: absolute; 22 | top: 13%; 23 | left: auto; 24 | right: auto; 25 | font-size: 22px; 26 | height: 50px; 27 | background-color: #eee; 28 | color: black; 29 | opacity: 1.0; 30 | } 31 | } 32 | 33 | @media screen and (max-width: 767px) { 34 | .dropdown-menu { 35 | position:relative; 36 | float: none; 37 | font-size: 20px; 38 | width: 96%; 39 | margin: 0 2%; 40 | } 41 | .cb-search-tool ul{ 42 | width: 96% ; 43 | white-space:nowrap; 44 | overflow:hidden; 45 | text-overflow: ellipsis; 46 | } 47 | 48 | .cb-search-content { 49 | width: 96%; 50 | margin: 0 2%; 51 | position: absolute; 52 | top: 10%; 53 | left: auto; 54 | right: auto; 55 | font-size: 22px; 56 | height: 50px; 57 | background-color: #eee; 58 | color: black; 59 | opacity: 1.0; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /_posts/2014-11-06-java-trick-1.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: '不劳而获' 4 | date: '2014-11-06' 5 | header-img: "img/home-bg.jpg" 6 | tags: 7 | - java 8 | author: 'Codeboy' 9 | --- 10 | 11 | 12 | 下面的程序将打印一个单词,其首字母有一个随机生成器选择,请描述改程序的行为: 13 | 14 | import java.util.Random; 15 | 16 | public class Main { 17 | private static Random rnd = new Random(); 18 | 19 | public static void main(String[] args) { 20 | StringBuffer word = null; 21 | switch (rnd.nextInt(2)) { 22 | case 1: 23 | word = new StringBuffer('P'); 24 | case 2: 25 | word = new StringBuffer('G'); 26 | default: 27 | word = new StringBuffer('M'); 28 | } 29 | word.append('a'); 30 | word.append('i'); 31 | word.append('n'); 32 | System.out.println(word); 33 | } 34 | 35 | 咋一看这个程序可能会在一次又一次的运行中以相等概率的输出Pain, Gain, Main.是这样吗? 36 | 37 | 聪明的您可能发现问题了, Random.nextInt(int n)的范围是在0-n之间,含0不含n,所以整体上Random.nextInt(2)只会产生0或者1,所以程序是不会打印出Gain的,应该是等概率的输出Main与Pain。(**栅栏柱错误**) 38 | 39 | 看起来似乎正确了,但是哪里还是有些问题。看到了,是switch循环后面没有加上break,这样的话,Random.nextInt(2)产生1时会将3个case语句全部执行,也即相当于执行default里的语句;Random.nextInt(2)产生0时也是执行default里的语句,这样下来最终的结果只能有一个,那就是Main了。(**switch-case-break错误**) 40 | 41 | 复制代码,运行一下,发现结果是ain,不管运行多少次,结果都是一样的,为什么没有打印出M呢,下面我们来看一下StringBuffer,StringBuffer类没有对应的字符构造函数,在eclipse中可以将鼠标放在case中的构造器中,提示了一下内容: 42 | 43 | java.lang.StringBuffer.StringBuffer(int capacity) 44 | 45 | Constructs a string buffer with no characters in it and the specified initial capacity. 46 | 47 | Parameters: 48 | capacity the initial capacity. 49 | Throws: 50 | NegativeArraySizeException - if the capacity argument is less than 0. 51 | 52 | 这下明白了,原来StringBuffer('M')在构造的时候,是构造了一个容量为'M'对应ascii值大小的初始容量,之后再附加字符之前,都没有任何内容,所以最终的结果始终是Main。(**非常规方法使用错误**) 53 | 54 | 上面的3处错误或者问题是经常出现的,希望大家都能够多注意。 55 | 56 | 57 | > 如有任何知识产权、版权问题或理论错误,还请指正。 58 | > 59 | > 转载请注明原作者及以上信息。 60 | -------------------------------------------------------------------------------- /_includes/head.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | {% if page.title %}{{ page.title }} - {{ site.title }}{% else %}{{ site.title }}{% endif %} 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 24 | 25 | 26 | 27 | 28 | 29 | 33 | 34 | 42 | 43 | -------------------------------------------------------------------------------- /_includes/nav.html: -------------------------------------------------------------------------------- 1 | 2 | 50 | -------------------------------------------------------------------------------- /_posts/2015-04-29-java-hashmap-trick.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: 'HashMap的小优化' 4 | date: '2015-04-29' 5 | header-img: "img/home-bg.jpg" 6 | tags: 7 | - java 8 | author: 'Codeboy' 9 | --- 10 | 11 | HashMap是我们平日内用的非常多的集合框架,网上介绍有很多的实现原理,在存放数据数量已知的情况下,我们可以在构建hashmap的时候指定其容量,减少扩展空间时消耗的时间。下面看一个例子: 12 | 13 | import java.util.HashMap; 14 | import java.util.Map; 15 | 16 | /** 17 | * HashMap测试 18 | * 19 | * @author YD 20 | * 21 | */ 22 | public class MapTest { 23 | public static void main(String[] args) { 24 | int num = 10000; //数据容量 25 | Map map1 = new HashMap(); 26 | Map map2 = new HashMap(num); 27 | Map map3 = new HashMap(num * 2); 28 | 29 | long time1 = System.currentTimeMillis(); 30 | for (int i = 0; i < num; i++) 31 | map1.put(i, "haha"); 32 | long time2 = System.currentTimeMillis(); 33 | for (int i = 0; i < num; i++) 34 | map2.put(i, "haha"); 35 | long time3 = System.currentTimeMillis(); 36 | for (int i = 0; i < num; i++) 37 | map3.put(i, "haha"); 38 | long time4 = System.currentTimeMillis(); 39 | System.out.println("map1 time: " + (time2 - time1) + "ms"); 40 | System.out.println("map2 time: " + (time3 - time2) + "ms"); 41 | System.out.println("map3 time: " + (time4 - time3) + "ms"); 42 | } 43 | } 44 | 45 | 46 | 在数据量为10000的时候,多次测试,得出的较多的结果是 47 | 48 | map1 time: 14ms 49 | map2 time: 9ms 50 | map3 time: 4ms 51 | 52 | 在数据量为100000的时候,结果如下 53 | 54 | map1 time: 31ms 55 | map2 time: 16ms 56 | map3 time: 9ms 57 | 58 | 如果数据量更大的时候,升值1000000(一百万)时,结果如下 59 | 60 | map1 time: 119ms 61 | map2 time: 47ms 62 | map3 time: 59ms 63 | 64 | 数据量再增加10倍后(一千万),结果如下 65 | 66 | map1 time: 7718ms 67 | map2 time: 1035ms 68 | map3 time: 2156ms 69 | 70 | 可以看出,当我们预先知道数据量的时候,在构建hashmap的时候指定数据容量,可以在数据量大的时候减少消耗时间。指定数据容量时,不应该过多的分配空间。 71 | 72 | 73 | > 如有任何知识产权、版权问题或理论错误,还请指正。 74 | > 75 | > 转载请注明原作者及以上信息。 76 | -------------------------------------------------------------------------------- /_posts/2015-07-20-get-max-from-every-group.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: '获取所有分组中某列最大的行' 4 | date: '2015-07-20' 5 | header-img: "img/home-bg.jpg" 6 | tags: 7 | - database 8 | author: 'Codeboy' 9 | --- 10 | 11 | **怎么获取所有分组中某列最大的行?**下面用一个例子来说明下: 12 | 13 | 一共公司有若干员工,每个员工有各自的id, group_id(部门), salary(工资).现在的问题转变为 14 | 15 | 求公司各部门最高工资的员工 16 | 17 | 首先明确一个问题,一个部门的若干个员工可能同时拥有最高的工资,需要都列举出来。 18 | 19 | 看一下员工的数据库表结构(只包含有用的列): 20 | 21 | 22 | | Field | Type | Null | Key | Default | Extra | 23 | |----------|---------|------|-----|---------|-------| 24 | | id | int(11) | NO | PRI | NULL | | 25 | | group_id | int(11) | YES | | NULL | | 26 | | salary | int(11) | YES | | NULL | | 27 | 28 | 添加的测试数据如下: 29 | 30 | | id | group_id | salary | 31 | |----|----------|--------| 32 | | 1 | 1 | 100 | 33 | | 2 | 1 | 200 | 34 | | 3 | 1 | 200 | 35 | | 4 | 2 | 200 | 36 | | 5 | 2 | 300 | 37 | 38 | 我们需要做的步骤如下: 39 | 40 | - 1. 获取各个部门最高的工资 41 | - 2. 查找各个部门工资等于最高工资的员工 42 | 43 | #### 获取各个部门最高的工资 44 | 45 | select group_id, max(salary) as max_salary from employee group by group_id ; 46 | 47 | 执行后的结果: 48 | 49 | | group_id | max_salary | 50 | |----------|------------| 51 | | 1 | 200 | 52 | | 2 | 300 | 53 | 54 | #### 查找各个部门工资等于最高工资的员工 55 | 56 | select a.id, a.group_id, a.salary from employee as a, b where a.group_id=b.group_id and a.salary=b.max_salary ; 57 | 58 | >假设第一执行后的数据存在表b中。 59 | 60 | 这样就得到了最终的结果: 61 | 62 | | id | group_id | salary | 63 | |----|----------|--------| 64 | | 2 | 1 | 200 | 65 | | 3 | 1 | 200 | 66 | | 5 | 2 | 300 | 67 | 68 | 我们可以简单的将**获取各个部门最高的工资**的代码替换b即可,组合后的语句如下: 69 | 70 | select a.id, a.group_id, a.salary from employee as a, (select group_id, max(salary) as max_salary from employee group by group_id) as b where a.group_id=b.group_id and a.salary=b.max_salary ; 71 | 72 | 执行后的结果相同。 73 | 74 | #### 总结 75 | 我们首先按照部门进行分组,获取每组最大的工资(表b); 之后将表a(原表)与表b做一下笛卡尔积,筛选出我们需要的数据即可。 76 | 77 | > 如有任何知识产权、版权问题或理论错误,还请指正。 78 | > 79 | > 转载请注明原作者及以上信息。 80 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | ######################站点全局信息,需要部分修改######################### 2 | # Site settings 3 | title: "小胖轩" 4 | header-img: "img/home-bg.jpg" 5 | email: "app@codeboy.me" 6 | url: "http://127.0.0.1" 7 | description: "编码生涯的点点滴滴" 8 | github_username: "androiddevelop" 9 | zhihu_username: "codeboy" 10 | 11 | changyan_appid: "'changyan_appid'" 12 | changyan_conf: "'changyan_conf'" 13 | ##########################上述信息需要您修改,changyan_appid、changyan_conf############################ 14 | 15 | 16 | # Where things are 17 | source: . 18 | destination: ./_site 19 | plugins_dir: ./_plugins 20 | layouts_dir: ./_layouts 21 | data_dir: ./_data 22 | includes_dir: ./_includes 23 | posts_dir: ./_posts 24 | #collections: null 25 | 26 | # Handling Reading 27 | safe: false 28 | include: [".htaccess"] 29 | exclude: ["less","node_modules","Gruntfile.js","package.json","README.md","tmp","unless"] 30 | keep_files: [".git", ".svn"] 31 | encoding: "utf-8" 32 | markdown_ext: "markdown,mkdown,mkdn,mkd,md" 33 | 34 | # Filtering Content 35 | show_drafts: null 36 | limit_posts: 0 37 | future: false 38 | unpublished: false 39 | 40 | # Plugins 41 | whitelist: [] 42 | plugins: ["jekyll-paginate"] 43 | #gems: [] 44 | 45 | # Conversion 46 | markdown: kramdown 47 | highlighter: pygments 48 | lsi: false 49 | excerpt_separator: "\n\n" 50 | incremental: false 51 | 52 | # Serving 53 | detach: false 54 | port: 4000 55 | host: 127.0.0.1 56 | baseurl: "" # does not include hostname 57 | 58 | # Outputting 59 | permalink: pretty 60 | paginate: 16 61 | paginate_path: /page/:num 62 | timezone: Asia/Shanghai 63 | 64 | quiet: false 65 | defaults: [] 66 | 67 | 68 | # Markdown Processors 69 | kramdown: 70 | auto_ids: true 71 | footnote_nr: 1 72 | entity_output: as_char 73 | toc_levels: 1..6 74 | smart_quotes: lsquo,rsquo,ldquo,rdquo 75 | input: GFM 76 | 77 | syntax_highlighter_opts: 78 | wrap: div 79 | line_numbers: nil 80 | line_number_start: 1 81 | tab_width: 4 82 | bold_every: 10 83 | css: style 84 | -------------------------------------------------------------------------------- /tags.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: Tags 3 | layout: default 4 | header-img: "img/tags-bg.jpg" 5 | --- 6 | 7 | 8 |
    9 |
    10 |
    11 |
    12 |
    13 |

    {% if page.title %}{{ page.title }}{% else %}{{ site.title }}{% endif %}

    14 | {{ page.description }} 15 |
    16 |
    17 |
    18 |
    19 |
    20 | 21 | 22 |
    23 |
    24 |
    25 | 26 |
    27 | {% for tag in site.tags %} 28 | {{ tag[0] }} 29 | {% endfor %} 30 |
    31 | 32 |
    33 | 标签命名规则: 34 |
  • 一篇文章相关的领域都将打上标签
  • 35 |
  • 每个便签下含有所有包含此标签的文章
  • 36 |
    37 | 38 | 39 | {% for tag in site.tags %} 40 |
    41 | {{ tag[0] }} 42 | {% for post in tag[1] %} 43 |
    44 | 45 |

    {{ post.title }} 46 |

    47 | {% if post.subtitle %} 48 |

    49 | {{ post.subtitle }} 50 |

    51 | {% endif %} 52 |
    53 | 54 |
    55 |
    56 | {% endfor %} 57 |
    58 | {% endfor %} 59 | 60 |
    61 |
    62 |
    63 | -------------------------------------------------------------------------------- /_posts/2015-07-02-image-gray.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: '图片灰度化' 4 | date: '2015-07-02' 5 | tags: 6 | - java 7 | - discover 8 | author: 'Codeboy' 9 | --- 10 | 怎么将图片灰度化,看到一个黑白滤镜的实现,黑白滤镜原理十分简单,是根据各种颜色在人眼中的亮度响应将rgb三通道的像素转换成单通道的灰度像素.而对于彩色转灰度,有一个很著名的心理学公式: 11 | 12 | Gray = R*0.299 + G*0.587 + B*0.114 13 | 14 | 下面看一下具体怎么使用,怎么讲一张彩色照片转变为黑白照片。看一段java代码: 15 | 16 | package me.codeboy.lyd.image; 17 | 18 | import javax.imageio.ImageIO; 19 | import java.awt.*; 20 | import java.awt.image.BufferedImage; 21 | import java.io.File; 22 | import java.io.IOException; 23 | 24 | /** 25 | * Created by yuedong on 7/2/15. 26 | */ 27 | public class GrayImage { 28 | public static void main(String[] args) throws IOException { 29 | File file = new File("src.png"); 30 | File out = new File("out.png"); 31 | BufferedImage image = ImageIO.read(file); 32 | int width = image.getWidth(); 33 | int height = image.getHeight(); 34 | for (int i = 0; i < width; i++) { 35 | for (int j = 0; j < height; j++) { 36 | int rgb = image.getRGB(i, j); 37 | int r = rgb & 0x00ff0000 >> 16; 38 | int g = rgb & 0x0000ff00 >> 8; 39 | int b = rgb & 0x000000ff; 40 | 41 | //根据公式计算 42 | int color = (int) (r * 0.299 + g * 0.587 + b * 0.114); 43 | image.setRGB(i, j, new Color(color, color, color).getRGB()); 44 | } 45 | } 46 | ImageIO.write(image, "PNG", out); 47 | 48 | //rgb相同下产生的图片 49 | BufferedImage colorImage = new BufferedImage(256, 256 * 3, BufferedImage.TYPE_3BYTE_BGR); 50 | for (int i = 0; i < 256; i++) { 51 | for (int j = 0; j < 256 * 3; j++) { 52 | int k = j/3; 53 | colorImage.setRGB(i,j,new Color(k,k,k).getRGB()); 54 | } 55 | } 56 | 57 | File colorFile = new File("color.png"); 58 | ImageIO.write(colorImage, "PNG", colorFile); 59 | } 60 | } 61 | 62 | 代码进行了2个操作,一个讲图片进行灰度化,怎么进行灰度化呢,可以看出,仅仅是获取每一个点的rgb值,按照公式计算出灰度值,然后设置新的rgb值,每一个r,g,b的值都是这个灰度值。处理前后的照片如下: 63 | ![img](/img/image-src.png) 64 | ![img](/img/image-gray.png) 65 | 66 | 为什么呢?因为r=g=b时,获取的颜色的区间就是由黑到白,紧接着的代码就是将r=g=b的颜色绘制出来,图片如下(最上面的是r=g=b=0,最下面的是r=g=b=255): 67 | ![img](/img/image-rgb.png) 68 | 69 | 70 | > 如有任何知识产权、版权问题或理论错误,还请指正。 71 | > 72 | > 转载请注明原作者及以上信息。 73 | -------------------------------------------------------------------------------- /_posts/2015-01-06-ftp-no-download.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: '配置ftp服务器只能上传不能进行其他操作' 4 | date: '2015-01-06' 5 | header-img: "img/post-bg-unix.jpg" 6 | tags: 7 | - server 8 | - web 9 | author: 'Codeboy' 10 | --- 11 | 12 | 又到期末考试了,今年当了数据挖掘助教,课程有一道编程大作业,需要搭建ftp服务器,实现文件上传,但是禁止下载重命名。 13 | 14 | 服务器系统是ubuntu12.04 server,使用的ftp服务器也是linux下大名鼎鼎的vsftpd,配置如下: 15 | 16 | **1. 创建用户dm,将其登录终端设置为/bin/false,防止用户ssh登录** 17 | 18 | useradd -m -s /bin/false dm 19 | 20 | **2. 将/bin/false加入/etc/shells中,使其可以使用dm用户进行ftp登录** 21 | 22 | echo "/bin/bash">>/etc/shells 23 | 24 | **3. 配置vsftpd.conf,禁止用户访问上层目录.自行创建/etc/vsftpd.chroot_list,不添加任何用户,在vsftpd.chroot_list中得用户可以切换到上层目录,我们这里需要禁止dm用户。主要配置如下:** 25 | 26 | chroot_local_user=YES 27 | chroot_list_enable=YES 28 | chroot_list_file=/etc/vsftpd.chroot_list 29 | 30 | **4. 添加相应权限,防止用户下载重命名** 31 | 32 | 使用cmds_allows命令配置,将不允许的命令(重命名,下载,删除,创建文件夹)除去即可: 33 | 34 | cmds_allowed=FEAT,REST,CWD,LIST,MDTM,NLST,PASS,PASV,PORT,PWD,QUIT,RMD,SIZE,STOR,TYPE,USER,ACCT,APPE,CDUP,HELP,MODE,NOOP,REIN,STAT,STOU,STRU,SYST 35 | 36 | 37 | 主要命令解释如下: 38 | 39 | MKD - make a remote directory 新建文件夹 40 | NLST - name list of remote directory 41 | PWD - print working directory 显示当前工作目录 42 | RETR - retrieve a remote file 下载文件 43 | STOR - store a file on the remote host 上传文件 44 | DELE - delete a remote file 删除文件 45 | RMD - remove a remote directory 删除目录 46 | RNFR - rename from 重命名 47 | RNTO - rename to 重命名 48 | ABOR - abort a file transfer 取消文件传输 49 | CWD - change working directory 更改目录 50 | DELE - delete a remote file 删除文件 51 | LIST - list remote files 列目录 52 | MDTM - return the modification time of a file 返回文件的更新时间 53 | MKD - make a remote directory 新建文件夹 54 | NLST - name list of remote directory 55 | PASS - send password 56 | PASV - enter passive mode 57 | PORT - open a data port 打开一个传输端口 58 | PWD - print working directory 显示当前工作目录 59 | QUIT - terminate the connection 退出 60 | RETR - retrieve a remote file 下载文件 61 | RMD - remove a remote directory 62 | RNFR - rename from 63 | RNTO - rename to 64 | SITE - site-specific commands 65 | SIZE - return the size of a file 返回文件大小 66 | STOR - store a file on the remote host 上传文件 67 | TYPE - set transfer type 68 | USER - send username 69 | 70 | 71 | > 如有任何知识产权、版权问题或理论错误,还请指正。 72 | > 73 | > 转载请注明原作者及以上信息。 74 | -------------------------------------------------------------------------------- /js/jquery.tagcloud.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | 3 | $.fn.tagcloud = function(options) { 4 | var opts = $.extend({}, $.fn.tagcloud.defaults, options); 5 | tagWeights = this.map(function(){ 6 | return $(this).attr("rel"); 7 | }); 8 | tagWeights = jQuery.makeArray(tagWeights).sort(compareWeights); 9 | lowest = tagWeights[0]; 10 | highest = tagWeights.pop(); 11 | range = highest - lowest; 12 | if(range === 0) {range = 1;} 13 | // Sizes 14 | if (opts.size) { 15 | fontIncr = (opts.size.end - opts.size.start)/range; 16 | } 17 | // Colors 18 | if (opts.color) { 19 | colorIncr = colorIncrement (opts.color, range); 20 | } 21 | return this.each(function() { 22 | weighting = $(this).attr("rel") - lowest; 23 | if (opts.size) { 24 | $(this).css({"font-size": opts.size.start + (weighting * fontIncr) + opts.size.unit}); 25 | } 26 | if (opts.color) { 27 | // change color to background-color 28 | $(this).css({"backgroundColor": tagColor(opts.color, colorIncr, weighting)}); 29 | } 30 | }); 31 | }; 32 | 33 | $.fn.tagcloud.defaults = { 34 | size: {start: 14, end: 18, unit: "pt"} 35 | }; 36 | 37 | // Converts hex to an RGB array 38 | function toRGB (code) { 39 | if (code.length == 4) { 40 | code = jQuery.map(/\w+/.exec(code), function(el) {return el + el; }).join(""); 41 | } 42 | hex = /(\w{2})(\w{2})(\w{2})/.exec(code); 43 | return [parseInt(hex[1], 16), parseInt(hex[2], 16), parseInt(hex[3], 16)]; 44 | } 45 | 46 | // Converts an RGB array to hex 47 | function toHex (ary) { 48 | return "#" + jQuery.map(ary, function(i) { 49 | hex = i.toString(16); 50 | hex = (hex.length == 1) ? "0" + hex : hex; 51 | return hex; 52 | }).join(""); 53 | } 54 | 55 | function colorIncrement (color, range) { 56 | return jQuery.map(toRGB(color.end), function(n, i) { 57 | return (n - toRGB(color.start)[i])/range; 58 | }); 59 | } 60 | 61 | function tagColor (color, increment, weighting) { 62 | rgb = jQuery.map(toRGB(color.start), function(n, i) { 63 | ref = Math.round(n + (increment[i] * weighting)); 64 | if (ref > 255) { 65 | ref = 255; 66 | } else { 67 | if (ref < 0) { 68 | ref = 0; 69 | } 70 | } 71 | return ref; 72 | }); 73 | return toHex(rgb); 74 | } 75 | 76 | function compareWeights(a, b) 77 | { 78 | return a - b; 79 | } 80 | 81 | })(jQuery); 82 | -------------------------------------------------------------------------------- /apps.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title: "Apps" 4 | description: "实用 便捷 流畅 强大" 5 | header-img: "img/post-bg-android.jpg" 6 | --- 7 | 8 | 35 | 36 | 37 |
    38 | 50 |
    51 | 63 |
    64 | 76 | 77 |
    78 | 79 | 91 | 92 |
    93 |
    94 | -------------------------------------------------------------------------------- /_posts/2015-06-28-android-unleak-hander.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: 'Android Handler如何避免内存泄露' 4 | date: '2015-06-28' 5 | author: 'Codeboy' 6 | header-img: 'img/post-bg-android.jpg' 7 | tags: 8 | - android 9 | --- 10 | 在使用Android Handler的时候,可能会遇到编译器给我们这样的警告: 11 | 12 | This Handler class should be static or leaks might occur 13 | 14 | 造成这个警告的原因是handler持有外层类(Activity等)的引用,同时消息队列中的Message对handler也持有引用,这样就造成一些资源不能回,从而可能造成内存泄露。 15 | 16 | 解决这个警告的办法即让handler不持有外部类的引用,怎么做到这一点呢,即将Handler设置为静态内部类就行了,将外部类(Activity等)传递给Handler,在Handler中建立弱引用(WeakReference)。 17 | 18 | 为了能够使以后更好的使用Handler-Message机制,我这里对其进行了封装,使用方法见下。先看一下代码。 19 | 20 | ### CBHandler.java 21 | package me.codeboy.android.common.component; 22 | 23 | import android.os.Handler; 24 | import android.os.Message; 25 | 26 | import java.lang.ref.WeakReference; 27 | 28 | import me.codeboy.android.common.app.CBActivity; 29 | 30 | /** 31 | * Created by yuedong.lyd on 6/7/15. 32 | *

    ; 33 | * 构建防止内存泄露的handler 34 | *

    35 | */ 36 | public class CBHandler { 37 | /** 38 | * 防止handler对activity有隐式引用,匿名内部类不会对外部类有引用 39 | */ 40 | public static class UnleakHandler extends Handler { 41 | private final WeakReference activity; 42 | 43 | public UnleakHandler(CBActivity activity) { 44 | this.activity = new WeakReference<CBActivity>(activity); 45 | } 46 | 47 | @Override 48 | public void handleMessage(Message msg) { 49 | super.handleMessage(msg); 50 | if(activity.get() == null) { 51 | return; 52 | } 53 | activity.get().processMessage(msg); 54 | } 55 | } 56 | } 57 | 58 | 59 | ### CBActivity 60 | 61 | package me.codeboy.android.common.app; 62 | 63 | import android.app.Activity; 64 | import android.os.Bundle; 65 | import android.os.Message; 66 | 67 | import me.codeboy.android.common.component.CBHandler; 68 | 69 | /** 70 | * Created by yuedong.lyd on 6/8/15. 71 | */ 72 | public abstract class CBActivity extends Activity{ 73 | public CBHandler.UnleakHandler handler ; 74 | 75 | @Override 76 | protected void onCreate(Bundle savedInstanceState) { 77 | super.onCreate(savedInstanceState); 78 | handler = new CBHandler.UnleakHandler(this); 79 | } 80 | 81 | /** 82 | * 处理消息 83 | * @param msg 84 | */ 85 | public abstract void processMessage(Message msg); 86 | } 87 | 88 | 在使用中,我们只需自己的Activity继承CBActivity即可,在onCreate时自动创建UnleakHandler的实例handler,从CBHandler的代码中我们也可以看出来,UnleakHandler自动将收到的消息交给CBActivity中的processMessage进行处理。我们只需要在发送消息的时候使用handler变量发送即可,处理在processHandler中处理即可。 89 | 90 | > 如有任何知识产权、版权问题或理论错误,还请指正。 91 | > 92 | > 转载请注明原作者及以上信息。 93 | -------------------------------------------------------------------------------- /_layouts/post.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 | 5 | 6 |
    7 |
    8 |
    9 |
    10 |
    11 |
    12 | {% for tag in page.tags %} 13 | {{ tag }} 14 | {% endfor %} 15 |
    16 |

    {{ page.title }}

    17 | {% comment %} 18 | always create a h2 for keeping the margin 19 | {% endcomment %} 20 | {% comment %} if page.subtitle {% endcomment %} 21 |

    {{ page.subtitle }}

    22 | {% comment %} endif {% endcomment %} 23 | Posted by {% if page.author %}{{ page.author }}{% else %}{{ site.title }}{% endif %} on {{ page.date | date: "%B %-d, %Y" }} 24 |
    25 |
    26 |
    27 |
    28 |
    29 | 30 | 31 |
    32 |
    33 |
    34 |
    35 | 36 | {{ content }} 37 | 38 |
    39 |
    40 | 41 | 42 | 50 | 51 |
    52 |
    53 |
    54 | -------------------------------------------------------------------------------- /js/codeboy.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Clean Blog v1.0.0 (http://startbootstrap.com) 3 | * Copyright 2015 Start Bootstrap 4 | * Licensed under Apache 2.0 (https://github.com/IronSummitMedia/startbootstrap/blob/gh-pages/LICENSE) 5 | */ 6 | 7 | // Tooltip Init 8 | $(function() { 9 | $("[data-toggle='tooltip']").tooltip(); 10 | }); 11 | 12 | // make all images responsive 13 | /* 14 | * actually only Portfolio-Pages can't use it and only post-img need it. 15 | * so I modify the _layout/post and CSS to make post-img responsive! 16 | */ 17 | // $(function() { 18 | // $("img").addClass("img-responsive"); 19 | // }); 20 | 21 | // responsive tables 22 | $(document).ready(function() { 23 | $("table").wrap("
    "); 24 | $("table").addClass("table"); 25 | }); 26 | 27 | // responsive embed videos 28 | $(document).ready(function () { 29 | $('iframe[src*="youku.com"]').wrap('
    '); 30 | $('iframe[src*="youku.com"]').addClass('embed-responsive-item'); 31 | $('iframe[src*="vimeo.com"]').wrap('
    '); 32 | $('iframe[src*="vimeo.com"]').addClass('embed-responsive-item'); 33 | }); 34 | 35 | // Navigation Scripts to Show Header on Scroll-Up 36 | jQuery(document).ready(function($) { 37 | var MQL = 1170; 38 | 39 | //primary navigation slide-in effect 40 | if ($(window).width() > MQL) { 41 | var headerHeight = $('.navbar-custom').height(); 42 | $(window).on('scroll', { 43 | previousTop: 0 44 | }, 45 | function() { 46 | var currentTop = $(window).scrollTop(); 47 | //check if user is scrolling up 48 | if (currentTop < this.previousTop) { 49 | //if scrolling up... 50 | if (currentTop > 0 && $('.navbar-custom').hasClass('is-fixed')) { 51 | $('.navbar-custom').addClass('is-visible'); 52 | } else { 53 | $('.navbar-custom').removeClass('is-visible is-fixed'); 54 | } 55 | } else { 56 | //if scrolling down... 57 | $('.navbar-custom').removeClass('is-visible'); 58 | if (currentTop > headerHeight && !$('.navbar-custom').hasClass('is-fixed')) $('.navbar-custom').addClass('is-fixed'); 59 | } 60 | this.previousTop = currentTop; 61 | }); 62 | } 63 | 64 | hljs.initHighlightingOnLoad(); 65 | $("pre code").each(function () { 66 | if ($(this).attr('class') !== "language-nohighlight") { 67 | let content = $(this).html(); 68 | //单行不进行操作 69 | if (content.split('\n').length <= 4) { 70 | return; 71 | } 72 | let content2 = content.replace(/\n/g, "\n
  • "); 73 | content2 = content2.substring(0, content2.length - 4); 74 | $(this).html(""); 75 | } 76 | }) 77 | }); 78 | -------------------------------------------------------------------------------- /search/js/cb-search.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function () { 2 | var time1 = 0; 3 | var show = false; 4 | var names = new Array(); //文章名字等 5 | var urls = new Array(); //文章地址 6 | $(document).keyup(function (e) { 7 | var time2 = new Date().getTime(); 8 | if (e.keyCode == 17) { 9 | var gap = time2 - time1; 10 | time1 = time2; 11 | if (gap < 500) { 12 | if (show) { 13 | $(".cb-search-tool").css("display", "none"); 14 | show = false; 15 | } else { 16 | $(".cb-search-tool").css("display", "block"); 17 | show = true; 18 | $("#cb-search-content").val(""); 19 | $("#cb-search-content").focus(); 20 | } 21 | time1 = 0; 22 | } 23 | }else if(e.keyCode == 27){ 24 | $(".cb-search-tool").css("display", "none"); 25 | show = false; 26 | time1 = 0; 27 | } 28 | }); 29 | 30 | $("#cb-search-content").keyup(function (e) { 31 | var time2 = new Date().getTime(); 32 | if (e.keyCode == 17) { 33 | var gap = time2 - time1; 34 | time1 = time2; 35 | if (gap < 500) { 36 | if (show) { 37 | $(".cb-search-tool").css("display", "none"); 38 | show = false; 39 | } else { 40 | $(".cb-search-tool").css("display", "block"); 41 | show = true; 42 | $("#cb-search-content").val(""); 43 | $("#cb-search-content").focus(); 44 | } 45 | time1 = 0; 46 | } 47 | } 48 | }); 49 | 50 | $("#cb-close-btn").click(function () { 51 | $(".cb-search-tool").css("display", "none"); 52 | show = false; 53 | time1 = 0; 54 | }); 55 | 56 | $("#cb-search-btn").click(function(){ 57 | $(".cb-search-tool").css("display", "block"); 58 | show = true; 59 | $("#cb-search-content").val(""); 60 | $("#cb-search-content").focus(); 61 | time1 = 0; 62 | }); 63 | 64 | $.getJSON("/search/cb-search.json").done(function (data) { 65 | if (data.code == 0) { 66 | for (var index in data.data) { 67 | var item = data.data[index]; 68 | names.push(item.title); 69 | urls.push(item.url); 70 | } 71 | 72 | $("#cb-search-content").typeahead({ 73 | source: names, 74 | 75 | afterSelect: function (item) { 76 | $(".cb-search-tool").css("display", "none"); 77 | show = false; 78 | window.location.href = (urls[names.indexOf(item)]); 79 | return item; 80 | } 81 | }); 82 | } 83 | }); 84 | 85 | }); 86 | -------------------------------------------------------------------------------- /_posts/2015-07-17-android-webview-optimize.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: 'Android WebView页面加载优化' 4 | date: '2015-07-17' 5 | header-img: "img/post-bg-android.jpg" 6 | tags: 7 | - android 8 | - network 9 | author: 'Codeboy' 10 | --- 11 | 12 | 目前webapp越来越多,体验也越来越好,为了能够更好的使用WebView展示出流畅的的页面,可以从以下几点做优化: 13 | 14 | - **WebView缓存** 15 | - **资源文件本地存储** 16 | - **减少耗时操作** 17 | - **客户端UI优化** 18 | 19 | 可能有人会说了,为什么不做成native的呢,这样就不用那么的麻烦了。如果我需要加载的内容都是静态的,当然做成native的是最好的,为什么我们要使用WebView呢,因为它可以加载一些容易改变的内容,同时也方便制作多平台应用。 20 | 21 | WebView可以优化的哪些地方呢? 22 | 23 | ### WebView缓存 24 | 25 | 开启WebView的缓存功能可以减少对服务器资源的请求,一般使用默认缓存策略就可以了。 26 | 27 | //设置 缓存模式 28 | webView.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT); 29 | // 开启 DOM storage API 功能 30 | webView.getSettings().setDomStorageEnabled(true); 31 | 32 | ### 资源文件本地存储 33 | 34 | 资源等文件(不需要更新)本地存储,在需要的时候直接从本地获取。哪些资源需要我们去存储在本地呢,当然是一些不会被更新的资源,例如图片文件,js文件,css文件,替换的方法也很简单,重写WebView的方法即可。 35 | 36 | { 37 | try { 38 | if (url.endsWith("icon.png")) { 39 | InputStream is = appRm.getInputStream(R.drawable.icon); 40 | WebResourceResponse response = new WebResourceResponse("image/png", 41 | "utf-8", is); 42 | return response; 43 | } else if (url.endsWith("jquery.min.js")) { 44 | InputStream is = appRm.getInputStream(R.raw.jquery_min_js); 45 | WebResourceResponse response = new WebResourceResponse("text/javascript", 46 | "utf-8", is); 47 | return response; 48 | } 49 | } catch (IOException e) { 50 | e.printStackTrace(); 51 | } 52 | return super.shouldInterceptRequest(view, url); 53 | } 54 | 55 | 56 | > 1. appRm为app资源管理器,读取drawable,assets,raw下的资源,都是android系统的一些很简单的函数调用。 57 | > 58 | > 2. getInputStream的参数代表资源具体位置 59 | > 60 | > 3. WebResourceResponse后的资源类型需要写正确 61 | 62 | 有些时候我们会为我们的网站加入一些统计代码,这些也可以精简掉(自己使用的CNZZ的大概占的有10k左右),可以使用Charles对客户端进行抓包查看。 63 | 64 | ### 减少耗时操作 65 | 66 | 准确的说,是减少同步操作的操作时间,尽量使用异步操作替代同步操作。如果服务端存在读取数据库和计算耗时的操作,尽量使用异步(ajax)进行操作,把原本的时间花在异步操作上。 67 | 68 | 举个例子,A页面到B页面,A页面实现登录功能,B页面展示主功能页面,如果让B页面去进行用户登录信息验证的话,B页面加载时间会加长(数据库查询等操作),同时客户端可能需要提供一个等待框(或进度条等)给用户,那看看在A页面使用异步操作的优势吧: 69 | 70 | - 可以提供统一的js等待框,多平台保持一致性,减少客户端代码工作量。 71 | - 加载页面的时间变短。B页面由于减少了耗时的操作,加载时间变短,用户等待时间也变短。 72 | - 可以方便加入一些验证后的控制逻辑,不需要进行页面跳转。A页面可以根据异步操作进行结果判断,做出相应的处理。 73 | 74 | 75 | ### 客户端UI优化 76 | 77 | 怎么让用户看不到WebView加载前的白色页面呢?首次加载后页面的跳转可以用上面的步骤进行优化,可以提供给用户一个很好的体验,那加载的第一页呢?我们需要WebView预加载页面,这个该怎么做到的呢?下面提供两种方法: 78 | 79 | - ViewPager,将欢迎页面与WebView页面一起放进ViewPager中,设置预加载页面个数,使WebView所在页面可以预加载,在加载完毕的时候切换到WebView所在页面。 80 | - FrameLayout,将欢迎页面与WebView页面的布局合在一起,显示在一个页面内,起始隐藏WebView布局,待WebView加载完毕,隐藏欢迎布局,显示WebView布局。 81 | 82 | 使用FrameLayout简单一些,两种方法都是需要对WebChromeClient的onProgressChanged进行监听,加载完毕进行页面切换,如下: 83 | 84 | webView.setWebChromeClient(new WebChromeClient() { 85 | @Override 86 | public void onProgressChanged(WebView view, int newProgress) { 87 | super.onProgressChanged(view, newProgress); 88 | if (newProgress >= 100) { 89 | // 切换页面 90 | } 91 | } 92 | }); 93 | 94 | 95 | 经过以上几步的优化,一个流畅的webapp生成了。 96 | 97 | 98 | > 如有任何知识产权、版权问题或理论错误,还请指正。 99 | > 100 | > 转载请注明原作者及以上信息。 101 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | CodeboyBlog 2 | --- 3 | 4 | **[codeboy.me](https://www.codeboy.me)的网站模板** 5 | 6 | 其中搜索模块可以单独安装,地址如下 7 | 8 | - jekyll-search [https://github.com/androiddevelop/jekyll-search](https://github.com/androiddevelop/jekyll-search) 9 | - hexo-search [https://github.com/androiddevelop/hexo-search](https://github.com/androiddevelop/hexo-search) 10 | 11 | ![网站截图](codeboy.me.png) 12 | 13 | 本工程实时预览地址 [blogtest.codeboy.me](http://blogtest.codeboy.me) 14 | 15 | 博客可以简单的搭配微信小程序查看, 具体查看 [https://github.com/androiddevelop/WechatBlog](https://github.com/androiddevelop/WechatBlog) 16 | 17 | ## 安装方式: 18 | 19 | 1. 安装jeykll 20 | 21 | ``` 22 | gem install jekyll 23 | gem install jekyll-paginate 24 | ``` 25 | 2. 将CodeboyBlog复制到服务器(部署到github.io的方式自行搜索)。 26 | 3. 运行命令生成网站即可(经常改变配置的话不建议增量更新)。 27 | 28 | ``` 29 | jekyll serve --watch & 30 | jekyll serve --watch --incremental & ##增量更新 31 | ``` 32 | 为了能够更好的生成网站,我们可以写一个脚本: 33 | 34 | ``` 35 | #!/bin/bash 36 | ps aux |grep jekyll |awk '{print $2}' | xargs kill -9 37 | cd /path/to/blog 38 | jekyll serve --watch & 39 | ``` 40 | 41 | > ps开头的命令是关闭所有jekyll的进程 42 | > 43 | > cd到网站的根目录 44 | > 45 | > 启动jekyll服务 46 | 47 | ## 需要配置的内容: 48 | 49 | 1. 修改_config.yml中的信息(知乎等帐号,特别需要注意的是畅言配置(changyan_appid和changyan_appid)必须更换,否则您将不能查看到博客的评论)。 畅言的申请地址 [http://changyan.kuaizhan.com/](http://changyan.kuaizhan.com/) 50 | 2. 修改about/index.html中个人信息(如果不需要个人简介,可以在步骤3中去除对应标签)。 51 | 3. 修改_include/nav.html,选择自己需要的导航标签(主页, 应用, 标签, 关于等) 52 | 4. 如果博客底部的github,知乎等需要修改,请编辑_includes/footer.html中分享的信息。 53 | 5. 去除CNAME文件,或者CNAME文件中的域名更换为您的博客域名。 54 | 55 | ## 更新内容: 56 | 57 | #### 2022-04-09 58 | 59 | - 关闭chrome自动联想功能。 60 | - 完善代码部分展示。 61 | - 去除畅言评论组件。 62 | 63 | #### 2018-05-03 64 | 65 | - 评论组件调整为畅言。 66 | 67 | #### 2017-12-19 68 | 69 | - 代码显示行号。(/css/syntax.css) 70 | 71 | #### 2017-11-17 72 | 73 | - 添加初版微信小程序支持,可以便捷创建专属于自己博客的小程序。 74 | 75 | #### 2017-04-05 76 | 77 | - 调整_config部分配置。 78 | - 由于多说即将关闭,评论组件调整为网易云跟贴。 79 | 80 | #### 2017-02-19 81 | 82 | - 修正文章双滚动条 83 | 84 | #### 2016-11-22 85 | 86 | - 升级jekyll-search(v1.0.1), 兼容firefox。 (/search/js/cb-search.js) 87 | - 修正移动端宽度展示。(/_layouts/page.html) 88 | 89 | #### 2016-06-12 90 | 91 | - 修正jekyll版本升级至3.1.0+后tags页面的显示问题。 92 | - 将jquery、bootstrap等引用改为cdn,减少站内流量消耗。 93 | 94 | #### 2015-12-20 95 | 96 | - 多说id移动至_config.xml文件中,集中配置。 97 | 98 | #### 2015-12-09 99 | 100 | - 更新_config.yml配置,适配jekyll 3.0+版本。 101 | - 更新博客中相关链接,便于博客转向https站点。 102 | - 去除anchor,标题前面不再显示 `#` 号。 103 | 104 | #### 2015-10-10 105 | 106 | - 在Clean Blog的基础上修改,同时加入黄玄在CleanBlog上添加的云标签。 107 | - 加入文章搜索功能,pc上可以双击ctrl触发。 108 | - 优化界面,更好的适配手机。 109 | 110 | 111 | ## License 112 | 113 | ``` 114 | Copyright 2016 Yuedong.li 115 | 116 | Licensed under the Apache License, Version 2.0 (the "License"); 117 | you may not use this file except in compliance with the License. 118 | You may obtain a copy of the License at 119 | 120 | http://www.apache.org/licenses/LICENSE-2.0 121 | 122 | Unless required by applicable law or agreed to in writing, software 123 | distributed under the License is distributed on an "AS IS" BASIS, 124 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 125 | See the License for the specific language governing permissions and 126 | limitations under the License. 127 | ``` 128 | 129 | > 有任何问题,欢迎发送邮件到app@codeboy.me交流. 130 | -------------------------------------------------------------------------------- /about/fonts/timelineicons/ecoico.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | This is a custom SVG font generated by IcoMoon. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 14 | 17 | 20 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /about/index.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title: "About" 4 | description: "简单 执着 勤奋 疯狂" 5 | header-img: "img/about-bg.jpg" 6 | --- 7 | 8 | 9 | 10 | 21 |
    22 |
    23 |
      24 |
    • 25 | 26 |
      27 |
      28 |

      个人介绍

      29 |
        30 |
      • 李跃东(玄恒)
      • 31 |
      • 喜欢Android, Web, Server等一些技术
      • 32 |
      • 可以通过app@codeboy.me联系我哦
      • 33 |
      34 |
      35 |
    • 36 |
    • 37 | 38 |
      39 |
      40 |

      天猫实习生

      41 | 42 |
        43 |
      • 客户端开发工程师
      • 44 |
      • 参与几个模块的开发
      • 45 |
      46 |
      47 |
    • 48 | 49 |
    • 50 | 51 |
      52 |
      53 |

      科大小秘书

      54 | 科大小秘书是一款为科大研究生设计的安卓软件。小秘书可以帮您跳过验证码的输入,方便实用。小秘书的功能有:查询成绩,查看个人课表,查询所有研究生选修课的时间地点老师,查询助研资金,查询epc预约课程信息等. 55 |
      56 |
    • 57 | 58 | 59 |
    • 60 | 61 |
      62 |
      63 |

      中国科学技术大学

      64 |
        65 |
      • 计算机学院
      • 66 |
      • 安徽省合肥市金寨路96号
      • 67 |
      68 |
      69 |
    • 70 | 71 | 72 |
    • 73 | 74 |
      75 |
      76 |

      郑大小秘书

      77 | 郑大小秘书是一款专门为郑大学子设计的安卓软件。您通过它可以查询个人教务信息,新闻招聘信息,图书馆馆藏书目;可以方便的登陆ZzuWlan,可以和同学相互发送私信,对自己感兴趣的内容加以收藏等。 78 |
      79 |
    • 80 | 81 | 82 |
    • 83 | 84 |
      85 |
      86 |

      短信邮箱

      87 | 短信邮箱是一款便捷的短信同步软件,它会将您发送和收到的短信发送至您的邮箱,您可以设置过滤器(号码或关键字)来取消同步含有这些特性的短信。 88 |
      89 |
    • 90 | 91 | 92 |
    • 93 | 94 |
      95 |
      96 |

      郑州大学

      97 |
        98 |
      • 信息工程学院
      • 99 |
      • 河南省郑州市高新技术开发区科学大道100号
      • 100 |
      101 |
      102 |
    • 103 | 104 |
    • 105 | 106 |
      107 |
      108 |

      爱心捐助

      109 | 110 |
      111 |
    • 112 |
    113 |
    114 |
    115 | -------------------------------------------------------------------------------- /about/fonts/timelineicons/ecoico.dev.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | This is a custom SVG font generated by IcoMoon. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 14 | 17 | 20 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /css/syntax.css: -------------------------------------------------------------------------------- 1 | /* to make lines scroll instead of wrap */ 2 | /* from http://stackoverflow.com/a/23393920 */ 3 | 4 | .highlight pre code * { 5 | white-space: nowrap; // this sets all children inside to nowrap 6 | } 7 | 8 | .highlight pre { 9 | overflow-x: auto; // this sets the scrolling in x 10 | } 11 | 12 | .highlight pre code { 13 | white-space: pre; // forces to respect
     formatting
     14 | }
     15 | 
     16 | 
     17 | /*
     18 |  * GitHub style for Pygments syntax highlighter, for use with Jekyll
     19 |  * Courtesy of GitHub.com
     20 |  */
     21 | 
     22 | .highlight pre, pre, .highlight .hll { background-color: #f8f8f8; border: 1px solid #ccc; padding: 6px 10px; border-radius: 3px; }
     23 | .highlight .c { color: #999988; font-style: italic; }
     24 | .highlight .err { color: #a61717; background-color: #e3d2d2; }
     25 | .highlight .k { font-weight: bold; }
     26 | .highlight .o { font-weight: bold; }
     27 | .highlight .cm { color: #999988; font-style: italic; }
     28 | .highlight .cp { color: #999999; font-weight: bold; }
     29 | .highlight .c1 { color: #999988; font-style: italic; }
     30 | .highlight .cs { color: #999999; font-weight: bold; font-style: italic; }
     31 | .highlight .gd { color: #000000; background-color: #ffdddd; }
     32 | .highlight .gd .x { color: #000000; background-color: #ffaaaa; }
     33 | .highlight .ge { font-style: italic; }
     34 | .highlight .gr { color: #aa0000; }
     35 | .highlight .gh { color: #999999; }
     36 | .highlight .gi { color: #000000; background-color: #ddffdd; }
     37 | .highlight .gi .x { color: #000000; background-color: #aaffaa; }
     38 | .highlight .go { color: #888888; }
     39 | .highlight .gp { color: #555555; }
     40 | .highlight .gs { font-weight: bold; }
     41 | .highlight .gu { color: #800080; font-weight: bold; }
     42 | .highlight .gt { color: #aa0000; }
     43 | .highlight .kc { font-weight: bold; }
     44 | .highlight .kd { font-weight: bold; }
     45 | .highlight .kn { font-weight: bold; }
     46 | .highlight .kp { font-weight: bold; }
     47 | .highlight .kr { font-weight: bold; }
     48 | .highlight .kt { color: #445588; font-weight: bold; }
     49 | .highlight .m { color: #009999; }
     50 | .highlight .s { color: #dd1144; }
     51 | .highlight .n { color: #333333; }
     52 | .highlight .na { color: teal; }
     53 | .highlight .nb { color: #0086b3; }
     54 | .highlight .nc { color: #445588; font-weight: bold; }
     55 | .highlight .no { color: teal; }
     56 | .highlight .ni { color: purple; }
     57 | .highlight .ne { color: #990000; font-weight: bold; }
     58 | .highlight .nf { color: #990000; font-weight: bold; }
     59 | .highlight .nn { color: #555555; }
     60 | .highlight .nt { color: navy; }
     61 | .highlight .nv { color: teal; }
     62 | .highlight .ow { font-weight: bold; }
     63 | .highlight .w { color: #bbbbbb; }
     64 | .highlight .mf { color: #009999; }
     65 | .highlight .mh { color: #009999; }
     66 | .highlight .mi { color: #009999; }
     67 | .highlight .mo { color: #009999; }
     68 | .highlight .sb { color: #dd1144; }
     69 | .highlight .sc { color: #dd1144; }
     70 | .highlight .sd { color: #dd1144; }
     71 | .highlight .s2 { color: #dd1144; }
     72 | .highlight .se { color: #dd1144; }
     73 | .highlight .sh { color: #dd1144; }
     74 | .highlight .si { color: #dd1144; }
     75 | .highlight .sx { color: #dd1144; }
     76 | .highlight .sr { color: #009926; }
     77 | .highlight .s1 { color: #dd1144; }
     78 | .highlight .ss { color: #990073; }
     79 | .highlight .bp { color: #999999; }
     80 | .highlight .vc { color: teal; }
     81 | .highlight .vg { color: teal; }
     82 | .highlight .vi { color: teal; }
     83 | .highlight .il { color: #009999; }
     84 | .highlight .gc { color: #999; background-color: #EAF2F5; }
     85 | 
     86 | .hljs {
     87 | 	border: 0;
     88 | 	font-family: "Consulas", "Courier New", Courier, mono, serif;
     89 | 	font-size: 14px;
     90 | 	/*background: #f8f8f8 !important;*/
     91 | 	display: block;
     92 | 	padding: 1px;
     93 | 	margin: 0;
     94 | 	width: 100%;
     95 | 	font-weight: 200;
     96 | 	color: #333;
     97 | 	white-space: pre-wrap
     98 | }
     99 | .hljs ul {
    100 | 	list-style: decimal;
    101 | 	/*background-color: #f8f8f8;*/
    102 | 	margin: 0px 0px 0 36px !important;
    103 | 	padding: 0px;
    104 |   right: -14px;
    105 | }
    106 | .hljs ul li {
    107 | 	list-style: decimal-leading-zero;
    108 | 	border-left: 1px solid #ccc !important;
    109 | 	/*background: #fff;*/
    110 |   padding: 1px 5px 1px 10px !important;
    111 | 	margin: 0 !important;
    112 | 	/*line-height: 14px;*/
    113 | 	word-break: break-all;
    114 | 	word-wrap: break-word;
    115 | }
    116 | .hljs ul li:nth-of-type(even) {
    117 | 	/*background-color: #f8f8f8;*/
    118 | 	/*color: inherit;*/
    119 | }
    120 | 
    
    
    --------------------------------------------------------------------------------
    /open.html:
    --------------------------------------------------------------------------------
      1 | ---
      2 | layout: page
      3 | title: "Open"
      4 | description: "自由 包容 发展 共赢" 
      5 | header-img: "img/open-bg.jpg"
      6 | ---
      7 | 
      8 | 
     38 | 
     39 | 
     40 | 
    41 |
    42 | 45 | 46 |
    47 | 48 |

    AlignTextView

    49 | 两端对齐的TextView控件。 50 |
    51 | 52 |
    53 |
    54 |
    55 |
    56 | 57 | 60 | 61 |
    62 | 63 |

    CycleViewPager

    64 | 支持循环滚动,自动切换播放的viewpager控件。
    67 | 68 |
    69 |
    70 | 71 |
    72 | 73 |
    74 | 77 | 78 |
    79 | 80 |

    FilterFlowLayout

    81 | 含有过滤功能的流式布局。 82 |
    83 | 84 |
    85 |
    86 |
    87 | 88 |
    89 | 90 | 91 | 94 | 95 |
    96 | 97 |

    AndroidScreenshot

    98 | 在PC上展示手机屏幕,提供点击滑动等操作。 99 |
    100 |
    101 |
    102 |
    103 | 104 | 116 | 117 |
    118 |
    119 | 120 | 121 | 126 | 127 | 128 | 133 | 134 | 135 | 136 | 139 | 140 | 141 | -------------------------------------------------------------------------------- /_includes/footer.html: -------------------------------------------------------------------------------- 1 | 2 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 64 | 65 | 66 | 76 | 77 | 78 | 79 | 80 | 81 | 89 | 90 |
    91 | 92 |
    93 | 94 | 95 | 96 | 97 | 98 | 99 |
    100 | 101 |
    102 | -------------------------------------------------------------------------------- /about/css/default.css: -------------------------------------------------------------------------------- 1 | /* General Blueprint Style */ 2 | @import url(https://fonts.googleapis.com/css?family=Lato:300,400,700); 3 | @font-face { 4 | font-family: 'bpicons'; 5 | src:url('../fonts/bpicons/bpicons.eot'); 6 | src:url('../fonts/bpicons/bpicons.eot?#iefix') format('embedded-opentype'), 7 | url('../fonts/bpicons/bpicons.woff') format('woff'), 8 | url('../fonts/bpicons/bpicons.ttf') format('truetype'), 9 | url('../fonts/bpicons/bpicons.svg#bpicons') format('svg'); 10 | font-weight: normal; 11 | font-style: normal; 12 | } /* Made with http://icomoon.io/ */ 13 | 14 | *, *:after, *:before { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } 15 | body, html { font-size: 100%; padding: 0; margin: 0;} 16 | 17 | /* Clearfix hack by Nicolas Gallagher: http://nicolasgallagher.com/micro-clearfix-hack/ */ 18 | .clearfix:before, .clearfix:after { content: " "; display: table; } 19 | .clearfix:after { clear: both; } 20 | 21 | body { 22 | font-family: 'Lato', Calibri, Arial, sans-serif; 23 | color: #47a3da; 24 | } 25 | 26 | a { 27 | text-decoration: none; 28 | } 29 | 30 | .main, 31 | .about-container > header { 32 | width: 100%; 33 | max-width: 69em; 34 | margin: 0 auto; 35 | padding: 0 1.875em 3.125em 1.875em; 36 | } 37 | 38 | .about-container > header { 39 | padding: 2.875em 1.875em 1.875em; 40 | } 41 | 42 | .about-container > header h1 { 43 | font-size: 2.125em; 44 | line-height: 1.3; 45 | margin: 0 0 0.6em 0; 46 | float: left; 47 | font-weight: 400; 48 | } 49 | 50 | .about-container > header > span { 51 | display: block; 52 | position: relative; 53 | z-index: 9999; 54 | font-weight: 700; 55 | text-transform: uppercase; 56 | letter-spacing: 0.5em; 57 | padding: 0 0 0.6em 0.1em; 58 | } 59 | 60 | .about-container > header > span span:after { 61 | width: 30px; 62 | height: 30px; 63 | left: -12px; 64 | font-size: 50%; 65 | top: -8px; 66 | font-size: 75%; 67 | position: relative; 68 | } 69 | 70 | .about-container > header > span span:hover:before { 71 | content: attr(data-content); 72 | text-transform: none; 73 | text-indent: 0; 74 | letter-spacing: 0; 75 | font-weight: 300; 76 | font-size: 110%; 77 | padding: 0.8em 1em; 78 | line-height: 1.2; 79 | text-align: left; 80 | left: auto; 81 | margin-left: 4px; 82 | position: absolute; 83 | color: #fff; 84 | background: #47a3da; 85 | } 86 | 87 | .about-container > header nav { 88 | float: right; 89 | text-align: center; 90 | } 91 | 92 | .about-container > header nav a { 93 | display: inline-block; 94 | position: relative; 95 | text-align: left; 96 | width: 2.5em; 97 | height: 2.5em; 98 | background: #fff; 99 | border-radius: 50%; 100 | margin: 0 0.1em; 101 | border: 4px solid #47a3da; 102 | } 103 | 104 | .about-container > header nav a > span { 105 | display: none; 106 | } 107 | 108 | .about-container > header nav a:hover:before { 109 | content: attr(data-info); 110 | color: #47a3da; 111 | position: absolute; 112 | width: 600%; 113 | top: 120%; 114 | text-align: right; 115 | right: 0; 116 | pointer-events: none; 117 | } 118 | 119 | .about-container > header nav a:hover { 120 | background: #47a3da; 121 | } 122 | 123 | .bp-icon:after { 124 | font-family: 'bpicons'; 125 | speak: none; 126 | font-style: normal; 127 | font-weight: normal; 128 | font-variant: normal; 129 | text-transform: none; 130 | text-align: center; 131 | color: #47a3da; 132 | -webkit-font-smoothing: antialiased; 133 | } 134 | 135 | .about-container > header nav .bp-icon:after { 136 | position: absolute; 137 | top: 0; 138 | left: 0; 139 | width: 100%; 140 | height: 100%; 141 | line-height: 2; 142 | text-indent: 0; 143 | } 144 | 145 | .about-container > header nav a:hover:after { 146 | color: #fff; 147 | } 148 | 149 | .bp-icon-next:after { 150 | content: "\e000"; 151 | } 152 | .bp-icon-drop:after { 153 | content: "\e001"; 154 | } 155 | .bp-icon-archive:after { 156 | content: "\e002"; 157 | } 158 | .bp-icon-about:after { 159 | content: "\e003"; 160 | } 161 | .bp-icon-prev:after { 162 | content: "\e004"; 163 | } 164 | 165 | @media screen and (max-width: 55em) { 166 | 167 | .about-container > header h1, 168 | .about-container > header nav { 169 | float: none; 170 | } 171 | 172 | .about-container > header > span, 173 | .about-container > header h1 { 174 | text-align: center; 175 | } 176 | 177 | .about-container > header nav { 178 | margin: 0 auto; 179 | } 180 | 181 | .about-container > header > span { 182 | text-indent: 30px; 183 | } 184 | } 185 | -------------------------------------------------------------------------------- /about/css/component.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'ecoico'; 3 | src:url('../fonts/timelineicons/ecoico.eot'); 4 | src:url('../fonts/timelineicons/ecoico.eot?#iefix') format('embedded-opentype'), 5 | url('../fonts/timelineicons/ecoico.woff') format('woff'), 6 | url('../fonts/timelineicons/ecoico.ttf') format('truetype'), 7 | url('../fonts/timelineicons/ecoico.svg#ecoico') format('svg'); 8 | font-weight: normal; 9 | font-style: normal; 10 | } /* Made with http://icomoon.io/ */ 11 | 12 | .cbp_tmtimeline { 13 | margin: 30px 0 0 0; 14 | padding: 0; 15 | list-style: none; 16 | position: relative; 17 | } 18 | 19 | /* The line */ 20 | .cbp_tmtimeline:before { 21 | content: ''; 22 | position: absolute; 23 | top: 0; 24 | bottom: 0; 25 | width: 10px; 26 | background: #afdcf8; 27 | left: 20%; 28 | margin-left: -10px; 29 | } 30 | 31 | .cbp_tmtimeline > li { 32 | position: relative; 33 | } 34 | 35 | /* The date/time */ 36 | .cbp_tmtimeline > li .cbp_tmtime { 37 | display: block; 38 | width: 26.5%; 39 | padding-right: 110px; 40 | position: absolute; 41 | top: -10px; 42 | } 43 | 44 | .cbp_tmtimeline > li .cbp_tmtime span { 45 | display: block; 46 | text-align: right; 47 | } 48 | 49 | .cbp_tmtimeline > li .cbp_tmtime span:first-child { 50 | font-size: 1.2em; 51 | color: #bdd0db; 52 | } 53 | 54 | .cbp_tmtimeline > li .cbp_tmtime span:last-child { 55 | font-size: 2.2em; 56 | color: #3594cb; 57 | } 58 | 59 | cbp_tmtimeline > li:nth-child(odd) .cbp_tmtime span:last-child { 60 | /*color: #6cbfee;*/ 61 | } 62 | 63 | /* Right content */ 64 | .cbp_tmtimeline > li .cbp_tmlabel { 65 | margin: 0 0 15px 25%; 66 | background: #3594cb; 67 | color: #fff; 68 | padding: 2em; 69 | font-size: 1.2em; 70 | font-weight: 300; 71 | line-height: 1.4; 72 | position: relative; 73 | border-radius: 5px; 74 | } 75 | 76 | .cbp_tmtimeline > li:nth-child(odd) .cbp_tmlabel { 77 | /*background: #6cbfee; */ 78 | } 79 | 80 | .cbp_tmtimeline > li .cbp_tmlabel h2 { 81 | margin-top: 0px; 82 | padding: 0 0 10px 0; 83 | border-bottom: 1px solid rgba(255,255,255,0.4); 84 | } 85 | 86 | /* The triangle */ 87 | .cbp_tmtimeline > li .cbp_tmlabel:after { 88 | right: 100%; 89 | border: solid transparent; 90 | content: " "; 91 | height: 0; 92 | width: 0; 93 | position: absolute; 94 | pointer-events: none; 95 | border-right-color: #3594cb; 96 | border-width: 10px; 97 | top: 10px; 98 | } 99 | 100 | .cbp_tmtimeline > li:nth-child(odd) .cbp_tmlabel:after { 101 | /* border-right-color: #6cbfee; */ 102 | } 103 | 104 | /* The icons */ 105 | .cbp_tmtimeline > li .cbp_tmicon { 106 | width: 40px; 107 | height: 40px; 108 | font-family: 'ecoico'; 109 | speak: none; 110 | font-style: normal; 111 | font-weight: normal; 112 | font-variant: normal; 113 | text-transform: none; 114 | font-size: 1.4em; 115 | line-height: 40px; 116 | -webkit-font-smoothing: antialiased; 117 | position: absolute; 118 | color: #fff; 119 | background: #46a4da; 120 | border-radius: 50%; 121 | box-shadow: 0 0 0 8px #afdcf8; 122 | text-align: center; 123 | left: 20%; 124 | top: 0; 125 | margin: 0 0 0 -25px; 126 | } 127 | 128 | .cbp_tmicon-phone:before { 129 | content: "\e000"; 130 | } 131 | 132 | .cbp_tmicon-screen:before { 133 | content: "\e001"; 134 | } 135 | 136 | .cbp_tmicon-mail:before { 137 | content: "\e002"; 138 | } 139 | 140 | .cbp_tmicon-earth:before { 141 | content: "\e003"; 142 | } 143 | 144 | /* Example Media Queries */ 145 | @media screen and (max-width: 65.375em) { 146 | 147 | .cbp_tmtimeline > li .cbp_tmtime span:last-child { 148 | font-size: 1.5em; 149 | } 150 | 151 | 152 | .cbp_tmtimeline > li .cbp_tmtime { 153 | position: absolute; 154 | top: 0px; 155 | } 156 | 157 | } 158 | 159 | @media screen and (max-width: 47.2em) { 160 | .cbp_tmtimeline:before { 161 | display: none; 162 | } 163 | 164 | .cbp_tmtimeline > li .cbp_tmtime { 165 | width: 100%; 166 | position: relative; 167 | padding: 0 0 20px 0; 168 | } 169 | 170 | .cbp_tmtimeline > li .cbp_tmtime span { 171 | text-align: left; 172 | } 173 | 174 | .cbp_tmtimeline > li .cbp_tmlabel { 175 | margin: 0 0 30px 0; 176 | padding: 1em; 177 | font-weight: 400; 178 | font-size: 95%; 179 | } 180 | 181 | .cbp_tmtimeline > li .cbp_tmlabel:after { 182 | right: auto; 183 | left: 20px; 184 | border-right-color: transparent; 185 | border-bottom-color: #3594cb; 186 | top: -20px; 187 | } 188 | 189 | .cbp_tmtimeline > li:nth-child(odd) .cbp_tmlabel:after { 190 | border-right-color: transparent; 191 | border-bottom-color: #6cbfee; 192 | } 193 | 194 | .cbp_tmtimeline > li .cbp_tmicon { 195 | position: relative; 196 | float: right; 197 | left: auto; 198 | margin: -65px 5px 0 0px; 199 | } 200 | } 201 | 202 | 203 | -------------------------------------------------------------------------------- /search/js/bootstrap3-typeahead.min.js: -------------------------------------------------------------------------------- 1 | !function(a,b){"use strict";"undefined"!=typeof module&&module.exports?module.exports=b(require("jquery")):"function"==typeof define&&define.amd?define(["jquery"],function(a){return b(a)}):b(a.jQuery)}(this,function(a){"use strict";var b=function(b,c){this.$element=a(b),this.options=a.extend({},a.fn.typeahead.defaults,c),this.matcher=this.options.matcher||this.matcher,this.sorter=this.options.sorter||this.sorter,this.select=this.options.select||this.select,this.autoSelect="boolean"==typeof this.options.autoSelect?this.options.autoSelect:!0,this.highlighter=this.options.highlighter||this.highlighter,this.render=this.options.render||this.render,this.updater=this.options.updater||this.updater,this.displayText=this.options.displayText||this.displayText,this.source=this.options.source,this.delay=this.options.delay,this.$menu=a(this.options.menu),this.$appendTo=this.options.appendTo?a(this.options.appendTo):null,this.shown=!1,this.listen(),this.showHintOnFocus="boolean"==typeof this.options.showHintOnFocus?this.options.showHintOnFocus:!1,this.afterSelect=this.options.afterSelect,this.addItem=!1};b.prototype={constructor:b,select:function(){var a=this.$menu.find(".active").data("value");if(this.$element.data("active",a),this.autoSelect||a){var b=this.updater(a);this.$element.val(this.displayText(b)||b).change(),this.afterSelect(b)}return this.hide()},updater:function(a){return a},setSource:function(a){this.source=a},show:function(){var b,c=a.extend({},this.$element.position(),{height:this.$element[0].offsetHeight});return b="function"==typeof this.options.scrollHeight?this.options.scrollHeight.call():this.options.scrollHeight,(this.$appendTo?this.$menu.appendTo(this.$appendTo):this.$menu.insertAfter(this.$element)).css({top:c.top+c.height+b,left:c.left}).show(),this.shown=!0,this},hide:function(){return this.$menu.hide(),this.shown=!1,this},lookup:function(b){if(this.query="undefined"!=typeof b&&null!==b?b:this.$element.val()||"",this.query.length0?this.$element.data("active",b[0]):this.$element.data("active",null),this.options.addItem&&b.push(this.options.addItem),"all"==this.options.items?this.render(b).show():this.render(b.slice(0,this.options.items)).show()):this.shown?this.hide():this},matcher:function(a){var b=this.displayText(a);return~b.toLowerCase().indexOf(this.query.toLowerCase())},sorter:function(a){for(var b,c=[],d=[],e=[];b=a.shift();){var f=this.displayText(b);f.toLowerCase().indexOf(this.query.toLowerCase())?~f.indexOf(this.query)?d.push(b):e.push(b):c.push(b)}return c.concat(d,e)},highlighter:function(b){var c,d,e,f,g,h=a("
    "),i=this.query,j=b.toLowerCase().indexOf(i.toLowerCase());if(c=i.length,0===c)return h.text(b).html();for(;j>-1;)d=b.substr(0,j),e=b.substr(j,c),f=b.substr(j+c),g=a("").text(e),h.append(document.createTextNode(d)).append(g),b=f,j=b.toLowerCase().indexOf(i.toLowerCase());return h.append(document.createTextNode(b)).html()},render:function(b){var c=this,d=this,e=!1;return b=a(b).map(function(b,f){var g=d.displayText(f);return b=a(c.options.item).data("value",f),b.find("a").html(c.highlighter(g)),g==d.$element.val()&&(b.addClass("active"),d.$element.data("active",f),e=!0),b[0]}),this.autoSelect&&!e&&(b.first().addClass("active"),this.$element.data("active",b.first().data("value"))),this.$menu.html(b),this},displayText:function(a){return a.name||a},next:function(){var b=this.$menu.find(".active").removeClass("active"),c=b.next();c.length||(c=a(this.$menu.find("li")[0])),c.addClass("active")},prev:function(){var a=this.$menu.find(".active").removeClass("active"),b=a.prev();b.length||(b=this.$menu.find("li").last()),b.addClass("active")},listen:function(){this.$element.on("focus",a.proxy(this.focus,this)).on("blur",a.proxy(this.blur,this)).on("keypress",a.proxy(this.keypress,this)).on("keyup",a.proxy(this.keyup,this)),this.eventSupported("keydown")&&this.$element.on("keydown",a.proxy(this.keydown,this)),this.$menu.on("click",a.proxy(this.click,this)).on("mouseenter","li",a.proxy(this.mouseenter,this)).on("mouseleave","li",a.proxy(this.mouseleave,this))},destroy:function(){this.$element.data("typeahead",null),this.$element.data("active",null),this.$element.off("focus").off("blur").off("keypress").off("keyup"),this.eventSupported("keydown")&&this.$element.off("keydown"),this.$menu.remove()},eventSupported:function(a){var b=a in this.$element;return b||(this.$element.setAttribute(a,"return;"),b="function"==typeof this.$element[a]),b},move:function(a){if(this.shown){switch(a.keyCode){case 9:case 13:case 27:a.preventDefault();break;case 38:if(a.shiftKey)return;a.preventDefault(),this.prev();break;case 40:if(a.shiftKey)return;a.preventDefault(),this.next()}a.stopPropagation()}},keydown:function(b){this.suppressKeyPressRepeat=~a.inArray(b.keyCode,[40,38,9,13,27]),this.shown||40!=b.keyCode?this.move(b):this.lookup()},keypress:function(a){this.suppressKeyPressRepeat||this.move(a)},keyup:function(a){switch(a.keyCode){case 40:case 38:case 16:case 17:case 18:break;case 9:case 13:if(!this.shown)return;this.select();break;case 27:if(!this.shown)return;this.hide();break;default:this.lookup()}a.stopPropagation(),a.preventDefault()},focus:function(){this.focused||(this.focused=!0,this.options.showHintOnFocus&&this.lookup(""))},blur:function(){this.focused=!1,!this.mousedover&&this.shown&&this.hide()},click:function(a){a.stopPropagation(),a.preventDefault(),this.select(),this.$element.focus()},mouseenter:function(b){this.mousedover=!0,this.$menu.find(".active").removeClass("active"),a(b.currentTarget).addClass("active")},mouseleave:function(){this.mousedover=!1,!this.focused&&this.shown&&this.hide()}};var c=a.fn.typeahead;a.fn.typeahead=function(c){var d=arguments;return"string"==typeof c&&"getActive"==c?this.data("active"):this.each(function(){var e=a(this),f=e.data("typeahead"),g="object"==typeof c&&c;f||e.data("typeahead",f=new b(this,g)),"string"==typeof c&&(d.length>1?f[c].apply(f,Array.prototype.slice.call(d,1)):f[c]())})},a.fn.typeahead.defaults={source:[],items:8,menu:'',item:'
  • ',minLength:1,scrollHeight:0,autoSelect:!0,afterSelect:a.noop,delay:0,addItem:!1},a.fn.typeahead.Constructor=b,a.fn.typeahead.noConflict=function(){return a.fn.typeahead=c,this},a(document).on("focus.typeahead.data-api",'[data-provide="typeahead"]',function(){var b=a(this);b.data("typeahead")||b.typeahead(b.data())})}); -------------------------------------------------------------------------------- /about/js/modernizr.custom.js: -------------------------------------------------------------------------------- 1 | /* Modernizr 2.6.2 (Custom Build) | MIT & BSD 2 | * Build: http://modernizr.com/download/#-shiv-cssclasses-load 3 | */ 4 | ;window.Modernizr=function(a,b,c){function u(a){j.cssText=a}function v(a,b){return u(prefixes.join(a+";")+(b||""))}function w(a,b){return typeof a===b}function x(a,b){return!!~(""+a).indexOf(b)}function y(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:w(f,"function")?f.bind(d||b):f}return!1}var d="2.6.2",e={},f=!0,g=b.documentElement,h="modernizr",i=b.createElement(h),j=i.style,k,l={}.toString,m={},n={},o={},p=[],q=p.slice,r,s={}.hasOwnProperty,t;!w(s,"undefined")&&!w(s.call,"undefined")?t=function(a,b){return s.call(a,b)}:t=function(a,b){return b in a&&w(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=q.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(q.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(q.call(arguments)))};return e});for(var z in m)t(m,z)&&(r=z.toLowerCase(),e[r]=m[z](),p.push((e[r]?"":"no-")+r));return e.addTest=function(a,b){if(typeof a=="object")for(var d in a)t(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,typeof f!="undefined"&&f&&(g.className+=" "+(b?"":"no-")+a),e[a]=b}return e},u(""),i=k=null,function(a,b){function k(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function l(){var a=r.elements;return typeof a=="string"?a.split(" "):a}function m(a){var b=i[a[g]];return b||(b={},h++,a[g]=h,i[h]=b),b}function n(a,c,f){c||(c=b);if(j)return c.createElement(a);f||(f=m(c));var g;return f.cache[a]?g=f.cache[a].cloneNode():e.test(a)?g=(f.cache[a]=f.createElem(a)).cloneNode():g=f.createElem(a),g.canHaveChildren&&!d.test(a)?f.frag.appendChild(g):g}function o(a,c){a||(a=b);if(j)return a.createDocumentFragment();c=c||m(a);var d=c.frag.cloneNode(),e=0,f=l(),g=f.length;for(;e",f="hidden"in a,j=a.childNodes.length==1||function(){b.createElement("a");var a=b.createDocumentFragment();return typeof a.cloneNode=="undefined"||typeof a.createDocumentFragment=="undefined"||typeof a.createElement=="undefined"}()}catch(c){f=!0,j=!0}})();var r={elements:c.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",shivCSS:c.shivCSS!==!1,supportsUnknownElements:j,shivMethods:c.shivMethods!==!1,type:"default",shivDocument:q,createElement:n,createDocumentFragment:o};a.html5=r,q(b)}(this,b),e._version=d,g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+p.join(" "):""),e}(this,this.document),function(a,b,c){function d(a){return"[object Function]"==o.call(a)}function e(a){return"string"==typeof a}function f(){}function g(a){return!a||"loaded"==a||"complete"==a||"uninitialized"==a}function h(){var a=p.shift();q=1,a?a.t?m(function(){("c"==a.t?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l=b.createElement(a),o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};1===y[c]&&(r=1,y[c]=[]),"object"==a?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),"img"!=a&&(r||2===y[c]?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i("c"==b?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),1==p.length&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&"[object Opera]"==o.call(a.opera),l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return"[object Array]"==o.call(a)},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f 50 | #include 51 | #include 52 | 53 | //宏定义打印函数,使用方法 LOGI("hello") 或者 LOGI("money %d",15) 54 | #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "native", __VA_ARGS__)) 55 | #define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "native", __VA_ARGS__)) 56 | 57 | const char key[] = "abcdefghijklmnop"; //16个字符 58 | int len = 0; 59 | 60 | //计算字符对应的byte值 61 | unsigned char getByteNumber(unsigned char first, unsigned char end) { 62 | int firstPosition = 0, endPosition = 0; 63 | int position = 0; 64 | for (; position < 16; position++) { 65 | if (key[position] == first) { 66 | firstPosition = position; 67 | } 68 | if (key[position] == end) { 69 | endPosition = position; 70 | } 71 | } 72 | return (firstPosition << 4) | (endPosition); 73 | } 74 | 75 | //加密函数 76 | void encrypt(unsigned char p[], unsigned char res[]) { 77 | int i = 0; 78 | for (; i < len; i++) { 79 | res[2 * i] = key[p[i] / 16]; 80 | res[2 * i + 1] = key[p[i] % 16]; 81 | } 82 | } 83 | 84 | //解密函数 85 | void decrypt(unsigned char p[], char res[]) { 86 | int i; 87 | for (i = 0; i < len; i++) { 88 | res[i] = getByteNumber(p[i * 2], p[i * 2 + 1]); 89 | } 90 | } 91 | 92 | //java中生命的native函数,函数名称格式Java_包名(点换下划线)_类名_函数名 93 | //前两个参数JNIEnv *env, jclass this比较固定,其中第二个参数jclass代表方法是静态的,仅仅是个表示,如果方法不是静态的话,jclass换成jobject 94 | //后续的参数是函数要传进来的参数 95 | //java中的byte数组对应jni中的jbyteArray,jni中的jbyteArray可以通过jni中的函数转换为char数组 96 | jstring Java_me_codeboy_encrypt_EncryptUtil_encrypt(JNIEnv *env, jclass this, 97 | jbyteArray src) { 98 | unsigned char *buff = (char*) (*env)->GetByteArrayElements(env, src, NULL); 99 | len = (*env)->GetArrayLength(env, src); 100 | //加密后长度变为原先的2倍 101 | unsigned char res[len * 2]; 102 | encrypt(buff, res); 103 | //此步骤很重要,标志结束 104 | res[len * 2] = '\0'; 105 | 106 | //使用完毕释放src数组,因为src数组的存在jvm中 107 | (*env)->ReleaseByteArrayElements(env, src, buff, 0); 108 | 109 | //jni中函数将char数组转变为字符串,jni中字符串为jstring,对应java中的String 110 | jstring resStr = (*env)->NewStringUTF(env, res); 111 | return resStr; 112 | } 113 | 114 | //和加密类似 115 | jstring Java_me_codeboy_encrypt_EncryptUtil_decrypt(JNIEnv *env, jclass this, 116 | jbyteArray src) { 117 | unsigned char *buff = (char*) (*env)->GetByteArrayElements(env, src, NULL); 118 | len = (*env)->GetArrayLength(env, src); 119 | //解密后长度变为原先的1/2 120 | len = len / 2; 121 | signed char res[len]; 122 | decrypt(buff, res); 123 | //此步骤很重要,标志结束 124 | res[len] = '\0'; 125 | 126 | //使用完毕释放src数组,因为src数组的存在jvm中 127 | (*env)->ReleaseByteArrayElements(env, src, buff, 0); 128 | 129 | jstring resStr = (*env)->NewStringUTF(env, res); 130 | return resStr; 131 | } 132 | 133 | 这样我们的ndk相关的文件就写好了,下面在终端下切换到AndroidNDK目录下,运行命令即可: 134 | 135 | ../ndk-build 136 | 137 | 运行结果如下: 138 | 139 | mac:AndroidNDK YD$ ../ndk-build 140 | Android NDK: WARNING: APP_PLATFORM android-21 is larger than android:minSdkVersion 14 in ./AndroidManifest.xml 141 | [armeabi] Compile thumb : codeboy_encrypt <= encrypt.c 142 | [armeabi] SharedLibrary : libcodeboy_encrypt.so 143 | [armeabi] Install : libcodeboy_encrypt.so => libs/armeabi/libcodeboy_encrypt.so 144 | [armeabi-v7a] Compile thumb : codeboy_encrypt <= encrypt.c 145 | [armeabi-v7a] SharedLibrary : libcodeboy_encrypt.so 146 | [armeabi-v7a] Install : libcodeboy_encrypt.so => libs/armeabi-v7a/libcodeboy_encrypt.so 147 | 148 | 执行完成后,我们可以看一下libs文件夹,多了一些so文件,如下: 149 | 150 | mac:AndroidNDK YD$ tree libs 151 | libs 152 | ├── android-support-v4.jar 153 | ├── armeabi 154 | │ └── libcodeboy_encrypt.so 155 | └── armeabi-v7a 156 | └── libcodeboy_encrypt.so 157 | 158 | 2 directories, 3 files 159 | 160 | 161 | 下面我们就开始写对应的java代码了,将调用c函数的加解密函数抽象到一个类中即可 162 | 163 | **EncryptUtil.java** 164 | 165 | package me.codeboy.encrypt; 166 | 167 | public class EncryptUtil { 168 | public native static String encrypt(byte[] src); // 加密函数 169 | 170 | public native static String decrypt(byte[] src); // 解密函数 171 | 172 | static { 173 | System.loadLibrary("codeboy_encrypt"); 174 | } 175 | 176 | /** 177 | * 加密函数 178 | * 179 | * @param src 180 | * @return 181 | */ 182 | public static String encrypt(String src) { 183 | return encrypt(src.getBytes()); 184 | } 185 | 186 | /** 187 | * 解密函数 188 | * 189 | * @param src 190 | * @return 191 | */ 192 | public static String decrypt(String src) { 193 | return decrypt(src.getBytes()); 194 | } 195 | } 196 | 197 | 注意C语言中的函数名称中的包名类名函数名要与该类统一,还有对应的链接库名称。 198 | 199 | 做好了这些以后,我们就可以使用了。在我们的Activity中简单的定义一个按钮,点击后对一个字符串进行加密打印,之后进行解密打印,Activity中的代码如下: 200 | 201 | package me.codeboy.ndk.ui; 202 | 203 | import me.codeboy.encrypt.EncryptUtil; 204 | import me.codeboy.ndk.R; 205 | import android.app.Activity; 206 | import android.os.Bundle; 207 | import android.view.View; 208 | import android.view.View.OnClickListener; 209 | import android.widget.Button; 210 | 211 | public class MainActivity extends Activity { 212 | @Override 213 | protected void onCreate(Bundle savedInstanceState) { 214 | setContentView(R.layout.main_ui); 215 | super.onCreate(savedInstanceState); 216 | 217 | Button btn = (Button) findViewById(R.id.btn); 218 | btn.setOnClickListener(new OnClickListener() { 219 | 220 | @Override 221 | public void onClick(View v) { 222 | String src = "我是玄恒,欢迎访问我的网站codeboy.me"; 223 | String res = EncryptUtil.encrypt(src); 224 | System.out.println("------>" + res); 225 | res = EncryptUtil.decrypt(res); 226 | System.out.println("--->" + res); 227 | } 228 | }); 229 | } 230 | } 231 | 232 | 233 | 点击按钮后可以看到点击button打印的结果: 234 | 235 | --->ogiijbogjikpohioieogibjcoplmimogkmkcoilpiooikolpojjhkoogiijbohjkieohlnjbohkljjgdgpgegfgcgphjcogngf 236 | --->我是玄恒,欢迎访问我的网站codeboy.me 237 | 238 | 这样下来我们就完成了简单的加解密操作,也对ndk有了一个初步的了解。 239 | 240 | 241 | > 如有任何知识产权、版权问题或理论错误,还请指正。 242 | > 243 | > 转载请注明原作者及以上信息。 244 | -------------------------------------------------------------------------------- /_posts/2015-06-28-android-context.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: 'Context, What Context?' 4 | date: '2015-06-28' 5 | header-img: "img/post-bg-android.jpg" 6 | tags: 7 | - android 8 | author: 'Codeboy' 9 | --- 10 | Android中有各种各样的context,不同context有不同的用途,不仅仅生命周期不同,同时能够实现的操作也不相同,下面看一篇外国朋友总结的文章: 11 | 12 | **Context is probably the most used element in Android application, it may also be the most misused.** 13 | 14 | Context objects are so common, and get passed around so frequently, it can be easy to create a situation you didn’t intend. Loading resources, launching a new Activity, obtaining a system service, getting internal file paths, and creating views all require a Context (and that’s not even getting started on the full list!) to accomplish the task. What I’d like to do is provide for you some insights on how Context works alongside some tips that will (hopefully) allow you to leverage it more effectively in your applications. 15 | 16 | Context Types 17 | ---- 18 | Not all Context instances are created equal. Depending on the Android application component, the Contextyou have access to varies slightly: 19 | 20 | **Application** – is a singleton instance running in your application process. It can be accessed via methods like getApplication() from an Activity or Service, and getApplicationContext() from any other object that inherits from Context. Regardless of where or how it is accessed, you will always receive the same instance from within your process. 21 | 22 | **Activity/Service** – inherit from ContextWrapper which implements the same API, but proxies all of its method calls to a hidden internal Context instance, also known as its base context. Whenever the framework creates a new Activity or Service instance, it also creates a new ContextImpl instance to do all of the heavy lifting that either component will wrap. Each Activity or Service, and their corresponding base context, are unique per-instance. 23 | 24 | **BroadcastReceiver** – is not a Context in and of itself, but the framework passes a Context to it in onReceive() each time a new broadcast event comes in. This instance is a ReceiverRestrictedContext with two main functions disabled; calling registerReceiver() and bindService(). These two functions are not allowed from within an existing BroadcastReceiver.onReceive(). Each time a receiver processes a broadcast, the Contexthanded to it is a new instance. 25 | 26 | **ContentProvider** – is also not a Context but is given one when created that can be accessed via getContext(). If the ContentProvider is running local to the caller (i.e. same application process), then this will actually return the same Application singleton. However, if the two are in separate processes, this will be a newly created instance representing the package the provider is running in. 27 | 28 | Saved References 29 | ---- 30 | The first issue we need to address comes from saving a reference to a Context in an object or class that has a lifecycle that extends beyond that of the instance you saved. For example, creating a custom singleton that requires a Context to load resources or access a ContentProvider, and saving a reference to the current Activity or Service in that singleton. 31 | 32 | **Bad Singleton** 33 | 34 | public class CustomManager { 35 | private static CustomManager sInstance; 36 | 37 | public static CustomManager getInstance(Context context) { 38 | if (sInstance == null) { 39 | sInstance = new CustomManager(context); 40 | } 41 | 42 | return sInstance; 43 | } 44 | 45 | private Context mContext; 46 | 47 | private CustomManager(Context context) { 48 | mContext = context; 49 | } 50 | } 51 | 52 | The problem here is we don’t know where that Context came from, and it is not safe to hold a reference to the object if it ends up being an Activity or a Service. This is a problem because a singleton is managed by a single static reference inside the enclosing class. This means that our object, and ALL the other objects referenced by it, will never be garbage collected. If this Context were an Activity, we would effectively hold hostage in memory all the views and other potentially large objects associated with it; creating a leak. 53 | 54 | To protect against this, we modify the singleton to always reference the application context: 55 | 56 | **Better Singleton** 57 | 58 | public class CustomManager { 59 | private static CustomManager sInstance; 60 | 61 | public static CustomManager getInstance(Context context) { 62 | if (sInstance == null) { 63 | //Always pass in the Application Context 64 | sInstance = new CustomManager(context.getApplicationContext()); 65 | } 66 | 67 | return sInstance; 68 | } 69 | 70 | private Context mContext; 71 | 72 | private CustomManager(Context context) { 73 | mContext = context; 74 | } 75 | } 76 | 77 | Now it doesn’t matter where our Context came from, because the reference we are holding is safe. The application context is itself a singleton, so we aren’t leaking anything by creating another static reference to it. Another great example of places where this can crop up is saving references to a Context from inside a running background thread or a pending Handler. 78 | 79 | So why can’t we always just reference the application context? Take the middleman out of the equation, as it were, and never have to worry about creating leaks? The answer, as I alluded to in the introduction, is because one Context is not equal to another. 80 | 81 | Context Capabilities 82 | ---- 83 | The common actions you can safely take with a given Context object depends on where it came from originally. Below is a table of the common places an application will receive a Context, and in each case what it is useful for: 84 | 85 | FUNCTION |APPLICATION |ACTIVITY| SERVICE| CONTENTPROVIDER| BROADCASTRECEIVER 86 | ---|---|---|---|---|--- 87 | Show a Dialog| NO| YES |NO| NO| NO 88 | Start an Activity| NO①| YES |NO①| NO①| NO① 89 | Layout Inflation| NO②| YES| NO②| NO②| NO② 90 | Start a Service| YES| YES| YES| YES| YES 91 | Bind to a Service| YES |YES| YES| YES| NO 92 | Send a Broadcast| YES |YES| YES |YES |YES 93 | Register BroadcastReceiver| YES |YES| YES| YES| NO③ 94 | Load Resource Values| YES |YES| YES| YES| YES 95 | 96 | > ① An application CAN start an Activity from here, but it requires that a new task be created. This may fit specific use cases, but can create non-standard back stack behaviors in your application and is generally not recommended or considered good practice. 97 | > 98 | > ② This is legal, but inflation will be done with the default theme for the system on which you are running, not what’s defined in your application. 99 | > 100 | > ③ Allowed if the receiver is null, which is used for obtaining the current value of a sticky broadcast, on Android 4.2 and above. 101 | 102 | User Interface 103 | ---- 104 | You can see from looking at the previous table that there are a number of functions the application context is not properly suited to handle; all of them related to working with the UI. In fact, the only implementation equipped to handle all tasks associated with the UI is Activity; the other instances fare pretty much the same in all categories. 105 | 106 | Luckily, these three actions are things an application doesn’t really have any place doing outside the scope of an Activity; it’s almost like the framework was designed that way on purpose. Attempting to show a Dialogthat was created with a reference to the application context, or starting an Activity from the application context will throw an exception and crash your application…a strong indicator something has gone wrong. 107 | 108 | The less obvious issue is inflating layouts. If you read my last piece on layout inflation, you already know that it can be a slightly mysterious process with some hidden behaviors; using the right Context is linked to another one of those behaviors. While the framework will not complain and will return a perfectly good view hierarchy from a LayoutInflater created with the application context, the themes and styles from your app will not be considered in the process. This is because Activity is the only Context on which the themes defined in your manifest are actually attached. Any other instance will use the system default theme to inflate your views, leading to a display output you probably didn’t expect. 109 | 110 | The Intersection of these Rules 111 | ----- 112 | 113 | Invariably, someone will arrive at the conclusion that these two rules conflict. There is a case in the application’s current design where a long-term reference must be saved and we must save an Activity because the tasks we want to accomplish include manipulation of the UI. If that is the case, I would urge you to reconsider your design, as this would be a textbook instance of fighting the framework. 114 | 115 | The Rule of Thumb 116 | ---- 117 | In most cases, use the Context directly available to you from the enclosing component you’re working within. You can safely hold a reference to it as long as that reference does not extend beyond the lifecycle of that component. As soon as you need to save a reference to a Context from an object that lives beyond your Activity or Service, even temporarily, switch that reference you save over to the application context. 118 | 119 | *转自: https://possiblemobile.com/2013/06/context/* 120 | 121 | 122 | > 如有任何知识产权、版权问题或理论错误,还请指正。 123 | > 124 | > 转载请注明原作者及以上信息。 125 | -------------------------------------------------------------------------------- /css/codeboy.min.css: -------------------------------------------------------------------------------- 1 | body{font-family:"Helvetica Neue",Arial,"Hiragino Sans GB","STHeiti","Microsoft YaHei","WenQuanYi Micro Hei",SimSun,sans-serif;line-height:1.7;font-size:16px;color:#404040;overflow-x:hidden}p{margin:30px 0}h1,h2,h3,h4,h5,h6{font-family:"Helvetica Neue",Arial,"Hiragino Sans GB","STHeiti","Microsoft YaHei","WenQuanYi Micro Hei",SimSun,sans-serif;line-height:1.7;line-height:1.1;font-weight:800}h1{font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif}h4{font-size:20px}a{color:#404040}a:hover,a:focus{color:#0085a1}a img:hover,a img:focus{cursor:zoom-in}article{overflow-x:hidden}blockquote{color:gray;font-style:italic;font-size:.95em;margin:20px 0 20px}blockquote p{margin:0}.table th,.table td{border:1px solid #eee !important}hr.small{max-width:100px;margin:15px auto;border-width:4px;border-color:white}@media screen and (max-width:500px){pre code{display:block;width:500px}}.post-container a{color:#337ab7}.post-container a:hover,.post-container a:focus{color:#0085a1}.post-container ul,.post-container ol{margin-bottom:40px}.post-container ol ol,.post-container ol ul,.post-container ul ol,.post-container ul ul{margin-bottom:5px}.post-container li p{margin:0;margin-bottom:5px}.post-container li h1,.post-container li h2,.post-container li h3,.post-container li h4,.post-container li h5,.post-container li h6{line-height:2;margin-top:20px}.navbar-custom{background:white;position:absolute;top:0;left:0;width:100%;z-index:3;font-family:"Helvetica Neue",Arial,"Hiragino Sans GB","STHeiti","Microsoft YaHei","WenQuanYi Micro Hei",SimSun,sans-serif;line-height:1.7}.navbar-custom .navbar-brand{font-weight:800}.navbar-custom .nav li a{text-transform:uppercase;font-size:16px;font-weight:800;letter-spacing:1px}@media only screen and (min-width:768px){.navbar-custom{background:transparent;border-bottom:1px solid transparent}.navbar-custom body{font-size:20px}.navbar-custom .navbar-brand{color:white;padding:20px}.navbar-custom .navbar-brand:hover,.navbar-custom .navbar-brand:focus{color:rgba(255,255,255,0.8)}.navbar-custom .nav li a{font-size:18px;color:white;padding:20px}.navbar-custom .nav li a:hover,.navbar-custom .nav li a:focus{color:rgba(255,255,255,0.8)}}@media only screen and (min-width:1170px){.navbar-custom{-webkit-transition:background-color .3s;-moz-transition:background-color .3s;transition:background-color .3s;-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);transform:translate3d(0,0,0);-webkit-backface-visibility:hidden;backface-visibility:hidden}.navbar-custom.is-fixed{position:fixed;top:-61px;background-color:rgba(255,255,255,0.9);border-bottom:1px solid #f2f2f2;-webkit-transition:-webkit-transform .3s;-moz-transition:-moz-transform .3s;transition:transform .3s}.navbar-custom.is-fixed .navbar-brand{color:#404040}.navbar-custom.is-fixed .navbar-brand:hover,.navbar-custom.is-fixed .navbar-brand:focus{color:#0085a1}.navbar-custom.is-fixed .nav li a{color:#404040}.navbar-custom.is-fixed .nav li a:hover,.navbar-custom.is-fixed .nav li a:focus{color:#0085a1}.navbar-custom.is-visible{-webkit-transform:translate3d(0,100%,0);-moz-transform:translate3d(0,100%,0);-ms-transform:translate3d(0,100%,0);-o-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}.intro-header{background:no-repeat center center;background-color:gray;background-attachment:scroll;-webkit-background-size:cover;-moz-background-size:cover;background-size:cover;-o-background-size:cover;margin-bottom:0}@media only screen and (min-width:768px){.intro-header{margin-bottom:20px}}.intro-header .site-heading,.intro-header .post-heading,.intro-header .page-heading{padding:100px 0 50px;color:white}@media only screen and (min-width:768px){.intro-header .site-heading,.intro-header .post-heading,.intro-header .page-heading{padding:150px 0}}.intro-header .site-heading,.intro-header .page-heading{text-align:center}.intro-header .site-heading h1,.intro-header .page-heading h1{margin-top:0;font-size:50px}.intro-header .site-heading .subheading,.intro-header .page-heading .subheading{font-family:"Helvetica Neue",Arial,"Hiragino Sans GB","STHeiti","Microsoft YaHei","WenQuanYi Micro Hei",SimSun,sans-serif;line-height:1.7;font-size:20px;line-height:1.1;display:block;font-weight:300;margin:10px 0 0}@media only screen and (min-width:768px){.intro-header .site-heading h1,.intro-header .page-heading h1{font-size:80px}}.intro-header .post-heading h1{font-size:30px}.intro-header .post-heading .subheading,.intro-header .post-heading .meta{line-height:1.1;display:block}.intro-header .post-heading .subheading{font-family:"Helvetica Neue",Arial,"Hiragino Sans GB","STHeiti","Microsoft YaHei","WenQuanYi Micro Hei",SimSun,sans-serif;line-height:1.7;font-size:17px;font-weight:normal;margin:10px 0 30px;margin-top:-5px}.intro-header .post-heading .meta{font-family:'Lora','Times New Roman',serif;font-style:italic;font-weight:300;font-size:18px}.intro-header .post-heading .meta a{color:white}@media only screen and (min-width:768px){.intro-header .post-heading h1{font-size:55px}.intro-header .post-heading .subheading{font-size:30px}.intro-header .post-heading .meta{font-size:20px}}.post-preview>a{color:#404040}.post-preview>a:hover,.post-preview>a:focus{text-decoration:none;color:#0085a1}.post-preview>a>.post-title{font-size:21px;line-height:1.3;margin-top:30px;margin-bottom:8px}.post-preview>a>.post-subtitle{font-size:15px;margin:0;font-weight:300;margin-bottom:10px}.post-preview>.post-meta{font-family:'Lora','Times New Roman',serif;color:gray;font-size:16px;font-style:italic;margin-top:0}.post-preview>.post-meta>a{text-decoration:none;color:#404040}.post-preview>.post-meta>a:hover,.post-preview>.post-meta>a:focus{color:#0085a1;text-decoration:underline}@media only screen and (min-width:768px){.post-preview>a>.post-title{font-size:26px;line-height:1.3;margin-bottom:10px}.post-preview>a>.post-subtitle{font-size:16px}.post-preview .post-meta{font-size:18px}}.post-content-preview{font-size:16px;color:#a3a3a3}.post-content-preview:hover{color:#0085a1}@media only screen and (min-width:768px){.post-content-preview{font-size:18px}}.section-heading{font-size:36px;margin-top:60px;font-weight:700}.caption{text-align:center;font-size:14px;padding:10px;font-style:italic;margin:0;display:block;border-bottom-right-radius:5px;border-bottom-left-radius:5px}footer{font-size:20px;padding:50px 0 65px}footer .list-inline{margin:0;padding:0}footer .copyright{font-size:14px;text-align:center;margin-bottom:0}.floating-label-form-group{font-size:14px;position:relative;margin-bottom:0;padding-bottom:.5em;border-bottom:1px solid #eee}.floating-label-form-group input,.floating-label-form-group textarea{z-index:1;position:relative;padding-right:0;padding-left:0;border:0;border-radius:0;font-size:1.5em;background:0;box-shadow:none !important;resize:none}.floating-label-form-group label{display:block;z-index:0;position:relative;top:2em;margin:0;font-size:.85em;line-height:1.764705882em;vertical-align:middle;vertical-align:baseline;opacity:0;-webkit-transition:top .3s ease,opacity .3s ease;-moz-transition:top .3s ease,opacity .3s ease;-ms-transition:top .3s ease,opacity .3s ease;transition:top .3s ease,opacity .3s ease}.floating-label-form-group::not(:first-child){padding-left:14px;border-left:1px solid #eee}.floating-label-form-group-with-value label{top:0;opacity:1}.floating-label-form-group-with-focus label{color:#0085a1}form .row:first-child .floating-label-form-group{border-top:1px solid #eee}.btn{font-family:"Helvetica Neue",Arial,"Hiragino Sans GB","STHeiti","Microsoft YaHei","WenQuanYi Micro Hei",SimSun,sans-serif;line-height:1.7;text-transform:uppercase;font-size:14px;font-weight:800;letter-spacing:1px;border-radius:0;padding:15px 25px}.btn-lg{font-size:16px;padding:25px 35px}.btn-default:hover,.btn-default:focus{background-color:#0085a1;border:1px solid #0085a1;color:white}.pager{margin:20px 0 0}.pager li>a,.pager li>span{font-family:"Helvetica Neue",Arial,"Hiragino Sans GB","STHeiti","Microsoft YaHei","WenQuanYi Micro Hei",SimSun,sans-serif;line-height:1.7;text-transform:uppercase;font-size:14px;font-weight:800;letter-spacing:1px;padding:10px 5px;background-color:white;border-radius:0}@media only screen and (min-width:768px){.pager li>a,.pager li>span{font-size:14px;padding:15px 25px}}.pager li>a{color:#404040}.pager li>a:hover,.pager li>a:focus{color:white;background-color:#0085a1;border:1px solid #0085a1}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:gray;background-color:#404040;cursor:not-allowed}::-moz-selection{color:white;text-shadow:none;background:#0085a1}::selection{color:white;text-shadow:none;background:#0085a1}img::selection{color:white;background:transparent}img::-moz-selection{color:white;background:transparent}body{webkit-tap-highlight-color:#0085a1}.tags{margin-bottom:-5px}.tags a,.tags .tag{display:inline-block;border:1px solid rgba(255,255,255,0.8);border-radius:999em;padding:0 10px;color:#fff;line-height:24px;font-size:12px;text-decoration:none;margin:0 1px;margin-bottom:6px}.tags a:hover,.tags .tag:hover,.tags a:active,.tags .tag:active{color:white;border-color:white;background-color:rgba(255,255,255,0.4);text-decoration:none}@media only screen and (min-width:768px){.tags a,.tags .tag{margin-right:5px}}@media only screen and (min-width:768px){#tag-heading{padding:50px 0}}#tag_cloud{margin:20px 0 15px 0}#tag_cloud a,#tag_cloud .tag{font-size:14px;border:0;line-height:28px;margin:0 2px;margin-bottom:8px}#tag_cloud a:hover,#tag_cloud .tag:hover,#tag_cloud a:active,#tag_cloud .tag:active{background-color:#0085a1 !important}@media only screen and (min-width:768px){#tag_cloud{margin-bottom:25px}}.tag-comments{font-size:12px}@media only screen and (min-width:768px){.tag-comments{font-size:14px}}.one-tag-list:first-child{margin-top:0}.listing-seperator{color:#0085a1;font-size:17px !important}.listing-seperator::before{margin-right:5px}@media only screen and (min-width:768px){.listing-seperator{font-size:20px !important;line-height:1.5 !important;margin-top:5px}}.one-tag-list .post-preview{position:relative}.one-tag-list .post-preview>a .post-title{font-size:15px;margin-top:20px}.one-tag-list .post-preview>a .post-subtitle{font-size:12px}.one-tag-list .post-preview>.post-meta{position:absolute;right:5px;bottom:0;margin:0;font-size:12px;line-height:12px}@media only screen and (min-width:768px){.one-tag-list .post-preview{margin-left:20px}.one-tag-list .post-preview>a>.post-title{font-size:18px;line-height:1.3}.one-tag-list .post-preview>a>.post-subtitle{font-size:14px}.one-tag-list .post-preview .post-meta{font-size:18px}}.post-container img{display:block;max-width:100%;height:auto;margin:1.5em auto 1.6em auto}.post-container img.shadow{box-shadow:rgba(0,0,0,0.258824) 0 2px 5px 0}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:inherit}.navbar-default .navbar-toggle:active{background-color:#ddd}.navbar-default .navbar-toggle{border-color:transparent;padding:14px 11px;margin-top:4px;margin-right:10px;margin-bottom:4px;border-radius:50%}.navbar-default .navbar-toggle .icon-bar{width:18px;border-radius:0}.navbar-default .navbar-toggle .icon-bar+.icon-bar{margin-top:3px}.comment #ds-thread{margin-top:20px}.comment #ds-thread #ds-reset a.ds-like-thread-button{border:1px solid #ddd;border-radius:0;background:white;box-shadow:none;text-shadow:none}.comment #ds-thread #ds-reset li.ds-tab a.ds-current{border:1px solid #ddd;border-radius:0;background:white;box-shadow:none;text-shadow:none}.comment #ds-thread #ds-reset .ds-textarea-wrapper{background:0}.comment #ds-thread #ds-reset .ds-gradient-bg{background:0}#ds-smilies-tooltip ul.ds-smilies-tabs li a{background:white !important} -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | -------------------------------------------------------------------------------- /css/codeboy.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: "Helvetica Neue", Arial, "Hiragino Sans GB", "STHeiti", "Microsoft YaHei", "WenQuanYi Micro Hei", SimSun, sans-serif; 3 | line-height: 1.7; 4 | font-size: 16px; 5 | color: #404040; 6 | overflow-x: hidden; 7 | } 8 | p { 9 | margin: 30px 0; 10 | } 11 | h1, 12 | h2, 13 | h3, 14 | h4, 15 | h5, 16 | h6 { 17 | font-family: "Helvetica Neue", Arial, "Hiragino Sans GB", "STHeiti", "Microsoft YaHei", "WenQuanYi Micro Hei", SimSun, sans-serif; 18 | line-height: 1.7; 19 | line-height: 1.1; 20 | font-weight: 800; 21 | } 22 | h1 { 23 | font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif; 24 | } 25 | h4 { 26 | font-size: 20px; 27 | } 28 | a { 29 | color: #404040; 30 | } 31 | a:hover, 32 | a:focus { 33 | color: #0085a1; 34 | } 35 | a img:hover, 36 | a img:focus { 37 | cursor: zoom-in; 38 | } 39 | article { 40 | overflow-x: hidden; 41 | } 42 | blockquote { 43 | color: #808080; 44 | font-style: italic; 45 | font-size: 0.95em; 46 | margin: 20px 0 20px; 47 | } 48 | blockquote p { 49 | margin: 0; 50 | } 51 | .table th, 52 | .table td { 53 | border: 1px solid #eee !important; 54 | } 55 | hr.small { 56 | max-width: 100px; 57 | margin: 15px auto; 58 | border-width: 4px; 59 | border-color: white; 60 | } 61 | @media screen and (max-width: 500px) { 62 | pre code { 63 | display: block; 64 | width: 500px; 65 | } 66 | } 67 | .post-container a { 68 | color: #337ab7; 69 | } 70 | .post-container a:hover, 71 | .post-container a:focus { 72 | color: #0085a1; 73 | } 74 | .post-container ul, 75 | .post-container ol { 76 | margin-bottom: 40px; 77 | } 78 | .post-container ol ol, 79 | .post-container ol ul, 80 | .post-container ul ol, 81 | .post-container ul ul { 82 | margin-bottom: 5px; 83 | } 84 | .post-container li p { 85 | margin: 0; 86 | margin-bottom: 5px; 87 | } 88 | .post-container li h1, 89 | .post-container li h2, 90 | .post-container li h3, 91 | .post-container li h4, 92 | .post-container li h5, 93 | .post-container li h6 { 94 | line-height: 2; 95 | margin-top: 20px; 96 | } 97 | .navbar-custom { 98 | background: white; 99 | position: absolute; 100 | top: 0; 101 | left: 0; 102 | width: 100%; 103 | z-index: 3; 104 | font-family: "Helvetica Neue", Arial, "Hiragino Sans GB", "STHeiti", "Microsoft YaHei", "WenQuanYi Micro Hei", SimSun, sans-serif; 105 | line-height: 1.7; 106 | } 107 | .navbar-custom .navbar-brand { 108 | font-weight: 800; 109 | } 110 | .navbar-custom .nav li a { 111 | text-transform: uppercase; 112 | font-size: 16px; 113 | font-weight: 800; 114 | letter-spacing: 1px; 115 | } 116 | @media only screen and (min-width: 768px) { 117 | .navbar-custom { 118 | background: transparent; 119 | border-bottom: 1px solid transparent; 120 | } 121 | .navbar-custom body { 122 | font-size: 20px; 123 | } 124 | .navbar-custom .navbar-brand { 125 | color: white; 126 | padding: 20px; 127 | } 128 | .navbar-custom .navbar-brand:hover, 129 | .navbar-custom .navbar-brand:focus { 130 | color: rgba(255, 255, 255, 0.8); 131 | } 132 | .navbar-custom .nav li a { 133 | font-size:18px; 134 | color: white; 135 | padding: 20px; 136 | } 137 | .navbar-custom .nav li a:hover, 138 | .navbar-custom .nav li a:focus { 139 | color: rgba(255, 255, 255, 0.8); 140 | } 141 | } 142 | @media only screen and (min-width: 1170px) { 143 | .navbar-custom { 144 | -webkit-transition: background-color 0.3s; 145 | -moz-transition: background-color 0.3s; 146 | transition: background-color 0.3s; 147 | /* Force Hardware Acceleration in WebKit */ 148 | -webkit-transform: translate3d(0, 0, 0); 149 | -moz-transform: translate3d(0, 0, 0); 150 | -ms-transform: translate3d(0, 0, 0); 151 | -o-transform: translate3d(0, 0, 0); 152 | transform: translate3d(0, 0, 0); 153 | -webkit-backface-visibility: hidden; 154 | backface-visibility: hidden; 155 | } 156 | .navbar-custom.is-fixed { 157 | /* when the user scrolls down, we hide the header right above the viewport */ 158 | position: fixed; 159 | top: -61px; 160 | background-color: rgba(255, 255, 255, 0.9); 161 | border-bottom: 1px solid #f2f2f2; 162 | -webkit-transition: -webkit-transform 0.3s; 163 | -moz-transition: -moz-transform 0.3s; 164 | transition: transform 0.3s; 165 | } 166 | .navbar-custom.is-fixed .navbar-brand { 167 | color: #404040; 168 | } 169 | .navbar-custom.is-fixed .navbar-brand:hover, 170 | .navbar-custom.is-fixed .navbar-brand:focus { 171 | color: #0085a1; 172 | } 173 | .navbar-custom.is-fixed .nav li a { 174 | color: #404040; 175 | } 176 | .navbar-custom.is-fixed .nav li a:hover, 177 | .navbar-custom.is-fixed .nav li a:focus { 178 | color: #0085a1; 179 | } 180 | .navbar-custom.is-visible { 181 | /* if the user changes the scrolling direction, we show the header */ 182 | -webkit-transform: translate3d(0, 100%, 0); 183 | -moz-transform: translate3d(0, 100%, 0); 184 | -ms-transform: translate3d(0, 100%, 0); 185 | -o-transform: translate3d(0, 100%, 0); 186 | transform: translate3d(0, 100%, 0); 187 | } 188 | } 189 | .intro-header { 190 | background: no-repeat center center; 191 | background-color: #808080; 192 | background-attachment: scroll; 193 | -webkit-background-size: cover; 194 | -moz-background-size: cover; 195 | background-size: cover; 196 | -o-background-size: cover; 197 | margin-bottom: 0px; 198 | /* 0 on mobile */ 199 | } 200 | @media only screen and (min-width: 768px) { 201 | .intro-header { 202 | margin-bottom: 20px; 203 | /* response on desktop */ 204 | } 205 | } 206 | .intro-header .site-heading, 207 | .intro-header .post-heading, 208 | .intro-header .page-heading { 209 | padding: 100px 0 50px; 210 | color: white; 211 | } 212 | @media only screen and (min-width: 768px) { 213 | .intro-header .site-heading, 214 | .intro-header .post-heading, 215 | .intro-header .page-heading { 216 | padding: 150px 0; 217 | } 218 | } 219 | .intro-header .site-heading, 220 | .intro-header .page-heading { 221 | text-align: center; 222 | } 223 | .intro-header .site-heading h1, 224 | .intro-header .page-heading h1 { 225 | margin-top: 0; 226 | font-size: 50px; 227 | } 228 | .intro-header .site-heading .subheading, 229 | .intro-header .page-heading .subheading { 230 | font-family: "Helvetica Neue", Arial, "Hiragino Sans GB", "STHeiti", "Microsoft YaHei", "WenQuanYi Micro Hei", SimSun, sans-serif; 231 | line-height: 1.7; 232 | font-size: 20px; 233 | line-height: 1.1; 234 | display: block; 235 | font-weight: 300; 236 | margin: 10px 0 0; 237 | } 238 | @media only screen and (min-width: 768px) { 239 | .intro-header .site-heading h1, 240 | .intro-header .page-heading h1 { 241 | font-size: 80px; 242 | } 243 | } 244 | .intro-header .post-heading h1 { 245 | font-size: 30px; 246 | } 247 | .intro-header .post-heading .subheading, 248 | .intro-header .post-heading .meta { 249 | line-height: 1.1; 250 | display: block; 251 | } 252 | .intro-header .post-heading .subheading { 253 | font-family: "Helvetica Neue", Arial, "Hiragino Sans GB", "STHeiti", "Microsoft YaHei", "WenQuanYi Micro Hei", SimSun, sans-serif; 254 | line-height: 1.7; 255 | font-size: 17px; 256 | font-weight: normal; 257 | margin: 10px 0 30px; 258 | margin-top: -5px; 259 | } 260 | .intro-header .post-heading .meta { 261 | font-family: 'Lora', 'Times New Roman', serif; 262 | font-style: italic; 263 | font-weight: 300; 264 | font-size: 18px; 265 | } 266 | .intro-header .post-heading .meta a { 267 | color: white; 268 | } 269 | @media only screen and (min-width: 768px) { 270 | .intro-header .post-heading h1 { 271 | font-size: 55px; 272 | } 273 | .intro-header .post-heading .subheading { 274 | font-size: 30px; 275 | } 276 | .intro-header .post-heading .meta { 277 | font-size: 20px; 278 | } 279 | } 280 | .post-preview > a { 281 | color: #404040; 282 | } 283 | .post-preview > a:hover, 284 | .post-preview > a:focus { 285 | text-decoration: none; 286 | color: #0085a1; 287 | } 288 | .post-preview > a > .post-title { 289 | font-size: 21px; 290 | line-height: 1.3; 291 | margin-top: 30px; 292 | margin-bottom: 8px; 293 | } 294 | .post-preview > a > .post-subtitle { 295 | font-size: 15px; 296 | margin: 0; 297 | font-weight: 300; 298 | margin-bottom: 10px; 299 | } 300 | .post-preview > .post-meta { 301 | font-family: 'Lora', 'Times New Roman', serif; 302 | color: #808080; 303 | font-size: 16px; 304 | font-style: italic; 305 | margin-top: 0; 306 | } 307 | .post-preview > .post-meta > a { 308 | text-decoration: none; 309 | color: #404040; 310 | } 311 | .post-preview > .post-meta > a:hover, 312 | .post-preview > .post-meta > a:focus { 313 | color: #0085a1; 314 | text-decoration: underline; 315 | } 316 | @media only screen and (min-width: 768px) { 317 | .post-preview > a > .post-title { 318 | font-size: 26px; 319 | line-height: 1.3; 320 | margin-bottom: 10px; 321 | } 322 | .post-preview > a > .post-subtitle { 323 | font-size: 16px; 324 | } 325 | .post-preview .post-meta { 326 | font-size: 18px; 327 | } 328 | } 329 | .post-content-preview { 330 | font-size: 16px; 331 | color: #a3a3a3; 332 | } 333 | .post-content-preview:hover { 334 | color: #0085a1; 335 | } 336 | @media only screen and (min-width: 768px) { 337 | .post-content-preview { 338 | font-size: 18px; 339 | } 340 | } 341 | .section-heading { 342 | font-size: 36px; 343 | margin-top: 60px; 344 | font-weight: 700; 345 | } 346 | .caption { 347 | text-align: center; 348 | font-size: 14px; 349 | padding: 10px; 350 | font-style: italic; 351 | margin: 0; 352 | display: block; 353 | border-bottom-right-radius: 5px; 354 | border-bottom-left-radius: 5px; 355 | } 356 | footer { 357 | font-size: 20px; 358 | padding: 50px 0 65px; 359 | } 360 | footer .list-inline { 361 | margin: 0; 362 | padding: 0; 363 | } 364 | footer .copyright { 365 | font-size: 14px; 366 | text-align: center; 367 | margin-bottom: 0; 368 | } 369 | .floating-label-form-group { 370 | font-size: 14px; 371 | position: relative; 372 | margin-bottom: 0; 373 | padding-bottom: 0.5em; 374 | border-bottom: 1px solid #eeeeee; 375 | } 376 | .floating-label-form-group input, 377 | .floating-label-form-group textarea { 378 | z-index: 1; 379 | position: relative; 380 | padding-right: 0; 381 | padding-left: 0; 382 | border: none; 383 | border-radius: 0; 384 | font-size: 1.5em; 385 | background: none; 386 | box-shadow: none !important; 387 | resize: none; 388 | } 389 | .floating-label-form-group label { 390 | display: block; 391 | z-index: 0; 392 | position: relative; 393 | top: 2em; 394 | margin: 0; 395 | font-size: 0.85em; 396 | line-height: 1.764705882em; 397 | vertical-align: middle; 398 | vertical-align: baseline; 399 | opacity: 0; 400 | -webkit-transition: top 0.3s ease,opacity 0.3s ease; 401 | -moz-transition: top 0.3s ease,opacity 0.3s ease; 402 | -ms-transition: top 0.3s ease,opacity 0.3s ease; 403 | transition: top 0.3s ease,opacity 0.3s ease; 404 | } 405 | .floating-label-form-group::not(:first-child) { 406 | padding-left: 14px; 407 | border-left: 1px solid #eeeeee; 408 | } 409 | .floating-label-form-group-with-value label { 410 | top: 0; 411 | opacity: 1; 412 | } 413 | .floating-label-form-group-with-focus label { 414 | color: #0085a1; 415 | } 416 | form .row:first-child .floating-label-form-group { 417 | border-top: 1px solid #eeeeee; 418 | } 419 | .btn { 420 | font-family: "Helvetica Neue", Arial, "Hiragino Sans GB", "STHeiti", "Microsoft YaHei", "WenQuanYi Micro Hei", SimSun, sans-serif; 421 | line-height: 1.7; 422 | text-transform: uppercase; 423 | font-size: 14px; 424 | font-weight: 800; 425 | letter-spacing: 1px; 426 | border-radius: 0; 427 | padding: 15px 25px; 428 | } 429 | .btn-lg { 430 | font-size: 16px; 431 | padding: 25px 35px; 432 | } 433 | .btn-default:hover, 434 | .btn-default:focus { 435 | background-color: #0085a1; 436 | border: 1px solid #0085a1; 437 | color: white; 438 | } 439 | .pager { 440 | margin: 20px 0 0; 441 | } 442 | .pager li > a, 443 | .pager li > span { 444 | font-family: "Helvetica Neue", Arial, "Hiragino Sans GB", "STHeiti", "Microsoft YaHei", "WenQuanYi Micro Hei", SimSun, sans-serif; 445 | line-height: 1.7; 446 | text-transform: uppercase; 447 | font-size: 14px; 448 | font-weight: 800; 449 | letter-spacing: 1px; 450 | padding: 10px 5px; 451 | background-color: white; 452 | border-radius: 0; 453 | } 454 | @media only screen and (min-width: 768px) { 455 | .pager li > a, 456 | .pager li > span { 457 | font-size: 14px; 458 | padding: 15px 25px; 459 | } 460 | } 461 | .pager li > a { 462 | color: #404040; 463 | } 464 | .pager li > a:hover, 465 | .pager li > a:focus { 466 | color: white; 467 | background-color: #0085a1; 468 | border: 1px solid #0085a1; 469 | } 470 | .pager .disabled > a, 471 | .pager .disabled > a:hover, 472 | .pager .disabled > a:focus, 473 | .pager .disabled > span { 474 | color: #808080; 475 | background-color: #404040; 476 | cursor: not-allowed; 477 | } 478 | ::-moz-selection { 479 | color: white; 480 | text-shadow: none; 481 | background: #0085a1; 482 | } 483 | ::selection { 484 | color: white; 485 | text-shadow: none; 486 | background: #0085a1; 487 | } 488 | img::selection { 489 | color: white; 490 | background: transparent; 491 | } 492 | img::-moz-selection { 493 | color: white; 494 | background: transparent; 495 | } 496 | body { 497 | webkit-tap-highlight-color: #0085a1; 498 | } 499 | /* add tags support */ 500 | .tags { 501 | margin-bottom: -5px; 502 | } 503 | .tags a, 504 | .tags .tag { 505 | display: inline-block; 506 | border: 1px solid rgba(255, 255, 255, 0.8); 507 | border-radius: 999em; 508 | padding: 0 10px; 509 | color: #ffffff; 510 | line-height: 24px; 511 | font-size: 12px; 512 | text-decoration: none; 513 | margin: 0 1px; 514 | margin-bottom: 6px; 515 | } 516 | .tags a:hover, 517 | .tags .tag:hover, 518 | .tags a:active, 519 | .tags .tag:active { 520 | color: white; 521 | border-color: white; 522 | background-color: rgba(255, 255, 255, 0.4); 523 | text-decoration: none; 524 | } 525 | @media only screen and (min-width: 768px) { 526 | .tags a, 527 | .tags .tag { 528 | margin-right: 5px; 529 | } 530 | } 531 | @media only screen and (min-width: 768px) { 532 | #tag-heading { 533 | padding: 50px 0; 534 | } 535 | } 536 | #tag_cloud { 537 | margin: 20px 0 15px 0; 538 | } 539 | #tag_cloud a, 540 | #tag_cloud .tag { 541 | font-size: 14px; 542 | border: none; 543 | line-height: 28px; 544 | margin: 0 2px; 545 | margin-bottom: 8px; 546 | } 547 | #tag_cloud a:hover, 548 | #tag_cloud .tag:hover, 549 | #tag_cloud a:active, 550 | #tag_cloud .tag:active { 551 | background-color: #0085a1 !important; 552 | } 553 | @media only screen and (min-width: 768px) { 554 | #tag_cloud { 555 | margin-bottom: 25px; 556 | } 557 | } 558 | .tag-comments { 559 | font-size: 12px; 560 | } 561 | @media only screen and (min-width: 768px) { 562 | .tag-comments { 563 | font-size: 14px; 564 | } 565 | } 566 | .one-tag-list:first-child { 567 | margin-top: 0px; 568 | } 569 | .listing-seperator { 570 | color: #0085a1; 571 | font-size: 17px !important; 572 | } 573 | .listing-seperator::before { 574 | margin-right: 5px; 575 | } 576 | @media only screen and (min-width: 768px) { 577 | .listing-seperator { 578 | font-size: 20px !important; 579 | line-height: 1.5 !important; 580 | margin-top: 5px; 581 | } 582 | } 583 | .one-tag-list .post-preview { 584 | position: relative; 585 | } 586 | .one-tag-list .post-preview > a .post-title { 587 | font-size: 15px; 588 | margin-top: 20px; 589 | } 590 | .one-tag-list .post-preview > a .post-subtitle { 591 | font-size: 12px; 592 | } 593 | .one-tag-list .post-preview > .post-meta { 594 | position: absolute; 595 | right: 5px; 596 | bottom: 0px; 597 | margin: 0px; 598 | font-size: 12px; 599 | line-height: 12px; 600 | } 601 | @media only screen and (min-width: 768px) { 602 | .one-tag-list .post-preview { 603 | margin-left: 20px; 604 | } 605 | .one-tag-list .post-preview > a > .post-title { 606 | font-size: 18px; 607 | line-height: 1.3; 608 | } 609 | .one-tag-list .post-preview > a > .post-subtitle { 610 | font-size: 14px; 611 | } 612 | .one-tag-list .post-preview .post-meta { 613 | font-size: 18px; 614 | } 615 | } 616 | /* Tags support End*/ 617 | /* make all img responsible in post-container */ 618 | .post-container img { 619 | display: block; 620 | max-width: 100%; 621 | height: auto; 622 | margin: 1.5em auto 1.6em auto; 623 | } 624 | .post-container img.shadow { 625 | box-shadow: rgba(0, 0, 0, 0.258824) 0px 2px 5px 0px; 626 | } 627 | /* Optimize UserExperience */ 628 | .navbar-default .navbar-toggle:focus, 629 | .navbar-default .navbar-toggle:hover { 630 | background-color: inherit; 631 | } 632 | .navbar-default .navbar-toggle:active { 633 | background-color: #ddd; 634 | } 635 | /* customize Style for navBar button */ 636 | .navbar-default .navbar-toggle { 637 | border-color: transparent; 638 | padding: 14px 11px; 639 | margin-top: 4px; 640 | margin-right: 10px; 641 | margin-bottom: 4px; 642 | border-radius: 50%; 643 | } 644 | .navbar-default .navbar-toggle .icon-bar { 645 | width: 18px; 646 | border-radius: 0px; 647 | } 648 | .navbar-default .navbar-toggle .icon-bar + .icon-bar { 649 | margin-top: 3px; 650 | } 651 | /* customize Style for Duoshuo */ 652 | .comment #ds-thread { 653 | margin-top: 20px; 654 | } 655 | .comment #ds-thread #ds-reset a.ds-like-thread-button { 656 | border: 1px solid #ddd; 657 | border-radius: 0px; 658 | background: white; 659 | box-shadow: none; 660 | text-shadow: none; 661 | } 662 | .comment #ds-thread #ds-reset li.ds-tab a.ds-current { 663 | border: 1px solid #ddd; 664 | border-radius: 0px; 665 | background: white; 666 | box-shadow: none; 667 | text-shadow: none; 668 | } 669 | .comment #ds-thread #ds-reset .ds-textarea-wrapper { 670 | background: none; 671 | } 672 | .comment #ds-thread #ds-reset .ds-gradient-bg { 673 | background: none; 674 | } 675 | #ds-smilies-tooltip ul.ds-smilies-tabs li a { 676 | background: white !important; 677 | } 678 | --------------------------------------------------------------------------------