<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>个人记录 | 随心所意，记录点滴</title>
    <link>https://gker.net/</link>
    <description>Recent content on 个人记录 | 随心所意，记录点滴</description>
    <generator>Hugo</generator>
    <language>zh-cn</language>
    <lastBuildDate>Mon, 30 Nov 2020 11:50:12 +1000</lastBuildDate>
    <atom:link href="https://gker.net/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>MacBook重新打包jar</title>
      <link>https://gker.net/post/10028/</link>
      <pubDate>Mon, 30 Nov 2020 11:50:12 +1000</pubDate>
      <guid>https://gker.net/post/10028/</guid>
      <description>&lt;ul&gt;&#xA;&lt;li&gt;解压jar包&#xA;先进入X.jar所在目录&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&#x9;jar -xvf X.jar&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;&#xA;&lt;li&gt;重新打jar包&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&#x9;jar -cvf X.jar ./&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;&#xA;&lt;li&gt;替换META-INF/MANIFEST.MF文件，到打包后的X.jar包中。&#xA;用上一个命令打出的包，MANIFEST.MF文件中是没有入口类的信息的，需要更新正确的清单文件(非可执行文件可以省略这一步)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&#x9;jar umf META-INF/MANIFEST.MF X.jar&#xA;&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>ProtoBuffer中文转码</title>
      <link>https://gker.net/post/10027/</link>
      <pubDate>Sat, 31 Oct 2020 11:50:12 +1000</pubDate>
      <guid>https://gker.net/post/10027/</guid>
      <description>&lt;p&gt;许多时候需要查看日志中的中文字符，但是protobuf中某字段为中文的话，打印出来为8进制字符。若要打印为中文，可用以下代码：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import com.google.protobuf.TextFormat;&#xD;&#xA;&#xD;&#xA;public class NormalProtobufDeserializer implements IProtobufDeserializer{&#xD;&#xA;    @Override&#xD;&#xA;    public String deserial(byte[] data) {&#xD;&#xA;        String ret = &amp;#34;&amp;#34;;&#xD;&#xA;        try{&#xD;&#xA;            NormalDeserializer.NormalMessage normalMessage = NormalDeserializer.NormalMessage.parseFrom(data);&#xD;&#xA;            //ret = normalMessage.toString(); 此时为8进制，如&amp;#34;\241\242\243\244\245&amp;#34;&#xD;&#xA;            ret = TextFormat.printToUnicodeString(normalMessage);&#xD;&#xA;        }catch (Throwable throwable){&#xD;&#xA; &#xD;&#xA;        }&#xD;&#xA;        return ret;&#xD;&#xA;    }&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;若已经打印出八进制”\241\242\243\244\245”，可以用以下代码转成中文：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public static void printProtoBuf(String dataStr) {&#xD;&#xA;        if (!dataStr.contains(&amp;#34;\\&amp;#34;)) {&#xD;&#xA;            System.out.println(&amp;#34;未识别：&amp;#34; + dataStr);&#xD;&#xA;        } else {&#xD;&#xA;            //不属于八进制内容的字符&#xD;&#xA;            StringBuilder oldBuffer = new StringBuilder();&#xD;&#xA;            //属于八进制的内容，转成十六进制后缓存在这里&#xD;&#xA;            StringBuilder hexBuffer = new StringBuilder();&#xD;&#xA;            for (int i = 0; i &amp;lt; dataStr.length(); i++) {&#xD;&#xA;                char c = dataStr.charAt(i);&#xD;&#xA;                if (c != &amp;#39;\\&amp;#39;) {&#xD;&#xA;                    oldBuffer.append(c);&#xD;&#xA;                }&#xD;&#xA;                //反斜杠往后3个为一组，组成了一个八进制数。例如\20710,其实是207组成了一个八进制数&#xD;&#xA;                else {&#xD;&#xA;                    char c1 = dataStr.charAt(i + 1);&#xD;&#xA;                    char c2 = dataStr.charAt(i + 2);&#xD;&#xA;                    char c3 = dataStr.charAt(i + 3);&#xD;&#xA;                    if(c1 == &amp;#39;n&amp;#39; &amp;amp;&amp;amp; c2 == &amp;#39;\\&amp;#39;){&#xD;&#xA;                        i += 1;&#xD;&#xA;                        oldBuffer.append(&amp;#34;\n&amp;#34;);&#xD;&#xA;                    }else if(c1 == &amp;#39;t&amp;#39; &amp;amp;&amp;amp; c2 == &amp;#39;\\&amp;#39;){&#xD;&#xA;                        i += 1;&#xD;&#xA;                        oldBuffer.append(&amp;#34;\t&amp;#34;);&#xD;&#xA;                    }else if(c1 == &amp;#39;f&amp;#39; &amp;amp;&amp;amp; c2 == &amp;#39;\\&amp;#39;){&#xD;&#xA;                        i += 1;&#xD;&#xA;                        oldBuffer.append(&amp;#34;\f&amp;#34;);&#xD;&#xA;                    }else {&#xD;&#xA;                        i += 3;&#xD;&#xA;                        //将八进制转换为十进制，再转换为十六进制&#xD;&#xA;                        String hex = Integer.toHexString((Integer.valueOf(&amp;#34;&amp;#34; + c1 + c2 + c3, 8)));&#xD;&#xA;                        //先缓存住，直到凑够三个字节&#xD;&#xA;                        hexBuffer.append(hex);&#xD;&#xA;                        String hexString = hexBuffer.toString();&#xD;&#xA;                        //utf8编码中，三个字节为一个汉字&#xD;&#xA;                        if (hexString.length() == 6) {&#xD;&#xA;                            //凑够三个字节了，转成汉字后放入oldBuffer中&#xD;&#xA;                            oldBuffer.append(hexStr2Str(hexString));&#xD;&#xA;                            //凑够一个汉字了，清空缓存&#xD;&#xA;                            hexBuffer = new StringBuilder();&#xD;&#xA;                        }&#xD;&#xA;                    }&#xD;&#xA;                }&#xD;&#xA;            }&#xD;&#xA;            System.out.println(&amp;#34;解码后：&amp;#34; + oldBuffer.toString());&#xD;&#xA;        }&#xD;&#xA;    }&#xA;&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>Parameter ‘directory‘ is not a directory</title>
      <link>https://gker.net/post/10026/</link>
      <pubDate>Wed, 21 Oct 2020 12:52:14 +1000</pubDate>
      <guid>https://gker.net/post/10026/</guid>
      <description>&lt;p&gt;将AndroidStudio项目复制了一份，运行时报错：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Execution failed for task &amp;#39;:app:dataBindingGenBaseClassesDebug&amp;#39;.      &#xD;&#xA;Parameter &amp;#39;directory&amp;#39; is not a directory   &#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;按照stackoverflow的方法， invalidata Cache/Restart 或者删除 .gradle 文件夹，都不好使 最终解决办法是在命令行执行编译一遍：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;./gradlew assembleDebug --rerun-tasks&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;完成后重新在AndroidStudio中运行就可以了。&lt;/p&gt;</description>
    </item>
    <item>
      <title>混淆映射mapping压缩</title>
      <link>https://gker.net/post/10025/</link>
      <pubDate>Tue, 25 Aug 2020 10:51:14 +0800</pubDate>
      <guid>https://gker.net/post/10025/</guid>
      <description>&lt;p&gt;我们项目里终会有一些不需要混淆的符号，比如一些第三方包，一些jni调用，一些自动解析的model,这些不混淆的符号也会在mapping里生在相同不变的符号映射，其实这些符号映射是不需要也能正常解码错误代码的，去掉这些未混淆的符号就能给mapping文件瘦身，当文件超级大时，可以把android源生sdk取消混淆，第三方开源库也能取消，只把自己开发的核心功能保留混淆，这样去掉未混淆之符号时，mapping会达到极为精简的地步。&lt;/p&gt;&#xA;&lt;p&gt;使用shell可以很轻松的去掉未混淆的符号：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;find ./ -name mapping.txt | xargs cat | awk &amp;#39;{if($2!=$4) print $0}&amp;#39;&amp;gt;./newmapping.txt&#xA;&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>使用Simpleperf对Android应用进行分析</title>
      <link>https://gker.net/post/10024/</link>
      <pubDate>Fri, 21 Aug 2020 19:15:23 +0800</pubDate>
      <guid>https://gker.net/post/10024/</guid>
      <description>&lt;p&gt;在NDK目录下，找到simpleperf目录，在终端中进入。&lt;/p&gt;&#xA;&lt;p&gt;调整现场，启动CPU分析，生成perf.data&lt;br&gt;&#xA;python uplive_profiler.py -p com.asiainno.uplive&lt;/p&gt;&#xA;&lt;p&gt;对perf.data进行解析生成out.perf&lt;br&gt;&#xA;python report_sample.py &amp;gt; out.perf&lt;/p&gt;&#xA;&lt;p&gt;借助FlameGraph工具&lt;br&gt;&#xA;git clone &lt;a href=&#34;https://github.com/brendangregg/FlameGraph.git&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;https://github.com/brendangregg/FlameGraph.git&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;将out.perf中的符号进行折叠：&lt;br&gt;&#xA;./FlameGraph/stackcollapse-perf.pl out.perf &amp;gt;out.folded&lt;/p&gt;&#xA;&lt;p&gt;生成svg图，用chrome打开既是火焰图&lt;br&gt;&#xA;./FlameGraph/flamegraph.pl out.folded &amp;gt;p.svg&lt;/p&gt;&#xA;&lt;p&gt;火焰图原理&lt;br&gt;&#xA;&lt;a href=&#34;https://blog.openresty.com.cn/cn/dynamic-tracing/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;https://blog.openresty.com.cn/cn/dynamic-tracing/&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>本站建设记录</title>
      <link>https://gker.net/about/</link>
      <pubDate>Mon, 10 Aug 2020 13:51:14 +0800</pubDate>
      <guid>https://gker.net/about/</guid>
      <description>&lt;h1 id=&#34;安装hugo下载直接可用&#34;&gt;安装hugo，下载直接可用 &lt;a href=&#34;#%e5%ae%89%e8%a3%85hugo%e4%b8%8b%e8%bd%bd%e7%9b%b4%e6%8e%a5%e5%8f%af%e7%94%a8&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;&lt;a href=&#34;https://github.com/gohugoio/hugo/releases&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;https://github.com/gohugoio/hugo/releases&lt;/a&gt;&lt;/p&gt;&#xA;&lt;h1 id=&#34;验证是否成功&#34;&gt;验证是否成功 &lt;a href=&#34;#%e9%aa%8c%e8%af%81%e6%98%af%e5%90%a6%e6%88%90%e5%8a%9f&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;hugo version&lt;/p&gt;&#xA;&lt;h1 id=&#34;建站&#34;&gt;建站 &lt;a href=&#34;#%e5%bb%ba%e7%ab%99&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;hugo new site gker&lt;/p&gt;&#xA;&lt;h1 id=&#34;添加主题&#34;&gt;添加主题 &lt;a href=&#34;#%e6%b7%bb%e5%8a%a0%e4%b8%bb%e9%a2%98&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;cd gker;&lt;br&gt;&#xA;git init;&lt;br&gt;&#xA;git submodule add &lt;a href=&#34;https://github.com/budparr/gohugo-theme-ananke.git&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;https://github.com/budparr/gohugo-theme-ananke.git&lt;/a&gt; themes/ananke;&lt;br&gt;&#xA;//编辑你的 config.toml 配置文件使用该主题&lt;br&gt;&#xA;echo &amp;rsquo;theme = &amp;ldquo;ananke&amp;rdquo;&amp;rsquo; &amp;raquo; config.toml&lt;/p&gt;&#xA;&lt;h1 id=&#34;新建文章&#34;&gt;新建文章 &lt;a href=&#34;#%e6%96%b0%e5%bb%ba%e6%96%87%e7%ab%a0&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;hugo new post/first.md&lt;/p&gt;&#xA;&lt;h1 id=&#34;本地测试&#34;&gt;本地测试 &lt;a href=&#34;#%e6%9c%ac%e5%9c%b0%e6%b5%8b%e8%af%95&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;hugo server -D&lt;br&gt;&#xA;访问http://localhost:1313&lt;/p&gt;&#xA;&lt;h1 id=&#34;生成静态网站&#34;&gt;生成静态网站 &lt;a href=&#34;#%e7%94%9f%e6%88%90%e9%9d%99%e6%80%81%e7%bd%91%e7%ab%99&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;hugo&lt;/p&gt;&#xA;&lt;h1 id=&#34;生成的网站源码结构&#34;&gt;生成的网站源码结构 &lt;a href=&#34;#%e7%94%9f%e6%88%90%e7%9a%84%e7%bd%91%e7%ab%99%e6%ba%90%e7%a0%81%e7%bb%93%e6%9e%84&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;archetypes: 储存.md的模板文件，类似于hexo的scaffolds，该文件夹的优先级高于主题下的/archetypes文件夹&lt;br&gt;&#xA;config.toml: 配置文件&lt;br&gt;&#xA;content: 储存网站的所有内容，类似于hexo的source&lt;br&gt;&#xA;data: 储存数据文件供模板调用，类似于hexo的source/_data&lt;br&gt;&#xA;layouts: 储存.html模板，该文件夹的优先级高于主题下的/layouts文件夹&lt;br&gt;&#xA;static: 储存图片,css,js等静态文件，该目录下的文件会直接拷贝到/public，该文件夹的优先级高于主题下的/static文件夹&lt;br&gt;&#xA;themes: 储存主题&lt;br&gt;&#xA;public: 执行hugo命令后，储存生成的静态文件&lt;/p&gt;</description>
    </item>
    <item>
      <title>Android颜色计算</title>
      <link>https://gker.net/post/10022/</link>
      <pubDate>Tue, 13 Nov 2018 12:53:25 +0800</pubDate>
      <guid>https://gker.net/post/10022/</guid>
      <description>&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;/**&#xD;&#xA; * 合并颜色，支持argb8888 &#xD;&#xA; * @param fg 前景色&#xD;&#xA; * @param bg 背景色&#xD;&#xA; */&#xD;&#xA; public static int blendColor(int fg, int bg) {&#xD;&#xA; int scr = Color.red(fg);&#xD;&#xA; int scg = Color.green(fg);&#xD;&#xA; int scb = Color.blue(fg);&#xD;&#xA; int sa = fg &amp;gt;&amp;gt;&amp;gt; 24;&#xD;&#xA; int dcr = Color.red(bg);&#xD;&#xA; int dcg = Color.green(bg);&#xD;&#xA; int dcb = Color.blue(bg);&#xD;&#xA; int color_r = dcr * (0xff - sa) / 0xff + scr * sa / 0xff;&#xD;&#xA; int color_g = dcg * (0xff - sa) / 0xff + scg * sa / 0xff;&#xD;&#xA; int color_b = dcb * (0xff - sa) / 0xff + scb * sa / 0xff;&#xD;&#xA; return ((color_r &amp;lt;&amp;lt; 16) + (color_g &amp;lt;&amp;lt; 8) + color_b) | (0xff000000);&#xD;&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;    /** Calculates the constrast between two colors, using the algorithm provided by the WCAG v2. */&#xD;&#xA;    public static float computeContrastBetweenColors(int bg, int fg) {&#xD;&#xA;        float bgR = Color.red(bg) / 255f;&#xD;&#xA;        float bgG = Color.green(bg) / 255f;&#xD;&#xA;        float bgB = Color.blue(bg) / 255f;&#xD;&#xA;        bgR = (bgR &amp;lt; 0.03928f) ? bgR / 12.92f : (float) Math.pow((bgR + 0.055f) / 1.055f, 2.4f);&#xD;&#xA;        bgG = (bgG &amp;lt; 0.03928f) ? bgG / 12.92f : (float) Math.pow((bgG + 0.055f) / 1.055f, 2.4f);&#xD;&#xA;        bgB = (bgB &amp;lt; 0.03928f) ? bgB / 12.92f : (float) Math.pow((bgB + 0.055f) / 1.055f, 2.4f);&#xD;&#xA;        float bgL = 0.2126f * bgR + 0.7152f * bgG + 0.0722f * bgB;&#xD;&#xA;        &#xD;&#xA;        float fgR = Color.red(fg) / 255f;&#xD;&#xA;        float fgG = Color.green(fg) / 255f;&#xD;&#xA;        float fgB = Color.blue(fg) / 255f;&#xD;&#xA;        fgR = (fgR &amp;lt; 0.03928f) ? fgR / 12.92f : (float) Math.pow((fgR + 0.055f) / 1.055f, 2.4f);&#xD;&#xA;        fgG = (fgG &amp;lt; 0.03928f) ? fgG / 12.92f : (float) Math.pow((fgG + 0.055f) / 1.055f, 2.4f);&#xD;&#xA;        fgB = (fgB &amp;lt; 0.03928f) ? fgB / 12.92f : (float) Math.pow((fgB + 0.055f) / 1.055f, 2.4f);&#xD;&#xA;        float fgL = 0.2126f * fgR + 0.7152f * fgG + 0.0722f * fgB;&#xD;&#xA; &#xD;&#xA;        return Math.abs((fgL + 0.05f) / (bgL + 0.05f));&#xD;&#xA;    }&#xD;&#xA;&#x9;//判断是否是深色&#xD;&#xA;&#x9;isDark = computeContrastBetweenColors(color,Color.WHITE) &amp;gt; 3f;&#xA;&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>MacOS遇到莫名其妙的ssl或者git问题</title>
      <link>https://gker.net/post/10021/</link>
      <pubDate>Wed, 25 Apr 2018 10:50:23 +0800</pubDate>
      <guid>https://gker.net/post/10021/</guid>
      <description>&lt;p&gt;mac上遇到unable to access &amp;lsquo;&lt;a href=&#34;https://github.com/bitcoin/bitcoin.git/%27&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;https://github.com/bitcoin/bitcoin.git/&#39;&lt;/a&gt;: LibreSSL SSL_read: SSL_ERROR_SYSCALL, errno 54&#xA;或者git无法使用时，执行下面的指令即可：&lt;/p&gt;&#xA;&lt;p&gt;sudo xcode-select -switch /Applications/Xcode.app/Contents/Developer&lt;/p&gt;</description>
    </item>
    <item>
      <title>EOS代码结构总览</title>
      <link>https://gker.net/post/10020/</link>
      <pubDate>Mon, 05 Feb 2018 12:11:12 +0800</pubDate>
      <guid>https://gker.net/post/10020/</guid>
      <description>&lt;p&gt;##总览&#xA;###代码地址&#xA;&lt;a href=&#34;https://github.com/EOSIO/eos&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;https://github.com/EOSIO/eos&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;###代码结构图&#xA;&lt;p class=&#34;markdown-image&#34;&gt;&#xD;&#xA;  &lt;img src=&#34;http://cdn.gker.net/883c64330fd14f2585e6dcfe8070c966.png&#34; alt=&#34;EOS代码&#34;  /&gt;&#xD;&#xA;&lt;/p&gt;&lt;/p&gt;&#xA;&lt;p&gt;###对应说明&#xA;CMakeModules&#xA;描述编译过程的文件&lt;/p&gt;&#xA;&lt;p&gt;Docker&#xA;容器，方便编译和运行。参考docker.com&lt;/p&gt;&#xA;&lt;p&gt;contracts&#xA;智能合约代码（重要）&lt;/p&gt;&#xA;&lt;p&gt;docs&#xA;文档&lt;/p&gt;&#xA;&lt;p&gt;libraries&#xA;EOS编译时依赖的其他项目&lt;/p&gt;&#xA;&lt;p&gt;plugins（重要）&#xA;各种API插件&lt;/p&gt;&#xA;&lt;p&gt;programs&#xA;可以运行的程序&lt;/p&gt;&#xA;&lt;p&gt;scripts&#xA;辅助编译的脚本&lt;/p&gt;&#xA;&lt;p&gt;tests&#xA;测试代码。编译完成后测试程序是否正常运行的程序。&lt;/p&gt;&#xA;&lt;p&gt;tools&#xA;工具类&lt;/p&gt;&#xA;&lt;p&gt;build.sh&#xA;开始编译的脚本&lt;/p&gt;&#xA;&lt;p&gt;其他程序图标等不做解释。为什么contracts和plugins标注重要呢？因为其他所有的东西都是辅助而已，contracts是最为核心的东西，plugins是桥梁对程序员来说也很重要，programs等只是外包装。&lt;/p&gt;&#xA;&lt;p&gt;###编译过程&#xA;在README文档中说的已经很清楚了，按照步骤一步一步即可编译完成。&#xA;&lt;p class=&#34;markdown-image&#34;&gt;&#xD;&#xA;  &lt;img src=&#34;http://cdn.gker.net/27803c8f8bb549d5801a4315f6c2fd5d.png&#34; alt=&#34;编译完成的目录结构&#34;  /&gt;&#xD;&#xA;&lt;/p&gt;&lt;/p&gt;&#xA;&lt;p&gt;###运行过程&#xA;编译完成后，主要的运行程序（对应在programs目录下）有eosiod、eosioc、eosio-walletd&#xA;按照README提示，执行一次eosiod生成data-dir目录，配置config.ini后重新运行即可。&lt;/p&gt;&#xA;&lt;p&gt;####eosiod&#xA;这是EOS的主程序&lt;/p&gt;&#xA;&lt;p&gt;####eosioc&#xA;eosioc 为了方面调用eosiod所暴露出来的REST接口的工具。&lt;/p&gt;&#xA;&lt;p&gt;####eosio-wallet&#xA;eosio-wallet启动后就是一个web服务器，默认监听本地8888接口，支持用 http://127.0.0.1:8888/v1/wallet/get_public_keys 等REST方法操作EOS账户、钱包相关动作。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Android硬件加速后单个Bitmap可以显示的最大尺寸</title>
      <link>https://gker.net/post/10019/</link>
      <pubDate>Tue, 14 Nov 2017 18:56:12 +0800</pubDate>
      <guid>https://gker.net/post/10019/</guid>
      <description>&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;private void getGLESTextureLimitBelowLollipop() {  &#xD;&#xA;    int[] maxSize = new int[1];  &#xD;&#xA;    GLES10.glGetIntegerv(GLES10.GL_MAX_TEXTURE_SIZE, maxSize, 0);  &#xD;&#xA;    Toast.makeText(this,&amp;#34; &amp;#34; + maxSize[0],Toast.LENGTH_LONG).show();  &#xD;&#xA;}  &#xA;&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;private void getGLESTextureLimitEqualAboveLollipop() {  &#xD;&#xA;    EGL10 egl = (EGL10) EGLContext.getEGL();  &#xD;&#xA;    EGLDisplay dpy = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);  &#xD;&#xA;    int[] vers = new int[2];  &#xD;&#xA;    egl.eglInitialize(dpy, vers);  &#xD;&#xA;    int[] configAttr = {  &#xD;&#xA;            EGL10.EGL_COLOR_BUFFER_TYPE, EGL10.EGL_RGB_BUFFER,  &#xD;&#xA;            EGL10.EGL_LEVEL, 0,  &#xD;&#xA;            EGL10.EGL_SURFACE_TYPE, EGL10.EGL_PBUFFER_BIT,  &#xD;&#xA;            EGL10.EGL_NONE  &#xD;&#xA;    };  &#xD;&#xA;    EGLConfig[] configs = new EGLConfig[1];  &#xD;&#xA;    int[] numConfig = new int[1];  &#xD;&#xA;    egl.eglChooseConfig(dpy, configAttr, configs, 1, numConfig);  &#xD;&#xA;    if (numConfig[0] == 0) {// TROUBLE! No config found.  &#xD;&#xA;    }  &#xD;&#xA;    EGLConfig config = configs[0];  &#xD;&#xA;    int[] surfAttr = {  &#xD;&#xA;            EGL10.EGL_WIDTH, 64,  &#xD;&#xA;            EGL10.EGL_HEIGHT, 64,  &#xD;&#xA;            EGL10.EGL_NONE  &#xD;&#xA;    };  &#xD;&#xA;    EGLSurface surf = egl.eglCreatePbufferSurface(dpy, config, surfAttr);  &#xD;&#xA;    final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;  // missing in EGL10  &#xD;&#xA;    int[] ctxAttrib = {  &#xD;&#xA;            EGL_CONTEXT_CLIENT_VERSION, 1,  &#xD;&#xA;            EGL10.EGL_NONE  &#xD;&#xA;    };  &#xD;&#xA;    EGLContext ctx = egl.eglCreateContext(dpy, config, EGL10.EGL_NO_CONTEXT, ctxAttrib);  &#xD;&#xA;    egl.eglMakeCurrent(dpy, surf, surf, ctx);  &#xD;&#xA;    int[] maxSize = new int[1];  &#xD;&#xA;    GLES10.glGetIntegerv(GLES10.GL_MAX_TEXTURE_SIZE, maxSize, 0);  &#xD;&#xA;    egl.eglMakeCurrent(dpy, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE,  &#xD;&#xA;            EGL10.EGL_NO_CONTEXT);  &#xD;&#xA;    egl.eglDestroySurface(dpy, surf);  &#xD;&#xA;    egl.eglDestroyContext(dpy, ctx);  &#xD;&#xA;    egl.eglTerminate(dpy);  &#xD;&#xA;  &#xD;&#xA;    Toast.makeText(this,&amp;#34; &amp;#34; + maxSize[0],Toast.LENGTH_LONG).show();  &#xD;&#xA;} &#xA;&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;if (Build.VERSION.SDK_INT &amp;gt;= Build.VERSION_CODES.LOLLIPOP) {  &#xD;&#xA;    getGLESTextureLimitEqualAboveLollipop();  &#xD;&#xA;} else {  &#xD;&#xA;    getGLESTextureLimitBelowLollipop();  &#xD;&#xA;} &#xA;&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>Fresco修改decoder，解决超大图显示模糊的问题。</title>
      <link>https://gker.net/post/10018/</link>
      <pubDate>Tue, 31 Oct 2017 16:35:39 +0800</pubDate>
      <guid>https://gker.net/post/10018/</guid>
      <description>&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;private void setImageUrl() {&#xD;&#xA;    ImageRequest request = ImageRequestBuilder.newBuilderWithSource(Uri.parse(model.getImage()))&#xD;&#xA;            .setImageDecodeOptions(Utils.getFileTypeIsGif(model.getImage()) ? null ://null表示使用原有默认decoder&#xD;&#xA;                    ImageDecodeOptions.newBuilder()&#xD;&#xA;                            .setCustomImageDecoder(new ImageDecoder() {&#xD;&#xA;                                @Override&#xD;&#xA;  public CloseableImage decode(EncodedImage encodedImage, int length, QualityInfo qualityInfo, ImageDecodeOptions options) {&#xD;&#xA;                                    Bitmap bitmap = null;&#xD;&#xA; if (encodedImage.getHeight() &amp;gt; Utils.dip2px(manager.getContext(), 150)) {&#xD;&#xA;                                        int height = Utils.dip2px(manager.getContext(), 150);&#xD;&#xA; int width = Utils.getWidth(manager.getContext());&#xD;&#xA;  width = width &amp;gt; encodedImage.getWidth() ? encodedImage.getWidth() : width;&#xD;&#xA;  SkiaImageRegionDecoder inDecoder = new SkiaImageRegionDecoder();&#xD;&#xA;  Rect region = new Rect();&#xD;&#xA;  region.left = (encodedImage.getWidth() - width) / 2;&#xD;&#xA;  region.right = region.left + width;&#xD;&#xA;  region.top = (encodedImage.getHeight() - height) / 2;&#xD;&#xA;  region.bottom = region.top + height;&#xD;&#xA; try {&#xD;&#xA;                                            inDecoder.init(manager.getContext(), Uri.parse(&amp;#34;file://&amp;#34; + FrescoUtils.getImageFileOnDisk(Uri.parse(model.getImage())).getAbsolutePath()));&#xD;&#xA;  bitmap = inDecoder.decodeRegion(region, 1);&#xD;&#xA;  } catch (Exception e) {&#xD;&#xA;                                            LogInfo.LogOut(e);&#xD;&#xA;  }&#xD;&#xA;                                    }&#xD;&#xA;                                    if (bitmap == null) {//TODO 此处最好使用原有默认decoder&#xD;&#xA;                                        bitmap = BitmapFactory.decodeStream(encodedImage.getInputStream());&#xD;&#xA;  }&#xD;&#xA;                                    return new CloseableStaticBitmap(&#xD;&#xA;                                            bitmap,&#xD;&#xA;  SimpleBitmapReleaser.getInstance(),&#xD;&#xA;  ImmutableQualityInfo.FULL_QUALITY,&#xD;&#xA;  0);&#xD;&#xA;&#xD;&#xA;  }&#xD;&#xA;                            })&#xD;&#xA;                            .build())&#xD;&#xA;            .build();&#xD;&#xA;  DraweeController controller = Fresco.newDraweeControllerBuilder()&#xD;&#xA;            .setImageRequest(request)&#xD;&#xA;            .setAutoPlayAnimations(Utils.getFileTypeIsGif(model.getImage()))&#xD;&#xA;            .setOldController(image.getController())&#xD;&#xA;            .setControllerListener(new BaseControllerListener())&#xD;&#xA;            .build();&#xD;&#xA;  image.setController(controller);&#xD;&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>学习正则表达式</title>
      <link>https://gker.net/post/10017/</link>
      <pubDate>Wed, 16 Aug 2017 12:25:29 +0800</pubDate>
      <guid>https://gker.net/post/10017/</guid>
      <description>&lt;p&gt;本文为转载，&lt;a href=&#34;https://github.com/zeeshanu/learn-regex/blob/master/README-cn.md&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;原文地址&lt;/a&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;什么是正则表达式&#34;&gt;什么是正则表达式? &lt;a href=&#34;#%e4%bb%80%e4%b9%88%e6%98%af%e6%ad%a3%e5%88%99%e8%a1%a8%e8%be%be%e5%bc%8f&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h2&gt;&lt;blockquote&gt;&#xA;&lt;p&gt;正则表达式是一组由字母和符号组成的特殊文本, 它可以用来从文本中找出满足你想要的格式的句子.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;一个正则表达式是在一个主体字符串中从左到右匹配字符串时的一种样式. 例如&amp;quot;Regular expression&amp;quot;是一个完整的句子, 但我们常使用缩写的术语&amp;quot;regex&amp;quot;或&amp;quot;regexp&amp;quot;. 正则表达式可以用来替换文本中的字符串,验证形式,提取字符串等等.&lt;/p&gt;&#xA;&lt;p&gt;想象你正在写一个应用, 然后你想设定一个用户命名的规则, 让用户名包含字符,数字,下划线和连字符,以及限制字符的个数,好让名字看起来没那么丑. 我们使用以下正则表达式来验证一个用户名:&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://camo.githubusercontent.com/90cf24181617b0cfc26f5a650d406f7e53b83927/68747470733a2f2f692e696d6775722e636f6d2f5071354c6c61742e706e67&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;p class=&#34;markdown-image&#34;&gt;&#xD;&#xA;  &lt;img src=&#34;https://camo.githubusercontent.com/90cf24181617b0cfc26f5a650d406f7e53b83927/68747470733a2f2f692e696d6775722e636f6d2f5071354c6c61742e706e67&#34; alt=&#34;&#34;  /&gt;&#xD;&#xA;&lt;/p&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;以上的正则表达式可以接受 &lt;code&gt;john_doe&lt;/code&gt;, &lt;code&gt;jo-hn_doe&lt;/code&gt;, &lt;code&gt;john12_as&lt;/code&gt;. 但不匹配&lt;code&gt;Jo&lt;/code&gt;, 因为它包含了大写的字母而且太短了.&lt;/p&gt;&#xA;&lt;h1 id=&#34;目录&#34;&gt;&lt;a href=&#34;https://gker.net/articles/2017/08/16/1502871430957.html#%e7%9b%ae%e5%bd%95&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;/a&gt;目录 &lt;a href=&#34;#%e7%9b%ae%e5%bd%95&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h1&gt;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://gker.net/articles/2017/08/16/1502871430957.html#1-%E5%9F%BA%E6%9C%AC%E5%8C%B9%E9%85%8D&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;1. 基本匹配&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://gker.net/articles/2017/08/16/1502871430957.html#2-%E5%85%83%E5%AD%97%E7%AC%A6&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;2. 元字符&lt;/a&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://gker.net/articles/2017/08/16/1502871430957.html#21-%E7%82%B9%E8%BF%90%E7%AE%97%E7%AC%A6-&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;2.1 点运算符 .&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://gker.net/articles/2017/08/16/1502871430957.html#22-%E5%AD%97%E7%AC%A6%E9%9B%86&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;2.2 字符集&lt;/a&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://gker.net/articles/2017/08/16/1502871430957.html#221-%E5%90%A6%E5%AE%9A%E5%AD%97%E7%AC%A6%E9%9B%86&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;2.2.1 否定字符集&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://gker.net/articles/2017/08/16/1502871430957.html#23-%E9%87%8D%E5%A4%8D%E6%AC%A1%E6%95%B0&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;2.3 重复次数&lt;/a&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://gker.net/articles/2017/08/16/1502871430957.html#231--%E5%8F%B7&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;2.3.1 * 号&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://gker.net/articles/2017/08/16/1502871430957.html#232--%E5%8F%B7&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;2.3.2 号&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://gker.net/articles/2017/08/16/1502871430957.html#233--%E5%8F%B7&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;2.3.3 ? 号&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://gker.net/articles/2017/08/16/1502871430957.html#24--%E5%8F%B7&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;2.4 {} 号&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://gker.net/articles/2017/08/16/1502871430957.html#25--%E7%89%B9%E5%BE%81%E6%A0%87%E7%BE%A4&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;2.5 (&amp;hellip;) 特征标群&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://gker.net/articles/2017/08/16/1502871430957.html#26--%E6%88%96%E8%BF%90%E7%AE%97%E7%AC%A6&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;2.6 | 或运算符&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://gker.net/articles/2017/08/16/1502871430957.html#27-%E8%BD%AC%E7%A0%81%E7%89%B9%E6%AE%8A%E5%AD%97%E7%AC%A6&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;2.7 转码特殊字符&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://gker.net/articles/2017/08/16/1502871430957.html#28-%E9%94%9A%E7%82%B9&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;2.8 锚点&lt;/a&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://gker.net/articles/2017/08/16/1502871430957.html#281--%E5%8F%B7&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;2.8.1 ^ 号&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://gker.net/articles/2017/08/16/1502871430957.html#282--%E5%8F%B7&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;2.8.2 $ 号&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://gker.net/articles/2017/08/16/1502871430957.html#3-%E7%AE%80%E5%86%99%E5%AD%97%E7%AC%A6%E9%9B%86&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;3. 简写字符集&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://gker.net/articles/2017/08/16/1502871430957.html#4-%E5%89%8D%E5%90%8E%E5%85%B3%E8%81%94%E7%BA%A6%E6%9D%9F%E5%89%8D%E5%90%8E%E9%A2%84%E6%9F%A5&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;4. 前后关联约束(前后预查)&lt;/a&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://gker.net/articles/2017/08/16/1502871430957.html#41--%E5%89%8D%E7%BD%AE%E7%BA%A6%E6%9D%9F%E5%AD%98%E5%9C%A8&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;4.1 ?=&amp;hellip; 前置约束(存在)&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://gker.net/articles/2017/08/16/1502871430957.html#42--%E5%89%8D%E7%BD%AE%E7%BA%A6%E6%9D%9F-%E6%8E%92%E9%99%A4&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;4.2 ?!&amp;hellip; 前置约束-排除&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://gker.net/articles/2017/08/16/1502871430957.html#43---%E5%90%8E%E7%BD%AE%E7%BA%A6%E6%9D%9F-%E5%AD%98%E5%9C%A8&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;4.3 ?&amp;lt;= &amp;hellip; 后置约束-存在&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;[4.4 ? &lt;code&gt;the&lt;/code&gt;, 它表示一个规则: 由字母&lt;code&gt;t&lt;/code&gt;开始,接着是&lt;code&gt;h&lt;/code&gt;,再接着是&lt;code&gt;e&lt;/code&gt;.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;&amp;ldquo;the&amp;rdquo; =&amp;gt; The fat cat sat on &lt;a href=&#34;https://gker.net/articles/2017/08/16/1502871430957.html#learn-regex&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;strong&gt;the&lt;/strong&gt;&lt;/a&gt; mat.&lt;/p&gt;</description>
    </item>
    <item>
      <title>升级到Android Studio 3.0 Beta 1后编译错误解决</title>
      <link>https://gker.net/post/10016/</link>
      <pubDate>Thu, 10 Aug 2017 10:55:19 +0800</pubDate>
      <guid>https://gker.net/post/10016/</guid>
      <description>&lt;p&gt;如果现有的 Android Studio 项目使用的是 Android plugin 3.0.0  的 Alpha 版本（如 3.0.0-alpha9），那么迁移到 Android plugin 3.0.0-beta1 并进行&lt;a href=&#34;http://d.android.com/studio/build/index.html#sync-files&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;项目同步&lt;/a&gt;时，可能会收到以下错误 ：Gradle project refresh failed。&lt;/p&gt;&#xA;&lt;p&gt;解决方法：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;从菜单栏中选择 &lt;strong&gt;Build &amp;gt; Clean Project&lt;/strong&gt;，需要为每个项目执行一次这个操作。然后，可以通过从工具栏中单击同步项目，使用 Gradle 将项目文件同步。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://androidstudio.googleblog.com/2017/08/android-studio-30-beta-1.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;官方解决方案链接&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>记录AndroidStudio升级2.3后DataBinding与Realm注解冲突问题</title>
      <link>https://gker.net/post/10015/</link>
      <pubDate>Thu, 22 Jun 2017 19:45:12 +0800</pubDate>
      <guid>https://gker.net/post/10015/</guid>
      <description>&lt;p&gt;现象：&#xA;2.3后不支持apt了，所以旧版本Realm编译不通过。&lt;/p&gt;&#xA;&lt;p&gt;升级Realm后，DataBinding编译失败，报找不到BR错误。&lt;/p&gt;&#xA;&lt;p&gt;借助kotlin使用kapt &amp;ldquo;com.android.databinding:compiler:2.3.3&amp;quot;编译后，Realm的相应注解没有被解析，报is not part of the schema for this Realm错误&lt;/p&gt;&#xA;&lt;p&gt;最终解决：&#xA;所有用到注解的三方库，都得加上解释器：&#xA;annotationProcessor &amp;ldquo;com.android.databinding:compiler:2.3.3&amp;rdquo;&#xA;annotationProcessor &amp;lsquo;org.greenrobot:eventbus-annotation-processor:3.0.1&amp;rsquo;&#xA;annotationProcessor &amp;ldquo;io.realm:realm-annotations-processor:3.3.2&amp;rdquo;&lt;/p&gt;&#xA;&lt;p&gt;参考&#xA;1.https://stackoverflow.com/questions/38642712/enable-annotation-processors-option-in-android-studio-2-2&#xA;2.https://stackoverflow.com/questions/40940253/realm-and-android-databinding&#xA;3.https://developer.android.com/topic/libraries/data-binding/index.html&lt;/p&gt;</description>
    </item>
    <item>
      <title>搜索中文汉字的正则表达式</title>
      <link>https://gker.net/post/10014/</link>
      <pubDate>Sun, 18 Jun 2017 16:16:38 +0800</pubDate>
      <guid>https://gker.net/post/10014/</guid>
      <description>&lt;p&gt;^((?!(*|//)).)+[\u4e00-\u9fa5]&lt;/p&gt;</description>
    </item>
    <item>
      <title>Android手机上传下载文件夹</title>
      <link>https://gker.net/post/10013/</link>
      <pubDate>Fri, 16 Jun 2017 12:13:28 +0800</pubDate>
      <guid>https://gker.net/post/10013/</guid>
      <description>&lt;p&gt;批量从/sdcard/files目录下载文件到电脑：adb shell ls /sdcard/files/* | tr &amp;ldquo;\n\r&amp;rdquo; &amp;quot; &amp;quot; | xargs -n1 adb pull&lt;/p&gt;&#xA;&lt;p&gt;注意：如果permission denied，则先执行adb root，再执行adb remount,如果你不知道什么是root，那么就不要操作了。&lt;/p&gt;&#xA;&lt;p&gt;将整个目录下的文件上传到手机：adb push . /sdcard/files&lt;/p&gt;</description>
    </item>
    <item>
      <title>Android打开最近任务列表代码</title>
      <link>https://gker.net/post/10012/</link>
      <pubDate>Thu, 18 May 2017 16:17:18 +0800</pubDate>
      <guid>https://gker.net/post/10012/</guid>
      <description>&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Class serviceManagerClass;&#xD;&#xA;try {&#xD;&#xA;    serviceManagerClass = Class.forName(&amp;#34;android.os.ServiceManager&amp;#34;);&#xD;&#xA;  Method getService = serviceManagerClass.getMethod(&amp;#34;getService&amp;#34;,&#xD;&#xA;  String.class);&#xD;&#xA;  IBinder retbinder = (IBinder) getService.invoke(&#xD;&#xA;            serviceManagerClass, &amp;#34;statusbar&amp;#34;);&#xD;&#xA;  Class statusBarClass = Class.forName(retbinder&#xD;&#xA;            .getInterfaceDescriptor());&#xD;&#xA;  Object statusBarObject = statusBarClass.getClasses()[0].getMethod(&#xD;&#xA;            &amp;#34;asInterface&amp;#34;, IBinder.class).invoke(null,&#xD;&#xA; new Object[]{retbinder});&#xD;&#xA;  Method clearAll = statusBarClass.getMethod(&amp;#34;toggleRecentApps&amp;#34;);&#xD;&#xA;  clearAll.setAccessible(true);&#xD;&#xA;  clearAll.invoke(statusBarObject);&#xD;&#xA;} catch (Exception e) {&#xD;&#xA;    e.printStackTrace();&#xD;&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>Activity的启动过程拦截Intent参数</title>
      <link>https://gker.net/post/10011/</link>
      <pubDate>Tue, 18 Apr 2017 18:14:10 +0800</pubDate>
      <guid>https://gker.net/post/10011/</guid>
      <description>&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import  android.content.ComponentName;&#xD;&#xA;import android.content.Context;&#xD;&#xA;import android.content.Intent;&#xD;&#xA;import android.os.Bundle;&#xD;&#xA;import android.os.Handler;&#xD;&#xA;import android.os.Message;&#xD;&#xA;import android.util.Log;&#xD;&#xA;&#xD;&#xA;import java.lang.reflect.Field;&#xD;&#xA;import java.lang.reflect.InvocationHandler;&#xD;&#xA;import java.lang.reflect.Method;&#xD;&#xA;import java.lang.reflect.Proxy;&#xD;&#xA;&#xD;&#xA;public class HookUtil {&#xD;&#xA;&#xD;&#xA;    private Class proxyActivity;&#xD;&#xA;&#xD;&#xA; private Context context;&#xD;&#xA;&#xD;&#xA; public HookUtil(Context context) {&#xD;&#xA;        try {&#xD;&#xA;            this.proxyActivity = Class.forName(&amp;#34;class&amp;#34;);&#xD;&#xA;  } catch (ClassNotFoundException e) {&#xD;&#xA;            e.printStackTrace();&#xD;&#xA;  }&#xD;&#xA;        this.context = context;&#xD;&#xA;  }&#xD;&#xA;&#xD;&#xA;    public void hookSystemHandler() {&#xD;&#xA;        try {&#xD;&#xA;&#xD;&#xA;            Class activityThreadClass = Class.forName(&amp;#34;android.app.ActivityThread&amp;#34;);&#xD;&#xA;  Method currentActivityThreadMethod = activityThreadClass.getDeclaredMethod(&amp;#34;currentActivityThread&amp;#34;);&#xD;&#xA;  currentActivityThreadMethod.setAccessible(true);&#xD;&#xA;  //获取主线程对象&#xD;&#xA;  Object activityThread = currentActivityThreadMethod.invoke(null);&#xD;&#xA;  //获取mH字段&#xD;&#xA;  Field mH = activityThreadClass.getDeclaredField(&amp;#34;mH&amp;#34;);&#xD;&#xA;  mH.setAccessible(true);&#xD;&#xA;  //获取Handler&#xD;&#xA;  Handler handler = (Handler) mH.get(activityThread);&#xD;&#xA;  //获取原始的mCallBack字段&#xD;&#xA;  Field mCallBack = Handler.class.getDeclaredField(&amp;#34;mCallback&amp;#34;);&#xD;&#xA;  mCallBack.setAccessible(true);&#xD;&#xA;  //这里设置了我们自己实现了接口的CallBack对象&#xD;&#xA;  mCallBack.set(handler, new ActivityThreadHandlerCallback(handler));&#xD;&#xA;&#xD;&#xA;  } catch (Exception e) {&#xD;&#xA;            e.printStackTrace();&#xD;&#xA;  }&#xD;&#xA;    }&#xD;&#xA;&#xD;&#xA;    public void hookAms() {&#xD;&#xA;&#xD;&#xA;        //一路反射，直到拿到IActivityManager的对象&#xD;&#xA;  try {&#xD;&#xA;            Class ActivityManagerNativeClss = Class.forName(&amp;#34;android.app.ActivityManagerNative&amp;#34;);&#xD;&#xA;  Field defaultFiled = ActivityManagerNativeClss.getDeclaredField(&amp;#34;gDefault&amp;#34;);&#xD;&#xA;  defaultFiled.setAccessible(true);&#xD;&#xA;  Object defaultValue = defaultFiled.get(null);&#xD;&#xA;  //反射SingleTon&#xD;&#xA;  Class SingletonClass = Class.forName(&amp;#34;android.util.Singleton&amp;#34;);&#xD;&#xA;  Field mInstance = SingletonClass.getDeclaredField(&amp;#34;mInstance&amp;#34;);&#xD;&#xA;  mInstance.setAccessible(true);&#xD;&#xA;  //到这里已经拿到ActivityManager对象&#xD;&#xA;  Object iActivityManagerObject = mInstance.get(defaultValue);&#xD;&#xA;&#xD;&#xA;  //开始动态代理，用代理对象替换掉真实的ActivityManager，瞒天过海&#xD;&#xA;  Class IActivityManagerIntercept = Class.forName(&amp;#34;android.app.IActivityManager&amp;#34;);&#xD;&#xA;&#xD;&#xA;  AmsInvocationHandler handler = new AmsInvocationHandler(iActivityManagerObject);&#xD;&#xA;&#xD;&#xA;  Object proxy = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[]{IActivityManagerIntercept}, handler);&#xD;&#xA;&#xD;&#xA;  //现在替换掉这个对象&#xD;&#xA;  mInstance.set(defaultValue, proxy);&#xD;&#xA;&#xD;&#xA;  } catch (Exception e) {&#xD;&#xA;            e.printStackTrace();&#xD;&#xA;  }&#xD;&#xA;    }&#xD;&#xA;&#xD;&#xA;    private class ActivityThreadHandlerCallback implements Handler.Callback {&#xD;&#xA;&#xD;&#xA;        private Handler handler;&#xD;&#xA;&#xD;&#xA; private ActivityThreadHandlerCallback(Handler handler) {&#xD;&#xA;            this.handler = handler;&#xD;&#xA;  }&#xD;&#xA;&#xD;&#xA;        @Override&#xD;&#xA;  public boolean handleMessage(Message msg) {&#xD;&#xA;            Log.i(&amp;#34;HookAmsUtil&amp;#34;, &amp;#34;handleMessage&amp;#34;);&#xD;&#xA;  //替换之前的Intent&#xD;&#xA;  if (msg.what == 100) {&#xD;&#xA;                Log.i(&amp;#34;HookAmsUtil&amp;#34;, &amp;#34;lauchActivity&amp;#34;);&#xD;&#xA;  handleLauchActivity(msg);&#xD;&#xA;  }&#xD;&#xA;&#xD;&#xA;            handler.handleMessage(msg);&#xD;&#xA; return true;  }&#xD;&#xA;&#xD;&#xA;        private void handleLauchActivity(Message msg) {&#xD;&#xA;            Object obj = msg.obj;//ActivityClientRecord&#xD;&#xA;  try {&#xD;&#xA;                Field intentField = obj.getClass().getDeclaredField(&amp;#34;intent&amp;#34;);&#xD;&#xA;  intentField.setAccessible(true);&#xD;&#xA;  Intent proxyInent = (Intent) intentField.get(obj);&#xD;&#xA;  Intent realIntent = proxyInent.getParcelableExtra(&amp;#34;oldIntent&amp;#34;);&#xD;&#xA; if (realIntent != null) {&#xD;&#xA;                    proxyInent.setComponent(realIntent.getComponent());&#xD;&#xA;  }&#xD;&#xA;            } catch (Exception e) {&#xD;&#xA;                Log.i(&amp;#34;HookAmsUtil&amp;#34;, &amp;#34;lauchActivity falied&amp;#34;);&#xD;&#xA;  }&#xD;&#xA;&#xD;&#xA;        }&#xD;&#xA;    }&#xD;&#xA;&#xD;&#xA;    public class AmsInvocationHandler implements InvocationHandler {&#xD;&#xA;&#xD;&#xA;        private Object iActivityManagerObject;&#xD;&#xA;&#xD;&#xA; public AmsInvocationHandler(Object iActivityManagerObject) {&#xD;&#xA;            this.iActivityManagerObject = iActivityManagerObject;&#xD;&#xA;  }&#xD;&#xA;&#xD;&#xA;        @Override&#xD;&#xA;  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {&#xD;&#xA;&#xD;&#xA;            Log.i(&amp;#34;HookUtil&amp;#34;, method.getName());&#xD;&#xA; if (&amp;#34;startActivity&amp;#34;.contains(method.getName())) {&#xD;&#xA;                Log.e(&amp;#34;HookUtil&amp;#34;, &amp;#34;Activity已经开始启动&amp;#34;);&#xD;&#xA;  //换掉&#xD;&#xA;  Intent intent = null;&#xD;&#xA; int index = 0;&#xD;&#xA; for (int i = 0; i &amp;lt; args.length; i++) {&#xD;&#xA;                    Object arg = args[i];&#xD;&#xA; if (arg instanceof Intent) {&#xD;&#xA;                        //说明找到了startActivity的Intent参数&#xD;&#xA;  intent = (Intent) args[i];&#xD;&#xA;  //这个意图是不能被启动的，因为Acitivity没有在清单文件中注册&#xD;&#xA;  index = i;&#xD;&#xA; if (intent != null) {&#xD;&#xA;                            Bundle extras = intent.getExtras();&#xD;&#xA; if (extras != null &amp;amp;&amp;amp; extras.keySet() != null) {&#xD;&#xA;                                for (String key : extras.keySet()) {&#xD;&#xA;                                    Log.d(&amp;#34;HookUtil&amp;#34;, &amp;#34;intent.extras.key=&amp;#34; + key + &amp;#34;,value=&amp;#34; + extras.get(key));&#xD;&#xA;  }&#xD;&#xA;                            }&#xD;&#xA;                            Log.d(&amp;#34;HookUtil&amp;#34;, extras + &amp;#34;&amp;#34;);&#xD;&#xA;  }&#xD;&#xA;                    }&#xD;&#xA;                }&#xD;&#xA;&#xD;&#xA;                //伪造一个代理的Intent，代理Intent启动的是proxyActivity&#xD;&#xA;  if (context != null &amp;amp;&amp;amp; proxyActivity != null) {&#xD;&#xA;                    Intent proxyIntent = new Intent();&#xD;&#xA;  ComponentName componentName = new ComponentName(context, proxyActivity);&#xD;&#xA;  proxyIntent.setComponent(componentName);&#xD;&#xA;  proxyIntent.putExtra(&amp;#34;oldIntent&amp;#34;, intent);&#xD;&#xA;  args[index] = proxyIntent;&#xD;&#xA;  }&#xD;&#xA;            }&#xD;&#xA;&#xD;&#xA;            return method.invoke(iActivityManagerObject, args);&#xD;&#xA;  }&#xD;&#xA;    }&#xD;&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;在Application中的onCreate函数中插桩&lt;/p&gt;</description>
    </item>
    <item>
      <title>RxAndroid学习笔记</title>
      <link>https://gker.net/post/10010/</link>
      <pubDate>Fri, 14 Apr 2017 16:15:15 +0800</pubDate>
      <guid>https://gker.net/post/10010/</guid>
      <description>&lt;p&gt;学习RX的原因各有不同，但是目的都一样，就是学会使用RX。想要学会使用RX，最好理解Rx的编程思想。&lt;/p&gt;&#xA;&lt;p&gt;官方网站：http://reactivex.io/&#xA;官方对RX的解释：ReactiveX is a library for composing asynchronous and event-based programs by using observable sequences.&lt;/p&gt;&#xA;&lt;p&gt;RxJava文档的中文翻译&#xA;&lt;a href=&#34;https://mcxiaoke.gitbooks.io/rxdocs&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;https://mcxiaoke.gitbooks.io/rxdocs&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;比较精华的文章&#xA;&lt;a href=&#34;http://gank.io/post/560e15be2dca930e00da1083&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;《给Android开发者的RxJava详解》 by:扔物线&lt;/a&gt;&#xA;&lt;a href=&#34;http://blog.csdn.net/lzyzsd/article/details/41833541&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;《深入浅出RxJava》 by:大头鬼&lt;/a&gt;&#xA;&lt;a href=&#34;https://segmentfault.com/a/1190000004049490&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;《谜之RxJava》 by:Gemini&lt;/a&gt;&#xA;&lt;a href=&#34;http://www.jianshu.com/p/7fd42c262982&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;《RxJava之旅》 by:Chuckiefan&lt;/a&gt;&#xA;&lt;a href=&#34;http://www.jianshu.com/u/c50b715ccaeb&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;《给初学者的RxJava2.0教程》系列 by:Season_zlc&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;RX官方解释为响应式编程。而Chuckiefan指出理解响应式编程首先要养成一切皆数据流的编程思维、理解异步编程和观察者模式，并将响应式编程与面向过程编程和面向对象编程并列。可见，如果不理解其编程思想，很难熟练运用RX。&lt;/p&gt;&#xA;&lt;p&gt;Season_zlc的水管理论通俗易懂，建议认真阅读。&lt;/p&gt;</description>
    </item>
    <item>
      <title>解决tomcat7经常crash的问题</title>
      <link>https://gker.net/post/10009/</link>
      <pubDate>Wed, 05 Apr 2017 15:52:12 +0800</pubDate>
      <guid>https://gker.net/post/10009/</guid>
      <description>&lt;p&gt;查阅catalina.out日志，发现以下信息，分析为网络爬虫携带的请求头不标准导致解析错误。&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Mar 29, 2017 11:58:18 AM org.apache.coyote.http11.AbstractHttp11Processor process&#xD;&#xA;INFO: Error parsing HTTP request header&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;解决方案：&#xA;在server.xml中,将所有的Connector都添加以下参数：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;maxHttpHeaderSize=&amp;#34;81920&amp;#34;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;别忘了重启tomcat哦。&lt;/p&gt;&#xA;&lt;p&gt;结果：&#xA;目前运行良好。&lt;/p&gt;</description>
    </item>
    <item>
      <title>使用Nginx代理tomcat时获取真正IP</title>
      <link>https://gker.net/post/10008/</link>
      <pubDate>Thu, 30 Mar 2017 12:42:32 +0800</pubDate>
      <guid>https://gker.net/post/10008/</guid>
      <description>&lt;p&gt;修改Nginx配置，增加真正IP的转发。&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;location / { &#xD;&#xA;#其他 &#xD;&#xA;proxy_set_header Host $host; &#xD;&#xA;proxy_set_header X-Real-IP $remote_addr; &#xD;&#xA;proxy_set_header REMOTE-HOST $remote_addr; &#xD;&#xA;proxy_set_header X-Forwarded-For &#xD;&#xA;$proxy_add_x_forwarded_for; &#xD;&#xA;#其他&#xD;&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>Notification播放apk中自带raw音频</title>
      <link>https://gker.net/post/10007/</link>
      <pubDate>Wed, 15 Mar 2017 09:45:54 +0800</pubDate>
      <guid>https://gker.net/post/10007/</guid>
      <description>&lt;ul&gt;&#xA;&lt;li&gt;本场景为自定义Notification的声音&lt;/li&gt;&#xA;&lt;li&gt;根本解决方式是修改notification的sound&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;notification.sound =Uri sound;&#xD;&#xA;//或者&#xD;&#xA;NotificationCompat.Builder.setSound(Uri sound)&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;&#xA;&lt;li&gt;Uri的规范可以参考 &lt;a href=&#34;http://www.ietf.org/rfc/rfc2396.txt&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;http://www.ietf.org/rfc/rfc2396.txt&lt;/a&gt; 以下为示例&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Uri sound=Uri.parse(&amp;#34;android.resource://&amp;#34; + getPackageName() + &amp;#34;/&amp;#34; + R.raw.notificationsound );  &#xD;&#xA;//或者&#xD;&#xA;Uri sound=Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + &amp;#34;://&amp;#34; + getPackageName() + &amp;#34;/raw/notificationsound&amp;#34;); &#xD;&#xA;//或者&#xD;&#xA;Uri sound=Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + &amp;#34;://&amp;#34; + getPackageName() + &amp;#34;/&amp;#34;+R.raw.notificationsound); &#xD;&#xA;//或者从铃声管理器获取 &#xD;&#xA;Uri sound= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;&#xA;&lt;li&gt;也可以将一个无声音的音频文件指定给notification使其静音，然后启用MediaPlayer播放铃声。播放代码如下：&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;try {&#xD;&#xA;  Context context = Application.getInstance();&#xD;&#xA;  MediaPlayer mediaPlayer;&#xD;&#xA;  if (rawId &amp;gt; 0) {&#xD;&#xA;        if (Build.VERSION.SDK_INT &amp;lt; Build.VERSION_CODES.LOLLIPOP) {&#xD;&#xA;            mediaPlayer = MediaPlayer.create(context, rawId);&#xD;&#xA;&#x9;&#x9;} else {&#xD;&#xA;&#x9;&#x9;  int sessionId = ((AudioManager) context.getSystemService(Context.AUDIO_SERVICE)).generateAudioSessionId();&#xD;&#xA;&#x9;&#x9;  AudioAttributes audioAttributes = new AudioAttributes.Builder()&#xD;&#xA;&#x9;&#x9;&#x9;&#x9;  .setUsage(AudioAttributes.USAGE_NOTIFICATION)&#xD;&#xA;&#x9;&#x9;&#x9;&#x9;  .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)&#xD;&#xA;&#x9;&#x9;&#x9;&#x9;  .setLegacyStreamType(AudioManager.STREAM_NOTIFICATION)&#xD;&#xA;&#x9;&#x9;&#x9;&#x9;  .build();&#xD;&#xA;&#x9;&#x9;  mediaPlayer = MediaPlayer.create(context, rawId, audioAttributes, sessionId);&#xD;&#xA;&#x9;&#x9;}&#xD;&#xA;    } else {&#xD;&#xA;        mediaPlayer = MediaPlayer.create(context, RingtoneManager.getActualDefaultRingtoneUri(context, RingtoneManager.TYPE_NOTIFICATION));&#xD;&#xA;    }&#xD;&#xA;&#x9; //使用MediaPlayer.create(context, R.raw.mingdao)这种方式创建的MediaPlayer已经prepare完成，且不能修改AudioStreamType&#xD;&#xA;&#x9; //mediaPlayer.setAudioStreamType(AudioManager.STREAM_ALARM);  &#xD;&#xA;&#x9; mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {&#xD;&#xA;        @Override&#xD;&#xA;&#x9;&#x9;public void onCompletion(MediaPlayer mediaPlayer) {&#xD;&#xA;            mediaPlayer.release();&#xD;&#xA;&#x9;}&#xD;&#xA;    });&#xD;&#xA;&#x9;mediaPlayer.start();&#xD;&#xA;} catch (Exception e) {&#xD;&#xA;    e.printStackTrace();&#xD;&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>Nginx&#43;Tomcat升级HTTPS过程</title>
      <link>https://gker.net/post/10006/</link>
      <pubDate>Sat, 04 Mar 2017 06:32:23 +0800</pubDate>
      <guid>https://gker.net/post/10006/</guid>
      <description>&lt;ul&gt;&#xA;&lt;li&gt;申请一个免费的SSL证书。目前&lt;a href=&#34;https://console.qcloud.com/ssl&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;腾讯云&lt;/a&gt;、&lt;a href=&#34;https://common-buy.aliyun.com/?commodityCode=cas#/buy&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;阿里云&lt;/a&gt;、&lt;a href=&#34;https://cloud.baidu.com/product/cas.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;百度云&lt;/a&gt;、&lt;a href=&#34;https://portal.qiniu.com/ssl?tab=crt&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;七牛云&lt;/a&gt;都提供免费的SSL证书，且都是赛门铁克签发。形式为gker.crt证书和gker.key私钥,用于Nginx。&lt;/li&gt;&#xA;&lt;li&gt;在&lt;a href=&#34;https://www.trustasia.com/tools-cert-converter&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;亚洲诚信&lt;/a&gt;上将此证书转换为jks形式，用于tomcat。&lt;/li&gt;&#xA;&lt;li&gt;打开tomcat的https&#xA;&lt;ul&gt;&#xA;&lt;li&gt;安装&lt;a href=&#34;http://apr.apache.org/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;APR&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;安装SSL-dev库&lt;/li&gt;&#xA;&lt;li&gt;修改tomcat的server.xml文件&#xA;原有被注释的以下内容，取消注释并增加key文件路径。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9; &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;Connector&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;port=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;8443&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;protocol=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;org.apache.coyote.http11.Http11Protocol&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;connectionTimeout=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;20000&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;&#x9;&#x9;  &lt;span style=&#34;color:#a6e22e&#34;&gt;maxThreads=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;150&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;SSLEnabled=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;true&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;scheme=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;https&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;secure=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;true&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;&#x9;&#x9;  &lt;span style=&#34;color:#a6e22e&#34;&gt;clientAuth=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;false&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;sslProtocol=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;TLS&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;&#x9;&#x9;  &lt;span style=&#34;color:#a6e22e&#34;&gt;keystoreFile=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;***.jks&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;&#x9;&#x9;  &lt;span style=&#34;color:#a6e22e&#34;&gt;keystorePass=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;***&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;&#x9;&#x9;  &lt;span style=&#34;color:#f92672&#34;&gt;/&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;  &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;!--关闭默认的SSLEngine--&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;Listener&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;className=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;org.apache.catalina.core.AprLifecycleListener&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;SSLEngine=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;off&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;/&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;&#xA;&lt;li&gt;打开Nginx的https&#xA;&lt;ul&gt;&#xA;&lt;li&gt;修改conf中的server配置&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&#x9;  #新增443端口监听&#xD;&#xA;&#x9;  listen 443 ;&#xD;&#xA;&#x9;  &#xD;&#xA;&#x9;  #修改代理的tomcat端口&#xD;&#xA;&#x9;  location ~ .* {&#xD;&#xA;&#x9;&#x9;proxy_pass https://127.0.0.1:8443 ;&#xD;&#xA;&#x9;  }&#xD;&#xA;&#x9;  &#xD;&#xA;&#x9;  #打开ssl&#xD;&#xA;&#x9;  ssl on ;&#xD;&#xA;&#x9;  &#xD;&#xA;&#x9;  #指定sslkey路径&#xD;&#xA;&#x9;  ssl_certificate /usr/local/nginx/***/gker.crt ;&#xD;&#xA;&#x9;  ssl_certificate_key /usr/local/nginx/***/gker.key ;&#xD;&#xA;&#x9;  &#xD;&#xA;&#x9;  #让http请求重定向到https请求   &#xD;&#xA;&#x9;  error_page 497  https://$host$uri?$args ;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;&#xA;&lt;li&gt;重启tomcat，再重启Nginx即可。&lt;/li&gt;&#xA;&lt;li&gt;期间tomcat可能会报各种错误，仔细排查即可。本文只是主体思路。&lt;/li&gt;&#xA;&lt;/ul&gt;</description>
    </item>
    <item>
      <title>TinyPng压缩资源图片</title>
      <link>https://gker.net/post/10005/</link>
      <pubDate>Fri, 03 Mar 2017 16:43:53 +0800</pubDate>
      <guid>https://gker.net/post/10005/</guid>
      <description>&lt;p&gt;无论在Android还是iOS还是H5等等前端开发中，都少不了对程序体积的考量。其中图片又是体积最大的一块。目前最牛的图片压缩算法掌握在&lt;a href=&#34;https://tinypng.com/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;TinyPng&lt;/a&gt;手里。&lt;/p&gt;&#xA;&lt;h3 id=&#34;使用方法一&#34;&gt;使用方法一 &lt;a href=&#34;#%e4%bd%bf%e7%94%a8%e6%96%b9%e6%b3%95%e4%b8%80&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h3&gt;&lt;ol&gt;&#xA;&lt;li&gt;用浏览器打开&lt;a href=&#34;https://tinypng.com/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;TinyPng&lt;/a&gt;&#xA;&lt;p class=&#34;markdown-image&#34;&gt;&#xD;&#xA;  &lt;img src=&#34;https://cdn.gker.net/f5bed4324f7b4926a0bfb0524d218069.png&#34; alt=&#34;tiny_main.png&#34;  /&gt;&#xD;&#xA;&lt;/p&gt;&lt;/li&gt;&#xA;&lt;li&gt;选择你要压缩的PNG图片或者直接将你要压缩的图片拖拽到网页中间的大框框内。&lt;/li&gt;&#xA;&lt;li&gt;压缩完成，点击download下载即可。&#xA;&lt;p class=&#34;markdown-image&#34;&gt;&#xD;&#xA;  &lt;img src=&#34;https://cdn.gker.net/2679c3fcfeab453bb3d50478e8e3102f.png&#34; alt=&#34;tiny_ok.png&#34;  /&gt;&#xD;&#xA;&lt;/p&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;使用方法二&#34;&gt;使用方法二 &lt;a href=&#34;#%e4%bd%bf%e7%94%a8%e6%96%b9%e6%b3%95%e4%ba%8c&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;购买tinypng出品的&lt;a href=&#34;https://tinypng.com/photoshop&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Photoshop插件&lt;/a&gt;&#xA;此方式适合UI美术人员使用，可以单张导出，也可配合批量插件进行批量处理。&lt;/p&gt;&#xA;&lt;h3 id=&#34;使用方法三&#34;&gt;使用方法三 &lt;a href=&#34;#%e4%bd%bf%e7%94%a8%e6%96%b9%e6%b3%95%e4%b8%89&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;使用**&lt;a href=&#34;https://github.com/meili/TinyPIC_Gradle_Plugin&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;TinyPIC_Gradle_Plugin&lt;/a&gt;**在编译时处理&#xA;此方式适合开发人员使用。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Lambda表达式在Java或Android中入门</title>
      <link>https://gker.net/post/10004/</link>
      <pubDate>Thu, 02 Mar 2017 15:28:32 +0800</pubDate>
      <guid>https://gker.net/post/10004/</guid>
      <description>&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;Lambda&lt;/strong&gt;是java8开始支持的一种语法格式，可以使用更少的代码实现更多功能。&lt;/li&gt;&#xA;&lt;li&gt;其本质与java6等相比，只是语法改变，使用Lambad语法写成的java编译成class后与java6写成的java编译的class无本质区别。由此可见，减少了代码量的同时，也减少了可读性，增加了维护难度。&lt;/li&gt;&#xA;&lt;li&gt;权威的文档可以参考&lt;a href=&#34;http://www.developer.com/java/start-using-java-lambda-expressions.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;此处&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;如果要在java6或者java7中使用Lambda，可以使用&lt;a href=&#34;https://github.com/orfjackal/retrolambda&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;retrolambda&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;如果要在Android中使用Lambda，并且使用gradle构建，可以使用&lt;a href=&#34;https://github.com/evant/gradle-retrolambda&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;gradle-retrolambda&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;hr&gt;&#xA;&lt;p&gt;&lt;strong&gt;Lambda表达式的语法&lt;/strong&gt;&#xA;基本语法:&#xA;&lt;strong&gt;(parameters) -&amp;gt; expression&lt;/strong&gt;&#xA;或&#xA;&lt;strong&gt;(parameters) -&amp;gt;{ statements; }&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;h3 id=&#34;举个栗子&#34;&gt;举个栗子 &lt;a href=&#34;#%e4%b8%be%e4%b8%aa%e6%a0%97%e5%ad%90&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h3&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 1. 不需要参数,返回值为 5  &lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;() &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; 5  &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 2. 接收一个参数(数字类型),返回其2倍的值  &lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;x &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; 2 &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; x  &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 3. 接受2个参数(数字),并返回他们的差值  &lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(x, y) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; x &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;–&lt;/span&gt; y  &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 4. 接收2个int型整数,返回他们的和  &lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; x, &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; y) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; x &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; y  &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)  &lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(String s) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; System.&lt;span style=&#34;color:#a6e22e&#34;&gt;out&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;print&lt;/span&gt;(s)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;匿名内部类的写法&#34;&gt;匿名内部类的写法 &lt;a href=&#34;#%e5%8c%bf%e5%90%8d%e5%86%85%e9%83%a8%e7%b1%bb%e7%9a%84%e5%86%99%e6%b3%95&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h3&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 1.1使用匿名内部类  &lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; Thread(&lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; Runnable() {  &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;@Override&lt;/span&gt;  &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;run&lt;/span&gt;() {  &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        System.&lt;span style=&#34;color:#a6e22e&#34;&gt;out&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;println&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Hello world !&amp;#34;&lt;/span&gt;);  &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }  &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}).&lt;span style=&#34;color:#a6e22e&#34;&gt;start&lt;/span&gt;();  &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 1.2使用 lambda expression  &lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; Thread(() &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; System.&lt;span style=&#34;color:#a6e22e&#34;&gt;out&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;println&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Hello world !&amp;#34;&lt;/span&gt;)).&lt;span style=&#34;color:#a6e22e&#34;&gt;start&lt;/span&gt;();  &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 2.1使用匿名内部类  &lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Runnable race1 &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; Runnable() {  &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;@Override&lt;/span&gt;  &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;run&lt;/span&gt;() {  &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        System.&lt;span style=&#34;color:#a6e22e&#34;&gt;out&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;println&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Hello world !&amp;#34;&lt;/span&gt;);  &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }  &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;};  &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 2.2使用 lambda expression  &lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Runnable race2 &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; () &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; System.&lt;span style=&#34;color:#a6e22e&#34;&gt;out&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;println&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Hello world !&amp;#34;&lt;/span&gt;);  &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 直接调用 run 方法(没开新线程哦!)  &lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;race1.&lt;span style=&#34;color:#a6e22e&#34;&gt;run&lt;/span&gt;();  &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;race2.&lt;span style=&#34;color:#a6e22e&#34;&gt;run&lt;/span&gt;();  &#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    <item>
      <title>Lottie简介</title>
      <link>https://gker.net/post/10003/</link>
      <pubDate>Sun, 26 Feb 2017 18:39:56 +0800</pubDate>
      <guid>https://gker.net/post/10003/</guid>
      <description>&lt;ul&gt;&#xA;&lt;li&gt;7个月前（2016.7）airbnb开源了一款开源动画框架 &lt;strong&gt;&lt;a href=&#34;https://github.com/airbnb/lottie-android&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;lottie&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Lottie&lt;/strong&gt;支持&lt;a href=&#34;https://github.com/airbnb/lottie-android&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Android&lt;/a&gt;、&lt;a href=&#34;https://github.com/airbnb/lottie-ios&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;iOS&lt;/a&gt;、&lt;a href=&#34;https://github.com/airbnb/lottie-react-native&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;ReactNative&lt;/a&gt;三个平台&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Lottie&lt;/strong&gt;官网为&lt;a href=&#34;http://airbnb.design/introducing-lottie/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;http://airbnb.design/&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Lottie&lt;/strong&gt;的作用是把&lt;a href=&#34;https://www.adobe.com/products/aftereffects.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Adobe After Effects&lt;/a&gt;导出的json文件渲染为动画&lt;/li&gt;&#xA;&lt;li&gt;AE导出json时应该使用&lt;a href=&#34;https://github.com/bodymovin/bodymovin&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Bodymovin&lt;/a&gt;插件&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Lottie&lt;/strong&gt;目前支持API 14及以上的系统，早期只支持到API16。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Lottie&lt;/strong&gt;最大的优势就是美术做好的动画，无需工程师用代码再实现一遍了。其体积又比帧动画或gif小很多，大大解放了工程师的劳动力。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;以下是Lottie性能的官方的说明：&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;如果没有mask和mattes，那么性能和内存非常好，没有bitmap创建，大部分操作都是简单的cavas绘制。&lt;/li&gt;&#xA;&lt;li&gt;如果存在mattes，将会创建2～3个bitmap。bitmap在动画加载到window时被创建，被window删除时回收。所以不宜在RecyclerView中使用包涵mattes或者mask的动画，否则会引起bitmap抖动。除了内存抖动，mattes和mask中必要的bitmap.eraseColor()和canvas.drawBitmap()也会降低动画性能。对于简单的动画，在实际使用时性能不太明显。&lt;/li&gt;&#xA;&lt;li&gt;如果在列表中使用动画，推荐使用缓存LottieAnimationView.setAnimation(String, CacheStrategy) 。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;以下是Lottie官方示例效果：&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://github.com/airbnb/lottie-android/blob/master/gifs/Example2.gif&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;p class=&#34;markdown-image&#34;&gt;&#xD;&#xA;  &lt;img src=&#34;https://github.com/airbnb/lottie-android/raw/master/gifs/Example2.gif&#34; alt=&#34;&#34;  /&gt;&#xD;&#xA;&lt;/p&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://github.com/airbnb/lottie-android/blob/master/gifs/Example3.gif&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;p class=&#34;markdown-image&#34;&gt;&#xD;&#xA;  &lt;img src=&#34;https://github.com/airbnb/lottie-android/raw/master/gifs/Example3.gif&#34; alt=&#34;&#34;  /&gt;&#xD;&#xA;&lt;/p&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://github.com/airbnb/lottie-android/blob/master/gifs/Community%202_3.gif&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;p class=&#34;markdown-image&#34;&gt;&#xD;&#xA;  &lt;img src=&#34;https://github.com/airbnb/lottie-android/raw/master/gifs/Community%202_3.gif&#34; alt=&#34;&#34;  /&gt;&#xD;&#xA;&lt;/p&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://github.com/airbnb/lottie-android/blob/master/gifs/Example4.gif&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;p class=&#34;markdown-image&#34;&gt;&#xD;&#xA;  &lt;img src=&#34;https://github.com/airbnb/lottie-android/raw/master/gifs/Example4.gif&#34; alt=&#34;&#34;  /&gt;&#xD;&#xA;&lt;/p&gt;&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Ubuntu安装官方JDK</title>
      <link>https://gker.net/post/10002/</link>
      <pubDate>Sat, 25 Feb 2017 18:39:56 +0800</pubDate>
      <guid>https://gker.net/post/10002/</guid>
      <description>&lt;h1 id=&#34;1删除自带的&#34;&gt;1.删除自带的 &lt;a href=&#34;#1%e5%88%a0%e9%99%a4%e8%87%aa%e5%b8%a6%e7%9a%84&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h1&gt;&lt;h1 id=&#34;2安装oracle官方的&#34;&gt;2.安装Oracle官方的 &lt;a href=&#34;#2%e5%ae%89%e8%a3%85oracle%e5%ae%98%e6%96%b9%e7%9a%84&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;sudo add-apt-repository ppa:webupd8team/java&lt;/p&gt;&#xA;&lt;p&gt;sudo apt-get update&lt;/p&gt;&#xA;&lt;p&gt;sudo apt-get install oracle-java8-installer&lt;/p&gt;&#xA;&lt;h1 id=&#34;3管理jdk&#34;&gt;3.管理JDK &lt;a href=&#34;#3%e7%ae%a1%e7%90%86jdk&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;sudo update-alternatives –config java&lt;/p&gt;</description>
    </item>
    <item>
      <title>Ubuntu更新软件源</title>
      <link>https://gker.net/post/10001/</link>
      <pubDate>Fri, 24 Feb 2017 18:39:56 +0800</pubDate>
      <guid>https://gker.net/post/10001/</guid>
      <description>&lt;h1 id=&#34;1sudo-vi-etcaptsourceslist&#34;&gt;1.sudo vi /etc/apt/sources.list &lt;a href=&#34;#1sudo-vi-etcaptsourceslist&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;deb &lt;a href=&#34;http://mirrors.163.com/ubuntu/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;http://mirrors.163.com/ubuntu/&lt;/a&gt; trusty main restricted universe multiverse&lt;/p&gt;&#xA;&lt;p&gt;deb &lt;a href=&#34;http://mirrors.163.com/ubuntu/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;http://mirrors.163.com/ubuntu/&lt;/a&gt; trusty-security main restricted universe multiverse&lt;/p&gt;&#xA;&lt;p&gt;deb &lt;a href=&#34;http://mirrors.163.com/ubuntu/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;http://mirrors.163.com/ubuntu/&lt;/a&gt; trusty-updates main restricted universe multiverse&lt;/p&gt;&#xA;&lt;p&gt;deb &lt;a href=&#34;http://mirrors.163.com/ubuntu/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;http://mirrors.163.com/ubuntu/&lt;/a&gt; trusty-proposed main restricted universe multiverse&lt;/p&gt;&#xA;&lt;p&gt;deb &lt;a href=&#34;http://mirrors.163.com/ubuntu/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;http://mirrors.163.com/ubuntu/&lt;/a&gt; trusty-backports main restricted universe multiverse&lt;/p&gt;&#xA;&lt;p&gt;deb-src &lt;a href=&#34;http://mirrors.163.com/ubuntu/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;http://mirrors.163.com/ubuntu/&lt;/a&gt; trusty main restricted universe multiverse&lt;/p&gt;&#xA;&lt;p&gt;deb-src &lt;a href=&#34;http://mirrors.163.com/ubuntu/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;http://mirrors.163.com/ubuntu/&lt;/a&gt; trusty-security main restricted universe multiverse&lt;/p&gt;&#xA;&lt;p&gt;deb-src &lt;a href=&#34;http://mirrors.163.com/ubuntu/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;http://mirrors.163.com/ubuntu/&lt;/a&gt; trusty-updates main restricted universe multiverse&lt;/p&gt;&#xA;&lt;p&gt;deb-src &lt;a href=&#34;http://mirrors.163.com/ubuntu/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;http://mirrors.163.com/ubuntu/&lt;/a&gt; trusty-proposed main restricted universe multiverse&lt;/p&gt;&#xA;&lt;p&gt;deb-src &lt;a href=&#34;http://mirrors.163.com/ubuntu/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;http://mirrors.163.com/ubuntu/&lt;/a&gt; trusty-backports main restricted universe multiverse&lt;/p&gt;&#xA;&lt;h1 id=&#34;2sudo-apt-get-update&#34;&gt;2.sudo apt-get update &lt;a href=&#34;#2sudo-apt-get-update&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h1&gt;</description>
    </item>
    <item>
      <title>初衷</title>
      <link>https://gker.net/post/10000/</link>
      <pubDate>Wed, 01 Aug 2007 13:51:14 +0800</pubDate>
      <guid>https://gker.net/post/10000/</guid>
      <description>&lt;h1 id=&#34;个人记录网建设初衷&#34;&gt;个人记录网建设初衷 &lt;a href=&#34;#%e4%b8%aa%e4%ba%ba%e8%ae%b0%e5%bd%95%e7%bd%91%e5%bb%ba%e8%ae%be%e5%88%9d%e8%a1%b7&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h1&gt;&lt;ul&gt;&#xA;&lt;li&gt;自2007年毕业工作以来，起初使用notepad记录工作心得。&lt;/li&gt;&#xA;&lt;li&gt;2008年伊始，对比了多家博客，采用百度空间开始记录博客，可惜百度空间于2012年关闭。&lt;/li&gt;&#xA;&lt;li&gt;2012-2017年期间使用印象笔记,可惜其较为封闭，不方便共享于众网友同仁。&lt;/li&gt;&#xA;&lt;li&gt;2017年开始了，鉴于百度空间关闭的前车之鉴，所以自建博客，用以共勉。&lt;/li&gt;&#xA;&lt;li&gt;2020年了，改用hugo，使用静态网站。&lt;/li&gt;&#xA;&lt;/ul&gt;</description>
    </item>
  </channel>
</rss>
