-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsearch.xml
336 lines (321 loc) · 92.9 KB
/
search.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title><![CDATA[InterfaceDoc]]></title>
<url>http://kippies.cn/2016/11/13/InterfaceDoc/</url>
<content type="html"><![CDATA[<h1 id="接口文档"><a href="#接口文档" class="headerlink" title="接口文档"></a>接口文档</h1><h2 id="请求地址"><a href="#请求地址" class="headerlink" title="请求地址"></a>请求地址</h2><blockquote>
<p>base url =?</p>
</blockquote>
<a id="more"></a>
<h2 id="Header、UA"><a href="#Header、UA" class="headerlink" title="Header、UA"></a>Header、UA</h2><blockquote>
<p>encode : UTF-8;<br>UA: eg. appName + versionName + os + osVersion + versionCode + manufacturer + module<br>参数在拿不到的情况下传 Unknown</p>
</blockquote>
<table>
<thead>
<tr>
<th>参数名称</th>
<th style="text-align:center">类型</th>
<th style="text-align:right">说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>x-user-id</td>
<td style="text-align:center">string</td>
<td style="text-align:right">用户ID</td>
</tr>
<tr>
<td>x-version-name</td>
<td style="text-align:center">string</td>
<td style="text-align:right">App版本名称 eg. 1.0.0</td>
</tr>
<tr>
<td>x-version-code</td>
<td style="text-align:center">string</td>
<td style="text-align:right">App版本号 eg. 666</td>
</tr>
<tr>
<td>x-channel</td>
<td style="text-align:center">string</td>
<td style="text-align:right">渠道号 eg. xiaomi</td>
</tr>
<tr>
<td>x-manufacturer</td>
<td style="text-align:center">string</td>
<td style="text-align:right">设备厂商 eg. 华为</td>
</tr>
<tr>
<td>x-model</td>
<td style="text-align:center">string</td>
<td style="text-align:right">设备型号 eg. Meta8</td>
</tr>
<tr>
<td>x-os</td>
<td style="text-align:center">string</td>
<td style="text-align:right">系统类型 eg. iOS</td>
</tr>
<tr>
<td>x-os-version</td>
<td style="text-align:center">string</td>
<td style="text-align:right">系统版本号 eg. 5.1</td>
</tr>
<tr>
<td>x-screen-height</td>
<td style="text-align:center">string</td>
<td style="text-align:right">屏幕高度 eg. 1920</td>
</tr>
<tr>
<td>x-screen-width</td>
<td style="text-align:center">string</td>
<td style="text-align:right">屏幕宽度 eg. 1080</td>
</tr>
<tr>
<td>x-app-timezone</td>
<td style="text-align:center">string</td>
<td style="text-align:right">时区 eg. Asia/Shanghai</td>
</tr>
<tr>
<td>User-Agent</td>
<td style="text-align:center">string</td>
<td style="text-align:right">UA</td>
</tr>
</tbody>
</table>
<h2 id="基本数据格式"><a href="#基本数据格式" class="headerlink" title="基本数据格式"></a>基本数据格式</h2><blockquote>
<p>ec: 状态码,非200,全部认为是失败,会处理特定的错误码 eg. 10001 : token 失效;<br>em: 提示信息;<br>客户端会优先处理em,当em有内容时,不对ec做处理;<br>data:obj{} 或者 arr[];</p>
</blockquote>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">[</span><br><span class="line"> <span class="string">"ec"</span>: <span class="number">200</span>,</span><br><span class="line"> <span class="string">"em"</span>: <span class="string">""</span>,</span><br><span class="line"> <span class="string">"data"</span>: {}</span><br><span class="line">]</span><br></pre></td></tr></table></figure>
<h2 id="登录"><a href="#登录" class="headerlink" title="登录"></a>登录</h2><blockquote>
<p>POST /login</p>
</blockquote>
<h3 id="Request"><a href="#Request" class="headerlink" title="Request"></a>Request</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">{</span><br><span class="line"> <span class="string">"userName"</span>:<span class="string">"a88dfa9v61ns2"</span>,</span><br><span class="line"> <span class="string">"psw"</span>:<span class="string">"a893l1jf3076c"</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h3 id="Response"><a href="#Response" class="headerlink" title="Response"></a>Response</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">[</span><br><span class="line"> <span class="string">"ec"</span>: <span class="number">200</span>,</span><br><span class="line"> <span class="string">"em"</span>: <span class="string">"success"</span>,</span><br><span class="line"> <span class="string">"data"</span>: {</span><br><span class="line"> <span class="string">"userId"</span>:<span class="string">"a88dfa9v61ns2"</span>,</span><br><span class="line"> <span class="string">"nickName"</span>:<span class="string">"喷塔Q"</span>,</span><br><span class="line"> <span class="string">"avatar"</span>:<span class="string">"https://7niu.ab.com/a8888.png"</span>,</span><br><span class="line"> <span class="string">"mobile"</span>:<span class="string">"18866668888"</span>,</span><br><span class="line"> <span class="string">"gender"</span>:<span class="string">"M/F"</span></span><br><span class="line"> <span class="string">"token"</span>:<span class="string">"fdljlRldkJjlskjdfls"</span>, <span class="comment">// 调用一次登录接口,重新生成token</span></span><br><span class="line"> }</span><br><span class="line">]</span><br></pre></td></tr></table></figure>
]]></content>
</entry>
<entry>
<title><![CDATA[Android使用Google Breakpad进行崩溃日志管理]]></title>
<url>http://kippies.cn/2016/07/10/Android%E4%BD%BF%E7%94%A8Google-Breakpad%E8%BF%9B%E8%A1%8C%E5%B4%A9%E6%BA%83%E6%97%A5%E5%BF%97%E7%AE%A1%E7%90%86/</url>
<content type="html"><![CDATA[<ul>
<li>开发过程中,最担心的问题就是程序崩溃,而且还不知道崩溃的原因,现在使用Google Breakpad来跟踪崩溃的位置,非常方便;由于目前使用Mac系统开发,Google Breadpad处理Android崩溃日志时需要Linux环境,借助 vagrant 可以非常方便地在Mac使用Ubuntu环境。</li>
</ul>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">$ varant ssh</span><br><span class="line">$ cd /vagrant</span><br><span class="line">$ sudo apt-get update</span><br><span class="line">$ sudo apt-get install build-essential</span><br><span class="line">$ svn checkout http:<span class="comment">//google-breakpad.googlecode.com/svn/trunk/ google-breakpad-read-only</span></span><br><span class="line">$ cd google-breakpad-read-only</span><br><span class="line">$ ./configure</span><br><span class="line">$ make</span><br></pre></td></tr></table></figure>
<p>执行完上面的命令将会在<code>google-breakpad-read-only/src/processor</code>目录下生成<code>minidump_stackwalk</code>工具,用于导出crash log.<br><code>google-breakpad-read-only/src/tools/linux/dump_syms</code>目录下生成 dump_syms工具,用于导出符号文件。<br><code>google-breakpad-read-only/src/client/linux</code> 目录下生成 libbreakpad_client.a。</p>
<a id="more"></a>
<ul>
<li>如果编译遇到 <code>“cc1plus: warnings being treated as errors“</code>错误,请将<code>google-breakpad-read-only/Makefile</code>文件中<code>"* -Werror* "</code>删除,重新编译。</li>
<li>如果make的时候遇到 “/lib64/libc.so.6: version `GLIBC_2.14’ not found “错误,说明 glibc 没有安装,安装方法请移步:<a href="http://my.oschina.net/zhangxu0512/blog/262275" target="_blank" rel="external">http://my.oschina.net/zhangxu0512/blog/262275</a></li>
</ul>
<h4 id="集成-google-breakpad到Android项目中"><a href="#集成-google-breakpad到Android项目中" class="headerlink" title="集成 google-breakpad到Android项目中"></a>集成 google-breakpad到Android项目中</h4><h5 id="添加google-beakpad代码:"><a href="#添加google-beakpad代码:" class="headerlink" title="添加google-beakpad代码:"></a>添加google-beakpad代码:</h5><ul>
<li><p>方法一:</p>
<ul>
<li>拷贝 <code>libbreakpad_client.a</code> 到 jni 目录下。</li>
<li>打开android项目的 Android.mk文件,在 LOCAL_PATH := $(call my-dir) 下加入如下代码:</li>
</ul>
</li>
</ul>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">include $(CLEAR_VARS) </span><br><span class="line">LOCAL_MODULE := breakpad_client </span><br><span class="line">LOCAL_MODULE_FILENAME := breakpad_client </span><br><span class="line">LOCAL_SRC_FILES := libbreakpad_client.a </span><br><span class="line">include $(PREBUILT_STATIC_LIBRARY)</span><br></pre></td></tr></table></figure>
<ul>
<li>方法二:</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$(call <span class="keyword">import</span>-<span class="keyword">module</span>,google-breakpad-read-only/android/google_breakpad)</span><br></pre></td></tr></table></figure>
<ul>
<li><p>方法三: </p>
<ul>
<li>将 google-breakpad 源代码里面的src文件夹拷贝到项目的jni目录下;</li>
<li><p>修改Android.mk文件:</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"> LOCAL_PATH := $(call my-dir)</span><br><span class="line"> include $(CLEAR_VARS)</span><br><span class="line"> LOCAL_MODULE := breakpad_client</span><br><span class="line"> LOCAL_CPP_EXTENSION := .cc .cpp</span><br><span class="line"> LOCAL_ARM_MODE := arm</span><br><span class="line"> LOCAL_SRC_FILES := \</span><br><span class="line"> main.cpp \</span><br><span class="line"> src/client/linux/crash_generation/crash_generation_client.cc \</span><br><span class="line"> src/client/linux/handler/exception_handler.cc \</span><br><span class="line"> src/client/linux/handler/minidump_descriptor.cc \</span><br><span class="line"> src/client/linux/<span class="built_in">log</span>/<span class="built_in">log</span>.cc \</span><br><span class="line"> src/client/linux/minidump_writer/linux_dumper.cc \</span><br><span class="line"> src/client/linux/minidump_writer/linux_ptrace_dumper.cc \</span><br><span class="line"> src/client/linux/minidump_writer/minidump_writer.cc \</span><br><span class="line"> src/client/linux/microdump_writer/microdump_writer.cc \</span><br><span class="line"> src/client/linux/dump_writer_common/ucontext_reader.cc \</span><br><span class="line"> src/client/linux/dump_writer_common/seccomp_unwinder.cc \</span><br><span class="line"> src/client/linux/dump_writer_common/thread_info.cc \</span><br><span class="line"> src/client/minidump_file_writer.cc \</span><br><span class="line"> src/common/android/breakpad_getcontext.S \</span><br><span class="line"> src/common/convert_UTF.c \</span><br><span class="line"> src/common/md5.cc \</span><br><span class="line"> src/common/string_conversion.cc \</span><br><span class="line"> src/common/linux/elfutils.cc \</span><br><span class="line"> src/common/linux/file_id.cc \</span><br><span class="line"> src/common/linux/guid_creator.cc \</span><br><span class="line"> src/common/linux/linux_libc_support.cc \</span><br><span class="line"> src/common/linux/memory_mapped_file.cc \</span><br><span class="line"> src/common/linux/safe_readlink.cc</span><br><span class="line">LOCAL_C_INCLUDES := $(LOCAL_PATH)/src/common/android/include \</span><br><span class="line"> $(LOCAL_PATH)/src </span><br><span class="line">LOCAL_C_INCLUDES += $(NDK_ROOT)/sources/cxx-stl/stlport/stlport</span><br><span class="line">LOCAL_EXPORT_C_INCLUDES := $(LOCAL_C_INCLUDES)</span><br><span class="line">LOCAL_EXPORT_LDLIBS := -llog</span><br><span class="line">LOCAL_LDLIBS := -llog</span><br><span class="line">LOCAL_LDLIBS += $(NDK_ROOT)/sources/cxx-stl/stlport/libs/armeabi/libstlport_static.a</span><br><span class="line">include $(BUILD_SHARED_LIBRARY)</span><br></pre></td></tr></table></figure>
</li>
</ul>
</li>
</ul>
<h5 id="加入对googole-breakpad的引用:"><a href="#加入对googole-breakpad的引用:" class="headerlink" title="加入对googole-breakpad的引用:"></a>加入对googole-breakpad的引用:</h5><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">LOCAL_WHOLE_STATIC_LIBRARIES += breakpad_client</span><br></pre></td></tr></table></figure>
<h5 id="包含搜索路径:"><a href="#包含搜索路径:" class="headerlink" title="包含搜索路径:"></a>包含搜索路径:</h5><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$GOOGLE_BREAKPAD_PATH/src </span><br><span class="line">$GOOGLE_BREAKPAD_PATH/src/common/android/include</span><br></pre></td></tr></table></figure>
<hr>
<pre><code>本文使用的是第三种集成方法。
</code></pre><h4 id="添加google-breakpad-的-c-代码:"><a href="#添加google-breakpad-的-c-代码:" class="headerlink" title="添加google breakpad 的 c++代码:"></a>添加google breakpad 的 c++代码:</h4><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><jni.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><time.h></span> </span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><stdlib.h></span> </span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="string">"com_test_crash_TestCrash.h"</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="string">"client/linux/handler/exception_handler.h"</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="string">"client/linux/handler/minidump_descriptor.h"</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="string">"log.h"</span></span></span><br><span class="line"></span><br><span class="line">google_breakpad::ExceptionHandler* exceptionHandler;</span><br><span class="line"></span><br><span class="line">JavaVM *jvm = <span class="literal">NULL</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">onNativeCrash</span><span class="params">(<span class="keyword">const</span> <span class="keyword">char</span>* info)</span> </span>{</span><br><span class="line"> JNIEnv *env = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">int</span> result = jvm->GetEnv((void **) &env, JNI_VERSION_1_6);</span><br><span class="line"> <span class="keyword">if</span> (result != JNI_OK) {</span><br><span class="line"> LOGE(<span class="string">"%s"</span>, <span class="string">"jvm->GetEnv null"</span>);</span><br><span class="line"> return;</span><br><span class="line"> }</span><br><span class="line"> jclass crashPinClass = env->FindClass(</span><br><span class="line"> <span class="string">"com/test/crash/TestCrash"</span>);</span><br><span class="line"> <span class="keyword">if</span> (crashPinClass == <span class="literal">NULL</span>) {</span><br><span class="line"> LOGE(<span class="string">"%s"</span>, <span class="string">"FindClass com/test/crash/TestCrash null"</span>);</span><br><span class="line"> return;</span><br><span class="line"> }</span><br><span class="line"> jmethodID crashReportMethod = env->GetStaticMethodID(crashPinClass,</span><br><span class="line"> <span class="string">"onNativeCrash"</span>, <span class="string">"(Ljava/lang/String;)V"</span>);</span><br><span class="line"> <span class="keyword">if</span> (crashReportMethod == <span class="literal">NULL</span>) {</span><br><span class="line"> LOGE(<span class="string">"%s"</span>, <span class="string">"GetMethod onNativeCrash null"</span>);</span><br><span class="line"> return;</span><br><span class="line"> }</span><br><span class="line"> jstring crashInfo = env->NewStringUTF(info);</span><br><span class="line"> env->CallStaticVoidMethod(crashPinClass, crashReportMethod, crashInfo);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 崩溃回调</span></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">DumpCallback</span><span class="params">(<span class="keyword">const</span> google_breakpad::MinidumpDescriptor& descriptor,</span><br><span class="line"> <span class="keyword">void</span>* context, <span class="keyword">bool</span> succeeded)</span> </span>{</span><br><span class="line"> LOGE(<span class="string">"Dump path: %s\n"</span>, descriptor.path());</span><br><span class="line"> onNativeCrash(<span class="string">""</span>);</span><br><span class="line"> return succeeded;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">extern</span> <span class="string">"C"</span> <span class="function">jint <span class="title">JNI_OnLoad</span><span class="params">(JavaVM *vm, <span class="keyword">void</span>* <span class="comment">/*reserved*/</span>)</span> </span>{</span><br><span class="line"> LOGE(<span class="string">"JNI_OnLoad"</span>);</span><br><span class="line"> jvm = vm;</span><br><span class="line"> return JNI_VERSION_1_6;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">ifdef</span> __cplusplus</span></span><br><span class="line"><span class="keyword">extern</span> <span class="string">"C"</span> {</span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 通过java代码调用initial()方法传人dmp文件保存的路径</span></span><br><span class="line"><span class="function">JNIEXPORT <span class="keyword">void</span> JNICALL <span class="title">Java_com_test_crash_TestCrash_initial</span><span class="params">(JNIEnv* env, jobject obj, jstring filepath)</span> </span>{</span><br><span class="line"> LOGE(<span class="string">"The Momo native crash initial."</span>);</span><br><span class="line"> <span class="keyword">const</span> <span class="keyword">char</span> *path = env->GetStringUTFChars(filepath, <span class="number">0</span>);</span><br><span class="line"> google_breakpad::<span class="function">MinidumpDescriptor <span class="title">descriptor</span><span class="params">(path)</span></span>;</span><br><span class="line"> exceptionHandler = new google_breakpad::ExceptionHandler(descriptor, NULL, DumpCallback, NULL,</span><br><span class="line"> true, <span class="number">-1</span>);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// native crash 测试代码</span></span><br><span class="line"><span class="function">JNIEXPORT <span class="keyword">void</span> JNICALL <span class="title">Java_com_test_crash_TestCrash_crash</span><span class="params">(JNIEnv *,</span><br><span class="line"> jobject)</span> </span>{</span><br><span class="line"> LOGE(<span class="string">"The test native crash."</span>);</span><br><span class="line"> <span class="keyword">volatile</span> <span class="keyword">int</span>* a = (int*)(NULL);</span><br><span class="line"> *a = <span class="number">1</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">ifdef</span> __cplusplus</span></span><br><span class="line">}</span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span></span></span><br></pre></td></tr></table></figure>
<h4 id="编译C-代码成-so文件(步骤略),通过加载libbreakpad-client-so,调用initial-初始化之后,就开始崩溃捕获。"><a href="#编译C-代码成-so文件(步骤略),通过加载libbreakpad-client-so,调用initial-初始化之后,就开始崩溃捕获。" class="headerlink" title="编译C++代码成.so文件(步骤略),通过加载libbreakpad_client.so,调用initial()初始化之后,就开始崩溃捕获。"></a>编译C++代码成.so文件(步骤略),通过加载libbreakpad_client.so,调用initial()初始化之后,就开始崩溃捕获。</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">TestCrash</span> </span>{</span><br><span class="line"> <span class="comment">// 加载动态链接库(加载.so最好放在application中)</span></span><br><span class="line"> <span class="keyword">static</span> {</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> System.loadLibrary(<span class="string">"breakpad_client"</span>);</span><br><span class="line"> } <span class="keyword">catch</span> (Error e) {</span><br><span class="line"> e.printStackTrace();</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 初始化</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">native</span> <span class="keyword">void</span> <span class="title">initial</span><span class="params">(String filePath)</span></span>;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// native crash测试代码方法</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">native</span> <span class="keyword">void</span> <span class="title">crash</span><span class="params">()</span></span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h4 id="解析生成的dmp文件:"><a href="#解析生成的dmp文件:" class="headerlink" title="解析生成的dmp文件:"></a>解析生成的dmp文件:</h4><ul>
<li>回到ubuntu环境,建立一个Dump目录:</li>
</ul>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ mkdir Dump</span><br></pre></td></tr></table></figure>
<p>分别将生成的.dmp文件、minidump_stackwalk、dump_syms、android项目下的obj/local/armeabi/libxxx.so库拷贝到Dump目录。</p>
<ul>
<li><p>特别说明:libxxx.so文件必须是obj/local/armeabi/ 文件夹下的,这个里面so文件包含了debug信息,相对lib下的so文件来说体积很大,有可能上百兆。</p>
</li>
<li><p>创建好的Dump文件夹路径在“个人 —> ubuntu —> Dump”;</p>
</li>
</ul>
<h4 id="执行生成符号文件命令:"><a href="#执行生成符号文件命令:" class="headerlink" title="执行生成符号文件命令:"></a>执行生成符号文件命令:</h4><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ cd /Dump </span><br><span class="line">$ dump_syms libxxx.so > libxxx.so.sym</span><br></pre></td></tr></table></figure>
<ul>
<li>查看libxxx.so.sym文件内容,头部会有,<code>BB0351B14DDA42A6D36FA6EA358B49D50</code> 这样的字符串:</li>
</ul>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ head -n1 libxxx.so.sym</span><br><span class="line">MODULE Linux arm BB0351B14DDA42A6D36FA6EA358B49D50 libxxx.so</span><br></pre></td></tr></table></figure>
<h4 id="继续执行命令:"><a href="#继续执行命令:" class="headerlink" title="继续执行命令:"></a>继续执行命令:</h4><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ mkdir -p symbols/libxxx.so/BB0351B14DDA42A6D36FA6EA358B49D50/ </span><br><span class="line">$ mv libxxx.so.sym symbols/libxxx.so/BB0351B14DDA42A6D36FA6EA358B49D50/</span><br></pre></td></tr></table></figure>
<ul>
<li>导出崩溃堆栈信息文件( 确保.dmp文件和 symbols目录是同级的 ):</li>
</ul>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ ./minidump_stackwalk filename.dmp symbols > crashed.<span class="built_in">log</span></span><br></pre></td></tr></table></figure>
<h3 id="打开-crashed-log-文件:"><a href="#打开-crashed-log-文件:" class="headerlink" title="打开 crashed.log 文件:"></a>打开 crashed.log 文件:</h3><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">Thread <span class="number">0</span> (crashed)</span><br><span class="line"> <span class="number">0</span> libxxx.so!Java_com_test_crash_TestCrash [TestCrash.cpp : <span class="number">68</span> + <span class="number">0x8</span>]</span><br><span class="line"> r0 = <span class="number">0x00000027</span> r1 = <span class="number">0xc3dab5eb</span> r2 = <span class="number">0x00000001</span> r3 = <span class="number">0x00000000</span></span><br><span class="line"> r4 = <span class="number">0x0000026a</span> r5 = <span class="number">0x12f99f20</span> r6 = <span class="number">0x12d63e00</span> r7 = <span class="number">0x75c4a1b0</span></span><br><span class="line"> r8 = <span class="number">0x1302b9e0</span> r9 = <span class="number">0xb4f07800</span> r10 = <span class="number">0x0000003a</span> r12 = <span class="number">0xb6e98929</span></span><br><span class="line"> fp = <span class="number">0x0000003a</span> sp = <span class="number">0xbebb8f58</span> lr = <span class="number">0xa289aafc</span> pc = <span class="number">0xa289ab04</span></span><br></pre></td></tr></table></figure>
<ul>
<li>[TestCrash.cpp : 68 + 0x8]:定位到TestCrash.cpp的 第68行,从左到右第8个字符 ,产生的崩溃。<h3 id="如果没有生成符号文件,则-crashed-log-文件中的信息如下:"><a href="#如果没有生成符号文件,则-crashed-log-文件中的信息如下:" class="headerlink" title="如果没有生成符号文件,则 crashed.log 文件中的信息如下:"></a>如果没有生成符号文件,则 crashed.log 文件中的信息如下:</h3></li>
</ul>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"> Thread <span class="number">0</span> (crashed) </span><br><span class="line"> <span class="number">0</span> libxxx.so + <span class="number">0xa289ab04</span> </span><br><span class="line"> r0 = <span class="number">0x00000027</span> r1 = <span class="number">0xc3dab5eb</span> r2 = <span class="number">0x00000001</span> r3 = <span class="number">0x00000000</span> </span><br><span class="line"> r4 = <span class="number">0x0000026a</span> r5 = <span class="number">0x12f99f20</span> r6 = <span class="number">0x12d63e00</span> r7 = <span class="number">0x75c4a1b0</span> </span><br><span class="line"> r8 = <span class="number">0x1302b9e0</span> r9 = <span class="number">0xb4f07800</span> r10 = <span class="number">0x0000003a</span> r12 = <span class="number">0xb6e98929</span> </span><br><span class="line"> fp = <span class="number">0x0000003a</span> sp = <span class="number">0xbebb8f58</span> lr = <span class="number">0xa289aafc</span> pc = <span class="number">0xa289ab04</span></span><br><span class="line">``` </span><br><span class="line"></span><br><span class="line">* 通过上面的信息,我们没办法直观的看出哪里导致的崩溃,所以需要使用NDK中的`arm-linux-androideabi-addr2line` 工具定位崩溃;</span><br><span class="line">* `arm-linux-androideabi-addr2line` 路径为:`$NDK_ROOT/toolchains/arm-linux-androideabi<span class="number">-4.8</span>/prebuilt/darwin-x86/bin/arm-linux-androideabi-addr2line`</span><br><span class="line">* usage: `arm-linux-androideabi-addr2line -C -f -e <库路径> <内存地址>`</span><br><span class="line"></span><br><span class="line">``` C++</span><br><span class="line">arm-linux-androideabi-addr2line -C -f -e project/test/obj/local/armeabi/libxxx.so <span class="number">0xa289ab04</span></span><br></pre></td></tr></table></figure>
<ul>
<li>这时候就可以在终端中看到是 libxxx.so 中的哪个文件的那一行发生异常了,接下来可以使用日志追踪有问题的代码了。</li>
</ul>
<hr>
<ul>
<li>参考:<a href="http://blog.linguofeng.com/archive/2014/04/02/google-breakpad-android.html" target="_blank" rel="external">http://blog.linguofeng.com/archive/2014/04/02/google-breakpad-android.html</a></li>
</ul>
]]></content>
</entry>
<entry>
<title><![CDATA[OS X下使用vagrant安装ubuntu环境]]></title>
<url>http://kippies.cn/2016/07/10/OS-X%E4%B8%8B%E4%BD%BF%E7%94%A8vagrant%E5%AE%89%E8%A3%85ubuntu%E7%8E%AF%E5%A2%83/</url>
<content type="html"><![CDATA[<h4 id="安装brew命令工具"><a href="#安装brew命令工具" class="headerlink" title="安装brew命令工具"></a>安装brew命令工具</h4><pre><code>* github:https://github.com/phinze/homebrew-cask
</code></pre><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">$ ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)"</span><br><span class="line">``` </span><br><span class="line">#### 安装 wget 命令工具</span><br><span class="line"></span><br><span class="line"> 查看要安装的版本 http://ftp.gnu.org/gnu/wget/</span><br><span class="line"></span><br><span class="line">#### 下载 wget</span><br><span class="line"></span><br><span class="line">``` java</span><br><span class="line">$ cd ~/Downloads </span><br><span class="line">$ curl -O http://ftp.gnu.org/gnu/wget/wget-1.15.tar.gz</span><br></pre></td></tr></table></figure>
<h4 id="解压-wget"><a href="#解压-wget" class="headerlink" title="解压 wget"></a>解压 wget</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ tar -zxvf wget-<span class="number">1.15</span>.tar.gz</span><br></pre></td></tr></table></figure>
<h4 id="编译和安装"><a href="#编译和安装" class="headerlink" title="编译和安装"></a>编译和安装</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">$ cd wget-<span class="number">1.15</span>/ </span><br><span class="line">$ ./configure --with-ssl=openssl </span><br><span class="line">$ make </span><br><span class="line">$ sudo make install</span><br></pre></td></tr></table></figure>
<a id="more"></a>
<h4 id="清理源文件"><a href="#清理源文件" class="headerlink" title="清理源文件"></a>清理源文件</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ rm -rf ~/Downloads/wget*</span><br></pre></td></tr></table></figure>
<h4 id="使用vagrant安装ubuntu环境"><a href="#使用vagrant安装ubuntu环境" class="headerlink" title="使用vagrant安装ubuntu环境"></a>使用vagrant安装ubuntu环境</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ brew tap phinze/cask </span><br><span class="line">$ brew install brew-cask</span><br></pre></td></tr></table></figure>
<h4 id="安装vagrant与virtualbox"><a href="#安装vagrant与virtualbox" class="headerlink" title="安装vagrant与virtualbox"></a>安装vagrant与virtualbox</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ brew cask install vagrant </span><br><span class="line">$ brew cask install virtualbox</span><br></pre></td></tr></table></figure>
<h4 id="下载ubuntu的box"><a href="#下载ubuntu的box" class="headerlink" title="下载ubuntu的box"></a>下载ubuntu的box</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$ mkdir ubuntu </span><br><span class="line">$ cd ubuntu </span><br><span class="line">$ wget http:<span class="comment">//files.vagrantup.com/precise32.box</span></span><br></pre></td></tr></table></figure>
<h4 id="创建与初始化ubuntu-box"><a href="#创建与初始化ubuntu-box" class="headerlink" title="创建与初始化ubuntu box"></a>创建与初始化ubuntu box</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ vagrant box add ubuntu ./precise32.box </span><br><span class="line">$ vagrant init ubuntu</span><br></pre></td></tr></table></figure>
<h4 id="接下来就可以使用ssh登录了"><a href="#接下来就可以使用ssh登录了" class="headerlink" title="接下来就可以使用ssh登录了"></a>接下来就可以使用ssh登录了</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ vagrant up </span><br><span class="line">$ vagrant ssh</span><br></pre></td></tr></table></figure>
<h4 id="进入ubuntu目录"><a href="#进入ubuntu目录" class="headerlink" title="进入ubuntu目录"></a>进入ubuntu目录</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cd /vagrant/ubuntu</span><br></pre></td></tr></table></figure>
<h4 id="接下来就可以在linux环境下进行编译了。"><a href="#接下来就可以在linux环境下进行编译了。" class="headerlink" title="接下来就可以在linux环境下进行编译了。"></a>接下来就可以在linux环境下进行编译了。</h4><ul>
<li>参考:<a href="http://segmentfault.com/a/1190000000264347" target="_blank" rel="external">http://segmentfault.com/a/1190000000264347</a></li>
</ul>
]]></content>
</entry>
<entry>
<title><![CDATA[Android输入框EditiText禁止输入Emoji表情符]]></title>
<url>http://kippies.cn/2016/07/10/Android%E8%BE%93%E5%85%A5%E6%A1%86EditiText%E7%A6%81%E6%AD%A2%E8%BE%93%E5%85%A5Emoji%E8%A1%A8%E6%83%85%E7%AC%A6/</url>
<content type="html"><![CDATA[<ol>
<li><p>通过添加EditText的addTextChangedListener()监听来过滤Emoji表情:</p>
<ul>
<li>onTextChanged()</li>
<li>beforeTextChanged()</li>
</ul>
</li>
<li><p>使用方法</p>
<ul>
<li>在开发中可能多处会用到过滤Emoji表情符,为了方便使用自定义EditText来实现:</li>
</ul>
</li>
</ol>
<p><img src="http://img.blog.csdn.net/20150430101855832" alt="输入"><br><img src="http://img.blog.csdn.net/20150430101911416" alt="结果"></p>
<a id="more"></a>
<p>以下是余下全文</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.liujy.ui.wiget;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> android.content.Context;</span><br><span class="line"><span class="keyword">import</span> android.text.Editable;</span><br><span class="line"><span class="keyword">import</span> android.text.Selection;</span><br><span class="line"><span class="keyword">import</span> android.text.Spannable;</span><br><span class="line"><span class="keyword">import</span> android.text.TextWatcher;</span><br><span class="line"><span class="keyword">import</span> android.util.AttributeSet;</span><br><span class="line"><span class="keyword">import</span> android.widget.EditText;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ContainsEmojiEditText</span> <span class="keyword">extends</span> <span class="title">EditText</span> </span>{</span><br><span class="line"> <span class="comment">//输入表情前的光标位置</span></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">int</span> cursorPos;</span><br><span class="line"> <span class="comment">//输入表情前EditText中的文本</span></span><br><span class="line"> <span class="keyword">private</span> String inputAfterText;</span><br><span class="line"> <span class="comment">//是否重置了EditText的内容</span></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">boolean</span> resetText;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">private</span> Context mContext;</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">ContainsEmojiEditText</span><span class="params">(Context context)</span> </span>{</span><br><span class="line"> <span class="keyword">super</span>(context);</span><br><span class="line"> <span class="keyword">this</span>.mContext = context;</span><br><span class="line"> initEditText();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">ContainsEmojiEditText</span><span class="params">(Context context, AttributeSet attrs)</span> </span>{</span><br><span class="line"> <span class="keyword">super</span>(context, attrs);</span><br><span class="line"> <span class="keyword">this</span>.mContext = context;</span><br><span class="line"> initEditText();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">ContainsEmojiEditText</span><span class="params">(Context context, AttributeSet attrs, <span class="keyword">int</span> defStyleAttr)</span> </span>{</span><br><span class="line"> <span class="keyword">super</span>(context, attrs, defStyleAttr);</span><br><span class="line"> <span class="keyword">this</span>.mContext = context;</span><br><span class="line"> initEditText();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 初始化edittext 控件</span></span><br><span class="line"> <span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">initEditText</span><span class="params">()</span> </span>{</span><br><span class="line"> addTextChangedListener(<span class="keyword">new</span> TextWatcher() {</span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">beforeTextChanged</span><span class="params">(CharSequence s, <span class="keyword">int</span> start, <span class="keyword">int</span> before, <span class="keyword">int</span> count)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (!resetText) {</span><br><span class="line"> cursorPos = getSelectionEnd();</span><br><span class="line"> <span class="comment">// 这里用s.toString()而不直接用s是因为如果用s,</span></span><br><span class="line"> <span class="comment">// 那么,inputAfterText和s在内存中指向的是同一个地址,s改变了,</span></span><br><span class="line"> <span class="comment">// inputAfterText也就改变了,那么表情过滤就失败了</span></span><br><span class="line"> inputAfterText= s.toString();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onTextChanged</span><span class="params">(CharSequence s, <span class="keyword">int</span> start, <span class="keyword">int</span> before, <span class="keyword">int</span> count)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (!resetText) {</span><br><span class="line"> <span class="keyword">if</span> (count >= <span class="number">2</span>) {<span class="comment">//表情符号的字符长度最小为2</span></span><br><span class="line"> CharSequence input = s.subSequence(cursorPos, cursorPos + count);</span><br><span class="line"> <span class="keyword">if</span> (containsEmoji(input.toString())) {</span><br><span class="line"> resetText = <span class="keyword">true</span>;</span><br><span class="line"> Toast.makeText(mContext, <span class="string">"不支持输入Emoji表情符号"</span>, Toast.LENGTH_SHORT).show();</span><br><span class="line"> <span class="comment">//是表情符号就将文本还原为输入表情符号之前的内容</span></span><br><span class="line"> setText(inputAfterText);</span><br><span class="line"> CharSequence text = getText();</span><br><span class="line"> <span class="keyword">if</span> (text <span class="keyword">instanceof</span> Spannable) {</span><br><span class="line"> Spannable spanText = (Spannable) text;</span><br><span class="line"> Selection.setSelection(spanText, text.length());</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> resetText = <span class="keyword">false</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">afterTextChanged</span><span class="params">(Editable editable)</span> </span>{</span><br><span class="line"></span><br><span class="line"> }</span><br><span class="line"> });</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span><br><span class="line"> * 检测是否有emoji表情</span><br><span class="line"> *</span><br><span class="line"> * <span class="doctag">@param</span> source</span><br><span class="line"> * <span class="doctag">@return</span></span><br><span class="line"> */</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">boolean</span> <span class="title">containsEmoji</span><span class="params">(String source)</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> len = source.length();</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < len; i++) {</span><br><span class="line"> <span class="keyword">char</span> codePoint = source.charAt(i);</span><br><span class="line"> <span class="keyword">if</span> (!isEmojiCharacter(codePoint)) { <span class="comment">//如果不能匹配,则该字符是Emoji表情</span></span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span><br><span class="line"> * 判断是否是Emoji</span><br><span class="line"> *</span><br><span class="line"> * <span class="doctag">@param</span> codePoint 比较的单个字符</span><br><span class="line"> * <span class="doctag">@return</span></span><br><span class="line"> */</span></span><br><span class="line"> <span class="function"><span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">boolean</span> <span class="title">isEmojiCharacter</span><span class="params">(<span class="keyword">char</span> codePoint)</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> (codePoint == <span class="number">0x0</span>) || (codePoint == <span class="number">0x9</span>) || (codePoint == <span class="number">0xA</span>) ||</span><br><span class="line"> (codePoint == <span class="number">0xD</span>) || ((codePoint >= <span class="number">0x20</span>) && (codePoint <= <span class="number">0xD7FF</span>)) ||</span><br><span class="line"> ((codePoint >= <span class="number">0xE000</span>) && (codePoint <= <span class="number">0xFFFD</span>)) || ((codePoint >= <span class="number">0x10000</span>)</span><br><span class="line"> && (codePoint <= <span class="number">0x10FFFF</span>));</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<ul>
<li>xml使用方法</li>
</ul>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">com.liujy.ui.wiget.ContainsEmojiEditText</span></span><br><span class="line"> <span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></span><br><span class="line"> <span class="attr">android:layout_height</span>=<span class="string">"wrap_content"</span> /></span></span><br></pre></td></tr></table></figure>]]></content>
</entry>
<entry>
<title><![CDATA[Android 判断程序是否在前台运行]]></title>
<url>http://kippies.cn/2016/07/10/Android%20%E5%88%A4%E6%96%AD%E7%A8%8B%E5%BA%8F%E6%98%AF%E5%90%A6%E5%9C%A8%E5%89%8D%E5%8F%B0%E8%BF%90%E8%A1%8C/</url>
<content type="html"><![CDATA[<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">static</span> <span class="keyword">boolean</span> <span class="title">isTopActivity</span><span class="params">(Activity activity)</span> </span>{ </span><br><span class="line"> String packageName = <span class="string">"com.liujy.android.test"</span>; </span><br><span class="line"> ActivityManager activityManager = (ActivityManager) activity </span><br><span class="line"> .getSystemService(Context.ACTIVITY_SERVICE); </span><br><span class="line"> List<RunningTaskInfo> tasksInfo = activityManager.getRunningTasks(<span class="number">1</span>); </span><br><span class="line"> <span class="keyword">if</span> (tasksInfo.size() > <span class="number">0</span>) { </span><br><span class="line"> <span class="comment">// 应用程序位于堆栈的顶层 </span></span><br><span class="line"> <span class="keyword">if</span> (packageName.equals(tasksInfo.get(<span class="number">0</span>).topActivity.getPackageName())) { </span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">true</span>; </span><br><span class="line"> } </span><br><span class="line"> } </span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">false</span>; </span><br><span class="line">}</span><br></pre></td></tr></table></figure>
]]></content>
</entry>
<entry>
<title><![CDATA[热更新-Android与Lua相互通信]]></title>
<url>http://kippies.cn/2016/07/08/%E7%83%AD%E6%9B%B4%E6%96%B0-Android%E4%B8%8ELua%E7%9B%B8%E4%BA%92%E9%80%9A%E4%BF%A1/</url>
<content type="html"><![CDATA[<h3 id="热更新介绍"><a href="#热更新介绍" class="headerlink" title="热更新介绍"></a>热更新介绍</h3><ul>
<li>什么是热更新?</li>
</ul>
<p><code>客户端启动时,主动请求服务端检查版本号,并更新资源到本地。</code></p>
<ul>
<li>应用场景:<ul>
<li>情况一:客户端已经发布了,但突然发现有个比较严重的bug需要修复。这时需要更新客户端的代码(Lua代码)。</li>
<li>情况二:情人节到了,需要搞个活动,在客户端中营造一个节日氛围。这时,需要更新客户端资源或增加一些功能。</li>
</ul>
</li>
<li>好处:<br><code>不需要重新打包和提交应用到市场等待审核。</code></li>
</ul>
<h3 id="Android与Lua相互通信"><a href="#Android与Lua相互通信" class="headerlink" title="Android与Lua相互通信"></a>Android与Lua相互通信</h3><ul>
<li><p>参考资料:</p>
<ul>
<li><a href="http://manual.luaer.cn/" target="_blank" rel="external">Lua 5.1 在线参考手册</a></li>
<li><a href="https://github.com/mkottman/AndroLua" target="_blank" rel="external">开源项目LuaJava</a></li>
</ul>
</li>
</ul>
<a id="more"></a>
<h3 id="在Android项目中使用Lua,需要两个步骤"><a href="#在Android项目中使用Lua,需要两个步骤" class="headerlink" title="在Android项目中使用Lua,需要两个步骤"></a>在Android项目中使用Lua,需要两个步骤</h3><ol>
<li>加载Lua脚本解析引擎</li>
<li>以Native API方式调用引擎接口</li>
</ol>
<ul>
<li>直接以JNI方式调用Lua解析引擎的接口十分麻烦,开源项目<a href="https://github.com/mkottman/AndroLua" target="_blank" rel="external">LuaJava</a>对这些JNI接口进行了很好的封装,它是一个包含了LuaJava的Android平台的Lua解析器,它提供一系列映射到Lua C实现函数的Java接口。</li>
</ul>
<h3 id="需注意的地方"><a href="#需注意的地方" class="headerlink" title="需注意的地方"></a>需注意的地方</h3><ul>
<li>.lua文件可存放在assets、raw文件夹;</li>
<li>提供给lua的回调必须是public,否则lua调不到;</li>
<li>“.”是用来调用类的方法或变量(静态方法),而“:”是用来调用对象的方法。</li>
</ul>
<h3 id="在Lua中调用Java类:"><a href="#在Lua中调用Java类:" class="headerlink" title="在Lua中调用Java类:"></a>在Lua中调用Java类:</h3><ul>
<li>newInstance(className, …) // 可以根据类名创建一个Java类,同时返回一个lua变量与Java类对应</li>
</ul>
<figure class="highlight lua"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">-- 启动手机设置</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">launchSetting</span><span class="params">(context)</span></span></span><br><span class="line"> <span class="comment">-- 得到Intent类的实例</span></span><br><span class="line"> intent = luajava.newInstance(<span class="string">"android.content.Intent"</span>)</span><br><span class="line"> c = luajava.newInstance(<span class="string">"android.content.ComponentName"</span>,<span class="string">"com.android.settings"</span>, <span class="string">"com.android.settings.Settings"</span>)</span><br><span class="line"> <span class="comment">-- intent:用来调用对象的方法 </span></span><br><span class="line"> <span class="comment">-- intent.用来调用类的方法或变量(静态方法)</span></span><br><span class="line"> intent:setFlags(intent.FLAG_ACTIVITY_NEW_TASK);</span><br><span class="line"> intent:setComponent(c)</span><br><span class="line"> context:startActivity(intent)</span><br><span class="line"><span class="keyword">end</span></span><br></pre></td></tr></table></figure>
<ul>
<li>bindClass(className) // 可以让lua中的变量对应一个Java的类(是类,不是实例),这样就可以用lua的这个变量创建实例以及调用静态类</li>
</ul>
<figure class="highlight lua"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">require</span> <span class="string">'import'</span></span><br><span class="line">button_cb = {}</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">button_cb.onClick</span><span class="params">(ev)</span></span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'hello,world'</span>)</span><br><span class="line"> launchSetting(activity)</span><br><span class="line"><span class="keyword">end</span></span><br><span class="line"><span class="comment">--[=[ 因为id是R.java里的一个静态类,所以引用Button的资源文件用下面的代码:</span><br><span class="line"> id.launchButton,而不是id:launchButton ]=]</span></span><br><span class="line"><span class="keyword">local</span> id = luajava.bindClass(<span class="string">"sk.kottman.androlua.R$id"</span>)</span><br><span class="line"><span class="keyword">local</span> launch = activity:findViewById(id.launchButton)</span><br><span class="line"><span class="comment">-- 另外,注意类中类的引用方法,如:android.view.View$OnClickListener</span></span><br><span class="line">buttonProxy = luajava.createProxy(<span class="string">"android.view.View$OnClickListener"</span>, button_cb)</span><br><span class="line">launch:setOnClickListener(buttonProxy)</span><br></pre></td></tr></table></figure>
<h3 id="在java中调用Lua:"><a href="#在java中调用Lua:" class="headerlink" title="在java中调用Lua:"></a>在java中调用Lua:</h3><ul>
<li>LuaState mLuaState = LuaStateFactory.newLuaState(); // Lua解析和执行由此对象完成</li>
<li>mLuaState.openLibs();</li>
<li>调用Lua脚本语句:</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">executeLuaStatemanet</span><span class="params">()</span> </span>{</span><br><span class="line"> mLuaState.LdoString(<span class="string">" varSay = 'call from android : This is string in lua script statement.'"</span>);<span class="comment">// 定义一个Lua变量</span></span><br><span class="line"> mLuaState.getGlobal(<span class="string">"varSay"</span>);<span class="comment">// 获取</span></span><br><span class="line"> displayResult1.setText(mLuaState.toString(-<span class="number">1</span>));<span class="comment">// 输出</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h3 id="调用Lua脚本文件:"><a href="#调用Lua脚本文件:" class="headerlink" title="调用Lua脚本文件:"></a>调用Lua脚本文件:</h3><figure class="highlight lua"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">private void executeLuaFile() {</span><br><span class="line"> mLuaState.LdoString(readStream(getResources().openRawResource(R.raw.luafile)));</span><br><span class="line"> mLuaState.getField(LuaState.LUA_GLOBALSINDEX, <span class="string">"functionInLuaFile"</span>);// 找到functionInLuaFile函数</span><br><span class="line"> mLuaState.pushString(<span class="string">"从Java中传递的参数"</span>);// 将参数压入栈</span><br><span class="line"> // functionInLuaFile函数有一个参数,一个返回结果</span><br><span class="line"> int paramCount = <span class="number">1</span>;</span><br><span class="line"> int resultCount = <span class="number">1</span>;</span><br><span class="line"> mLuaState.call(paramCount, resultCount);</span><br><span class="line"> mLuaState.setField(LuaState.LUA_GLOBALSINDEX, <span class="string">"resultKey"</span>);// 将结果保存到resultKey中</span><br><span class="line"> mLuaState.getGlobal(<span class="string">"resultKey"</span>);// 获取</span><br><span class="line"> displayResult2.setText(mLuaState.toString(<span class="number">-1</span>));// 输出</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h3 id="调用android-API:"><a href="#调用android-API:" class="headerlink" title="调用android API:"></a>调用android API:</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">callAndroidAPI</span><span class="params">()</span> </span>{</span><br><span class="line"> mLuaState.LdoString(readStream(getResources().openRawResource(R.raw.luafile)));</span><br><span class="line"> mLuaState.getField(LuaState.LUA_GLOBALSINDEX, <span class="string">"callAndroidApi"</span>);<span class="comment">// 找到callAndroidApi函数</span></span><br><span class="line"> mLuaState.pushJavaObject(getApplicationContext()); <span class="comment">// 上下文</span></span><br><span class="line"> mLuaState.pushJavaObject(mLayout); <span class="comment">// 布局</span></span><br><span class="line"> mLuaState.pushString(<span class="string">"lua call android Textview的setText()方法, 内容是:"</span> + (++count)); <span class="comment">// 内容</span></span><br><span class="line"> mLuaState.call(<span class="number">3</span>, <span class="number">0</span>); <span class="comment">// callAndroidApi函数需要传递3个参数,0个返回值</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h3 id="raw文件目录下luafile-lua代码:"><a href="#raw文件目录下luafile-lua代码:" class="headerlink" title="raw文件目录下luafile.lua代码:"></a>raw文件目录下luafile.lua代码:</h3><figure class="highlight lua"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">-- 调用Lua脚本文件</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">functionInLuaFile</span><span class="params">(key)</span></span></span><br><span class="line"> <span class="keyword">return</span> <span class="string">'call from android: I am in Lua file . Return : '</span>..key..<span class="string">'!'</span></span><br><span class="line"><span class="keyword">end</span></span><br><span class="line"></span><br><span class="line"><span class="comment">-- 调用android API</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">callAndroidApi</span><span class="params">(context,layout,tip)</span></span></span><br><span class="line"> tv = luajava.newInstance(<span class="string">"android.widget.TextView"</span>,context)</span><br><span class="line"> tv:setText(tip)</span><br><span class="line"> layout:addView(tv)</span><br><span class="line"><span class="keyword">end</span></span><br></pre></td></tr></table></figure>]]></content>
</entry>
<entry>
<title><![CDATA[java 计算时间差,还剩下xx天xx小时xx分xx秒]]></title>
<url>http://kippies.cn/2016/06/10/java-%E8%AE%A1%E7%AE%97%E6%97%B6%E9%97%B4%E5%B7%AE%EF%BC%8C%E8%BF%98%E5%89%A9%E4%B8%8Bxx%E5%A4%A9xx%E5%B0%8F%E6%97%B6xx%E5%88%86xx%E7%A7%92/</url>
<content type="html"><![CDATA[<p>计算时间差,还剩下xx天xx小时xx分xx秒</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">final</span> Handler handler = <span class="keyword">new</span> Handler();</span><br><span class="line"> Runnable runnable = <span class="keyword">new</span> Runnable() {</span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">run</span><span class="params">()</span> </span>{</span><br><span class="line"> setDateInfo(NumberUtil.convertTolong(data.getData().getSubmitDate(), System.currentTimeMillis()), orderDateAndNumber);</span><br><span class="line"> handler.postDelayed(<span class="keyword">this</span>, <span class="number">1000</span>);</span><br><span class="line"> }</span><br><span class="line"> };</span><br><span class="line"> runnable.run();</span><br></pre></td></tr></table></figure>
<a id="more"></a>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">setDateInfo</span><span class="params">(<span class="keyword">long</span> milliseconds, TextView textView)</span> </span>{</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> Date currDate = <span class="keyword">new</span> Date(System.currentTimeMillis());</span><br><span class="line"> Date endDate = <span class="keyword">new</span> Date(milliseconds);</span><br><span class="line"> <span class="keyword">long</span> diff = currDate.getTime() - endDate.getTime(); <span class="comment">// 得到的差值是微秒级别,可以忽略</span></span><br><span class="line"> <span class="keyword">long</span> days = diff / (<span class="number">1000</span> * <span class="number">60</span> * <span class="number">60</span> * <span class="number">24</span>);</span><br><span class="line"> <span class="keyword">long</span> hours = (diff - days * (<span class="number">1000</span> * <span class="number">60</span> * <span class="number">60</span> * <span class="number">24</span>)) / (<span class="number">1000</span> * <span class="number">60</span> * <span class="number">60</span>);</span><br><span class="line"> <span class="keyword">long</span> minutes = (diff - days * (<span class="number">1000</span> * <span class="number">60</span> * <span class="number">60</span> * <span class="number">24</span>) - hours * (<span class="number">1000</span> * <span class="number">60</span> * <span class="number">60</span>)) / (<span class="number">1000</span> * <span class="number">60</span>);</span><br><span class="line"> <span class="keyword">long</span> seconds = (diff - days * (<span class="number">1000</span> * <span class="number">60</span> * <span class="number">60</span> * <span class="number">24</span>) - hours * (<span class="number">1000</span> * <span class="number">60</span> * <span class="number">60</span>) - minutes * (<span class="number">1000</span> * <span class="number">60</span>)) / (<span class="number">1000</span>);</span><br><span class="line"> textView.setText(<span class="string">"订单将在"</span></span><br><span class="line"> + ((<span class="number">2</span> - (days + <span class="number">1</span>)) < <span class="number">0</span> ? <span class="string">"0"</span> : (<span class="number">2</span> - (days + <span class="number">1</span>))) + <span class="string">"天"</span></span><br><span class="line"> + (<span class="number">24</span> - (hours + <span class="number">1</span>)) + <span class="string">"小时"</span></span><br><span class="line"> + (<span class="number">60</span> - (minutes + <span class="number">1</span>)) + <span class="string">"分"</span></span><br><span class="line"> + (<span class="number">60</span> - (seconds + <span class="number">1</span>)) + <span class="string">"秒"</span></span><br><span class="line"> + <span class="string">"自动关闭"</span>);</span><br><span class="line"> } <span class="keyword">catch</span> (Exception e) {</span><br><span class="line"> e.printStackTrace();</span><br><span class="line"> }</span><br><span class="line"> }</span><br></pre></td></tr></table></figure>]]></content>
</entry>
<entry>
<title><![CDATA[Android的Activity管理]]></title>
<url>http://kippies.cn/2016/05/10/Android%E7%9A%84Activity%E7%AE%A1%E7%90%86/</url>
<content type="html"><![CDATA[<h4 id="可能你会遇到这种场景:"><a href="#可能你会遇到这种场景:" class="headerlink" title="可能你会遇到这种场景:"></a>可能你会遇到这种场景:</h4><ol>
<li>界面A–>界面B–>…–>界面N,停留在界面N的时候,提交数据,才会把界面N之前的界面A、B… finish掉;</li>
<li>登录、注册,最后的提交后,直接进入App主界面,这个时候就要把注册界面finish掉;</li>
<li>等等</li>
</ol>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> java.util.LinkedList; </span><br><span class="line"><span class="keyword">import</span> java.util.List; </span><br><span class="line"> </span><br><span class="line"><span class="keyword">import</span> android.app.Activity; </span><br><span class="line"><span class="keyword">import</span> android.app.Application; </span><br><span class="line"> </span><br><span class="line"><span class="comment">/** </span><br><span class="line"> * activity管理</span><br><span class="line"> * </span><br><span class="line"> * <span class="doctag">@author</span> Liujy</span><br><span class="line"> */</span> </span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">KYActivityMannger</span> <span class="keyword">extends</span> <span class="title">Application</span> </span>{ </span><br><span class="line"> <span class="keyword">private</span> List<Activity> mList = <span class="keyword">new</span> LinkedList<Activity>(); </span><br><span class="line"> <span class="keyword">private</span> List<Activity> mLogoutList = <span class="keyword">new</span> LinkedList<Activity>(); </span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">static</span> KYActivityMannger instance; </span><br><span class="line"> </span><br><span class="line"> <span class="function"><span class="keyword">private</span> <span class="title">KYActivityMannger</span><span class="params">()</span> </span>{ </span><br><span class="line"> } </span><br><span class="line"> </span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">synchronized</span> <span class="keyword">static</span> KYActivityMannger <span class="title">getInstance</span><span class="params">()</span> </span>{ </span><br><span class="line"> <span class="keyword">if</span> (<span class="keyword">null</span> == instance) { </span><br><span class="line"> instance = <span class="keyword">new</span> KYActivityMannger(); </span><br><span class="line"> } </span><br><span class="line"> <span class="keyword">return</span> instance; </span><br><span class="line"> } </span><br><span class="line"> </span><br><span class="line"> <span class="comment">/** </span><br><span class="line"> * add Activity save mList </span><br><span class="line"> * <span class="doctag">@param</span> activity </span><br><span class="line"> */</span> </span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">addActivity</span><span class="params">(Activity activity)</span> </span>{ </span><br><span class="line"> mList.add(activity); </span><br><span class="line"> } </span><br><span class="line"> </span><br><span class="line"> <span class="comment">/** </span><br><span class="line"> * add Activity save mLogoutList </span><br><span class="line"> * <span class="doctag">@param</span> activity </span><br><span class="line"> */</span> </span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">addLogoutActivity</span><span class="params">(Activity activity)</span> </span>{ </span><br><span class="line"> mLogoutList.add(activity); </span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> <span class="comment">/** </span><br><span class="line"> * 退出 </span><br><span class="line"> */</span> </span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">exit</span><span class="params">()</span> </span>{ </span><br><span class="line"> <span class="keyword">try</span> { </span><br><span class="line"> <span class="keyword">for</span> (Activity activity : mList) { </span><br><span class="line"> <span class="keyword">if</span> (activity != <span class="keyword">null</span>) </span><br><span class="line"> activity.finish(); </span><br><span class="line"> } </span><br><span class="line"> } <span class="keyword">catch</span> (Exception e) { </span><br><span class="line"> e.printStackTrace(); </span><br><span class="line"> } <span class="keyword">finally</span> { </span><br><span class="line"> android.os.Process.killProcess(android.os.Process.myPid()); </span><br><span class="line"> System.exit(<span class="number">0</span>); </span><br><span class="line"> } </span><br><span class="line"> } </span><br><span class="line"> </span><br><span class="line"> <span class="comment">/** </span><br><span class="line"> * 注销 </span><br><span class="line"> */</span> </span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">logout</span><span class="params">()</span> </span>{ </span><br><span class="line"> <span class="keyword">try</span> { </span><br><span class="line"> <span class="keyword">for</span> (Activity activity : mLogoutList) { </span><br><span class="line"> <span class="keyword">if</span> (activity != <span class="keyword">null</span>) </span><br><span class="line"> activity.finish(); </span><br><span class="line"> } </span><br><span class="line"> } <span class="keyword">catch</span> (Exception e) { </span><br><span class="line"> e.printStackTrace(); </span><br><span class="line"> } <span class="keyword">finally</span> { </span><br><span class="line"> System.gc(); </span><br><span class="line"> } </span><br><span class="line"> } </span><br><span class="line"> </span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onLowMemory</span><span class="params">()</span> </span>{ </span><br><span class="line"> <span class="keyword">super</span>.onLowMemory(); </span><br><span class="line"> System.gc(); </span><br><span class="line"> } </span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<a id="more"></a>
<h4 id="在需要对Activity管理的onCreate-)添加:"><a href="#在需要对Activity管理的onCreate-)添加:" class="headerlink" title="在需要对Activity管理的onCreate()添加:"></a>在需要对Activity管理的onCreate()添加:</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">KYActivityMannger.getInstance().addActivity(<span class="keyword">this</span>); </span><br><span class="line">KYActivityMannger.getInstance().addLogoutActivity(<span class="keyword">this</span>);</span><br></pre></td></tr></table></figure>
<h4 id="调用"><a href="#调用" class="headerlink" title="调用"></a>调用</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 注销不退出App</span></span><br><span class="line">KYActivityMannger.getInstance().logout();</span><br><span class="line"><span class="comment">// 退出并退出App</span></span><br><span class="line">KYActivityMannger.getInstance().exit();</span><br></pre></td></tr></table></figure>]]></content>
</entry>
<entry>
<title><![CDATA[最新的java正则表达式判断手机号,支持虚拟运营商170号段]]></title>
<url>http://kippies.cn/2016/05/07/%E6%9C%80%E6%96%B0%E7%9A%84-java-%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F%E5%88%A4%E6%96%AD%E6%89%8B%E6%9C%BA%E5%8F%B7%EF%BC%8C%E6%94%AF%E6%8C%81%E8%99%9A%E6%8B%9F%E8%BF%90%E8%90%A5%E5%95%86170%E5%8F%B7%E6%AE%B5/</url>
<content type="html"><![CDATA[<p>国家号码段分配如下:
</p>
<ul>
<li>移动:134、135、136、137、138、139、150、151、157(TD)、158、159、187、188、182</li>
<li>联通:130、131、132、152、155、156、185、186</li>
<li>电信:133、153、180、189、177、(1349卫通)</li>
<li>虚拟:170</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> java.io.IOException; </span><br><span class="line"><span class="keyword">import</span> java.util.regex.Matcher; </span><br><span class="line"><span class="keyword">import</span> java.util.regex.Pattern; </span><br><span class="line"> </span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ClassPathResource</span> </span>{ </span><br><span class="line"> </span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">boolean</span> <span class="title">isMobileNO</span><span class="params">(String mobiles)</span> </span>{ </span><br><span class="line"> Pattern p = Pattern.compile(<span class="string">"^((13[0-9])|(15[^4,\\D])|(14[57])|(17[0])|(17[7])|(18[0,0-9]))\\d{8}$"</span>); </span><br><span class="line"> Matcher m = p.matcher(mobiles); </span><br><span class="line"> System.out.println(m.matches()+<span class="string">"---"</span>); </span><br><span class="line"> <span class="keyword">return</span> m.matches(); </span><br><span class="line"> } </span><br><span class="line"> </span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> IOException </span>{ </span><br><span class="line"> </span><br><span class="line"> System.out.println(ClassPathResource.isMobileNO(<span class="string">"14738381438"</span>)); </span><br><span class="line"> </span><br><span class="line"> } </span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p><code>版权声明:本文为博主原创文章,未经博主允许不得转载。</code></p>
]]></content>
</entry>
<entry>
<title><![CDATA[Hello World]]></title>
<url>http://kippies.cn/2016/05/01/hello-world/</url>
<content type="html"><![CDATA[<ul>
<li>今天,是我诞生的日子 – 2016.05.01。</li>
</ul>
]]></content>
</entry>
</search>