-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathindex.html
877 lines (502 loc) · 41.7 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>葱丝瓣酱</title>
<meta name="author" content="Xiaocong He">
<meta name="description" content="Aug 26th, 2013 android, python, uiautomator Android Uiautomator的python包 随着Android的快速演进,先后经历了 Android 测试框架从 InstrumentationTest, Robotium, …">
<!-- http://t.co/dKP3o1e -->
<meta name="HandheldFriendly" content="True">
<meta name="MobileOptimized" content="320">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="/atom.xml" rel="alternate" title="葱丝瓣酱" type="application/atom+xml">
<link rel="canonical" href="http://xiaocong.github.io/">
<link href="/favicon.png" rel="shortcut icon">
<link href="/stylesheets/screen.css" media="screen, projection" rel="stylesheet" type="text/css">
<link href="/stylesheets/font-awesome.min.css" media="screen, projection" rel="stylesheet" type="text/css">
<!--[if lt IE 9]><script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
<link href='http://fonts.googleapis.com/css?family=Open+Sans:400italic,400,700' rel='stylesheet' type='text/css'>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<!--Fonts from Google"s Web font directory at http://google.com/webfonts -->
<link href="http://fonts.googleapis.com/css?family=PT+Serif:regular,italic,bold,bolditalic" rel="stylesheet" type="text/css">
<link href="http://fonts.googleapis.com/css?family=PT+Sans:regular,italic,bold,bolditalic" rel="stylesheet" type="text/css">
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-32376813-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</head>
<body>
<div class="container">
<div class="left-col">
<div class="intrude-less">
<header id="header" class="inner"><div class="profilepic">
<script src="/javascripts/md5.js"></script>
<script type="text/javascript">
$(function(){
$('.profilepic').append("<img src='http://www.gravatar.com/avatar/" + MD5("[email protected]") + "?s=160' alt='Profile Picture' style='width: 160px;' />");
});
</script>
</div>
<hgroup>
<h1><a href="/">葱丝瓣酱</a></h1>
<h2>你真的需要呼吸吗?!</h2>
</hgroup>
<nav id="main-nav"><ul class="main-navigation">
<li><a href="/">Blog</a></li>
<li><a href="/blog/archives">Archives</a></li>
</ul>
</nav>
<nav id="sub-nav">
<div class="social">
<a class="google" href="https://plus.google.com/106150875079575926280" rel="author" title="Google+">Google+</a>
<a class="twitter" href="http://twitter.com/xiaocong" title="Twitter">Twitter</a>
<a class="github" href="https://github.com/xiaocong" title="GitHub">GitHub</a>
<a class="rss" href="/atom.xml" title="RSS">RSS</a>
</div>
</nav>
</header>
</div>
</div>
<div class="mid-col">
<div id="banner" class="inner">
<div class="container">
<ul class="feed"></ul>
</div>
<small><a href="http://twitter.com/xiaocong">xiaocong</a> @ <a href="http://twitter.com">Twitter</a></small>
<div class="loading">Loading...</div>
</div>
<script src="/javascripts/twitter.js"></script>
<script type="text/javascript">
(function($){
$('#banner').getTwitterFeed('xiaocong', 4, false);
})(jQuery);
</script>
<div class="mid-col-container">
<div id="content" class="inner">
<div itemscope itemtype="http://schema.org/Blog">
<article class="post" itemprop="blogPost" itemscope itemtype="http://schema.org/BlogPosting">
<div class="meta">
<div class="date">
<time datetime="2013-08-26T17:59:00+08:00" data-updated="true" itemprop="datePublished">Aug 26<span>th</span>, 2013</time></div>
<div class="tags">
<a class='category' href='/blog/categories/android/'>android</a>, <a class='category' href='/blog/categories/python/'>python</a>, <a class='category' href='/blog/categories/uiautomator/'>uiautomator</a>
</div>
</div>
<h1 class="title" itemprop="name"><a href="/blog/2013/08/26/android-uiautomator-and-python/" itemprop="url">Android Uiautomator的python包</a></h1>
<div class="entry-content" itemprop="articleBody">
<p>随着Android的快速演进,先后经历了 Android 测试框架从 InstrumentationTest, Robotium, Monkeyrunner, 直到 uiautomator 的变化,从目前来看,对于独立的QA团队来说,uiautomator 是最适合的 Android 测试框架.</p>
<p>就我个人的体会,沉重的 Java 语言及其繁琐的工具链,是阻碍 uiautomator 推广的障碍,个人更喜欢 Python 和 Javascript 的快速开发和方便的工具链。为了更方便地利用 uiautomator,花了两周时间实现了 Android uiautomator 的 Python Wrapper 模块并开源出来:</p>
<ul>
<li><a href="https://pypi.python.org/pypi/uiautomator">pypi: uiautomator</a></li>
<li><a href="/slides/android-uiautomator-and-python/">uiautomator.py slides</a></li>
<li><a href="https://github.com/xiaocong/uiautomator">github source code</a></li>
</ul>
<p>希望下一步能有时间完成相应的 nodejs 模块。</p>
</div>
</article>
<article class="post" itemprop="blogPost" itemscope itemtype="http://schema.org/BlogPosting">
<div class="meta">
<div class="date">
<time datetime="2013-07-18T12:02:00+08:00" data-updated="true" itemprop="datePublished">Jul 18<span>th</span>, 2013</time></div>
<div class="tags">
<a class='category' href='/blog/categories/python/'>python</a>
</div>
</div>
<h1 class="title" itemprop="name"><a href="/blog/2013/07/18/idiomatic-python-code/" itemprop="url">符合语言习惯的Python编程</a></h1>
<div class="entry-content" itemprop="articleBody">
<p>给 Team 内部培训用的 Slides:<a href="/slides/idiomatic-python-code/">符合语言习惯的Python编程</a></p>
</div>
</article>
<article class="post" itemprop="blogPost" itemscope itemtype="http://schema.org/BlogPosting">
<div class="meta">
<div class="date">
<time datetime="2013-06-18T14:37:00+08:00" data-updated="true" itemprop="datePublished">Jun 18<span>th</span>, 2013</time></div>
<div class="tags">
<a class='category' href='/blog/categories/python/'>python</a>
</div>
</div>
<h1 class="title" itemprop="name"><a href="/blog/2013/06/18/customize-python-dev-environment-on-ubuntu/" itemprop="url">在Ubuntu下配置舒服的Python开发环境</a></h1>
<div class="entry-content" itemprop="articleBody">
<p>Ubuntu 提供了一个良好的 Python 开发环境,但如果想使我们的开发效率最大化,还需要进行很多定制化的安装和配置。下面的是我们团队开发人员推荐的一个安装和配置步骤,基于 Ubuntu 12.04 桌面版本标准安装。</p>
<h2>安装 Python 发布版本和 build 依赖包</h2>
<p>建议至少安装 Python 2.7/3.2 版本,毕竟 Python 2.X/3.X 还是有不少区别的。</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="c"># 安装 Python 发布版本,dev包必须安装,很多用pip安装包都需要编译</span>
</span><span class='line'>sudo apt-get install python2.7 python2.7-dev python3.2 python3.2-dev
</span><span class='line'><span class="c"># 很多pip安装的包都需要libssl和libevent编译环境</span>
</span><span class='line'>sudo apt-get install build-essential libssl-dev libevent-dev libjpeg-dev libxml2-dev libxslt-dev
</span></code></pre></td></tr></table></div></figure>
<a href="/blog/2013/06/18/customize-python-dev-environment-on-ubuntu/" class="more-link">Read on →</a>
</div>
</article>
<article class="post" itemprop="blogPost" itemscope itemtype="http://schema.org/BlogPosting">
<div class="meta">
<div class="date">
<time datetime="2013-06-16T12:36:00+08:00" data-updated="true" itemprop="datePublished">Jun 16<span>th</span>, 2013</time></div>
<div class="tags">
<a class='category' href='/blog/categories/python/'>python</a>
</div>
</div>
<h1 class="title" itemprop="name"><a href="/blog/2013/06/16/python-interview-question-and-answer/" itemprop="url">Python 面试问题</a></h1>
<div class="entry-content" itemprop="articleBody">
<p>最近正在团队内部普及 Python 语言,有些刚接触 Python 语言的工程师在概念上有很多混淆的地方,刚好看到这篇文章:<a href="http://ilian.i-n-i.org/python-interview-question-and-answers/">Python面试问题</a>,里面列举的问题都是关于 Python 基本的常识或者容易混淆的知识点,因此推荐给团队的 Python 初学者。</p>
<a href="/blog/2013/06/16/python-interview-question-and-answer/" class="more-link">Read on →</a>
</div>
</article>
<article class="post" itemprop="blogPost" itemscope itemtype="http://schema.org/BlogPosting">
<div class="meta">
<div class="date">
<time datetime="2013-06-04T10:53:00+08:00" data-updated="true" itemprop="datePublished">Jun 4<span>th</span>, 2013</time></div>
<div class="tags">
<a class='category' href='/blog/categories/python/'>python</a>
</div>
</div>
<h1 class="title" itemprop="name"><a href="/blog/2013/06/04/creating-a-singleton-in-python/" itemprop="url">在Python中生成单体实例的方法</a></h1>
<div class="entry-content" itemprop="articleBody">
<p>Python是很强力的编程语言,它即支持面向对象编程的特征,也支持很多函数式编程的特征,同时还是一门动态语言。由于Python语言特征的多样性,对于同一种设计需求,我们可以采用多种完全不同的方式进行实现。优秀的软件工程师总能在这些实现方式中,根据他们的优劣,选择出最适合的方式。</p>
<p>下面的内容源自<a href="http://stackoverflow.com/">StackOverflow</a>的一篇文章:<a href="http://stackoverflow.com/questions/6760685/creating-a-singleton-in-python">Creating a singleton in python</a>
。</p>
<blockquote><p>这个问题不是为了讨论单体实例是否是有必要的,或者是反面模式,也不是为了挑起任何宗教式的战争,而是为了讨论如何用更Pythonic的方式,最佳地实现单体实例模式。</p></blockquote>
<a href="/blog/2013/06/04/creating-a-singleton-in-python/" class="more-link">Read on →</a>
</div>
</article>
<article class="post" itemprop="blogPost" itemscope itemtype="http://schema.org/BlogPosting">
<div class="meta">
<div class="date">
<time datetime="2013-04-22T13:23:00+08:00" data-updated="true" itemprop="datePublished">Apr 22<span>nd</span>, 2013</time></div>
<div class="tags">
<a class='category' href='/blog/categories/markdown/'>markdown</a>, <a class='category' href='/blog/categories/uml/'>uml</a>
</div>
</div>
<h1 class="title" itemprop="name"><a href="/blog/2013/04/22/writing-development-documentation-with-markdown/" itemprop="url">在 Markdown 中嵌入 UML 文档</a></h1>
<div class="entry-content" itemprop="articleBody">
<p><a href="http://daringfireball.net/projects/markdown/" title="Markdown">Markdown</a>是网络书写语言,特别适合程序员书写文档:</p>
<ul>
<li>全文本格式,方便进行<code>diff</code>,<code>patch</code>和版本的管理;</li>
<li>格式直观,简单易学,便于书写和阅读;</li>
<li>兼容 HTML,能方便地转换为 pdf,doc等格式;</li>
<li>支持 Linux,Windows,Mac;</li>
<li>支持内嵌代码和语法高亮;</li>
</ul>
<p>估计只是方便版本管理,就能吸引很多程序员的兴趣,特别是需要团队一起参与书写文档的时候。感兴趣的可以参考官方网站,或者以前写的一份<a href="/slides/writing-documentation-with-markdown/">使用 Markdown 的 slides</a>。</p>
<p>但是毕竟<a href="http://daringfireball.net/projects/markdown/" title="Markdown">Markdown</a>只是书写语言,不是程序设计语言,如果我们需要嵌入 UML 的时候,不可避免地需要其他专业软件的支持。这里介绍几种利用网络服务,可以直接在<a href="http://daringfireball.net/projects/markdown/" title="Markdown">Markdown</a>文档中嵌入的 UML 建模图:</p>
<a href="/blog/2013/04/22/writing-development-documentation-with-markdown/" class="more-link">Read on →</a>
</div>
</article>
<article class="post" itemprop="blogPost" itemscope itemtype="http://schema.org/BlogPosting">
<div class="meta">
<div class="date">
<time datetime="2013-03-20T23:04:00+08:00" data-updated="true" itemprop="datePublished">Mar 20<span>th</span>, 2013</time></div>
<div class="tags">
<a class='category' href='/blog/categories/github/'>github</a>
</div>
</div>
<h1 class="title" itemprop="name"><a href="/blog/2013/03/20/team-collaboration-with-github/" itemprop="url">使用GitHub进行团队合作</a></h1>
<div class="entry-content" itemprop="articleBody">
<p><em>原文: <a href="http://net.tutsplus.com/articles/general/team-collaboration-with-github/" title="使用GitHub进行团队合作">Team Collaboration With GitHub</a></em></p>
<hr />
<p><a href="http://github.com" title="GitHub">GitHub</a>已经成为的一切开放源码软件的基石。开发人员喜欢它,基于它进行协作,并不断通过它开发令人惊叹的项目。除了代码托管,<a href="http://github.com" title="GitHub">GitHub</a>的主要吸引力是使用它作为一个协作开发工具。在本教程中,让我们来看看一些最有用的GitHub的功能,特别是使团队工作更有效率,更高生产力,非常重要的,好玩的那些功能!</p>
<hr />
<h1>GitHub和软件合作</h1>
<blockquote><p>有一件事我觉得非常有用的是,可以将GitHub的维基集成到项目的源代码主线上。</p></blockquote>
<p>本教程假定您已经熟悉<a href="http://git-scm.com/" title="git">Git</a> – 开放源码的分布式版本控制系统,由Linux的创世人<a href="http://en.wikipedia.org/wiki/Linus_Torvalds">Linus Torvalds</a>在2005年创造的。如果您需要修改或查找有关<a href="http://git-scm.com/" title="git">Git</a>,请访问我们以前的<a href="https://tutsplus.com/course/git-essentials/">截屏教程</a>,和一些<a href="http://net.tutsplus.com/tag/git/">文章</a>。此外,你应该已经有一个<a href="http://github.com" title="GitHub">Github</a>上的帐户,并做了一些基本的功能,如创建一个存储库,并推送到<a href="http://github.com" title="GitHub">GitHub</a>上。如果没有,可以参照更多以前的<a href="http://net.tutsplus.com/tag/github/">教程</a>。</p>
<p>在这个世界上的软件项目,不可避免的是,我们必须和一个团队一起工作来交付软件。在本教程中,我们将探索一些软件开发团队最常用的工具。这些工具包括:</p>
<ul>
<li><strong>添加团队成员</strong> – 组织和合作者</li>
<li><strong>Pull请求</strong> – 发送代码变更和合并</li>
<li><strong>问题跟踪</strong> – Github上的错误记录</li>
<li><strong>分析</strong> – 图形与网络</li>
<li><strong>项目管理</strong> – <a href="http://trello.com" title="Trello">Trello</a>与<a href="https://www.pivotaltracker.com/" title="Pivotal Tracker">Pivotal Tracker</a></li>
<li><strong>持续集成</strong> – <a href="https://travis-ci.org/" title="Travis CI">Travis CI</a></li>
<li><strong>代码审查</strong> – 代码行评论与URL查询</li>
<li><strong>文档记录</strong> – Wiki与Hubot</li>
</ul>
<h1>更喜欢截屏操作视频?</h1>
<p>如果你倾向于观看截屏操作视频,可以观看下面的截屏操作视频,而将本教程作为旁注。</p>
<p><video width='600' height='338' preload='none' controls poster=''><source src='http://tutsplus-media.s3.amazonaws.com/net.tutsplus.com/video/4-Team-Collaboration-With-GitHub.mp4' type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'></video></p>
<a href="/blog/2013/03/20/team-collaboration-with-github/" class="more-link">Read on →</a>
</div>
</article>
<article class="post" itemprop="blogPost" itemscope itemtype="http://schema.org/BlogPosting">
<div class="meta">
<div class="date">
<time datetime="2012-11-21T11:59:00+08:00" data-updated="true" itemprop="datePublished">Nov 21<span>st</span>, 2012</time></div>
<div class="tags">
<a class='category' href='/blog/categories/android/'>android</a>
</div>
</div>
<h1 class="title" itemprop="name"><a href="/blog/2012/11/21/to-introduce-android-dropboxmanager-service/" itemprop="url">介绍 Android DropBoxManager Service</a></h1>
<div class="entry-content" itemprop="articleBody">
<h2>什么是 DropBoxManager ?</h2>
<blockquote><p>Enqueues chunks of data (from various sources – application crashes, kernel log records, etc.). The queue is size bounded and will drop old data if the enqueued data exceeds the maximum size. You can think of this as a persistent, system-wide, blob-oriented “logcat”.</p></blockquote>
<p>DropBoxManager 是 <a href="http://www.android.com">Android</a> 在 Froyo(API level 8) 引入的用来持续化存储系统数据的机制, 主要用于记录
Android 运行过程中, 内核, 系统进程, 用户进程等出现严重问题时的 log, 可以认为这是一个可持续存储的系统级别的
<a href="http://developer.android.com/tools/help/logcat.html">logcat</a>.</p>
<p>我们可以通过用参数 <a href="http://developer.android.com/reference/android/content/Context.html#DROPBOX_SERVICE">DROPBOX_SERVICE</a>
调用 <a href="http://developer.android.com/reference/android/content/Context.html#getSystemService(java.lang.String">getSystemService(String)</a>
来获得这个服务, 并查询出所有存储在 DropBoxManager 里的系统错误记录.</p>
<h2>Android 缺省能记录哪些系统错误 ?</h2>
<p>我没有在官方的网站上找到关于哪些系统错误会被记录到 DropBoxManager 中的文档, 但我们可以查看源代码来找到相关信息.
从源代码中可以查找到记录到 DropBoxManager 中各种 <code>tag</code>(类似于 logcat 的 <code>tag</code>).</p>
<h3>crash (应用程序强制关闭, Force Close)</h3>
<p>当Java层遇到未被 catch 的例外时, ActivityManagerService 会记录一次 <code>crash</code> 到 DropBoxManager中, 并弹出 <code>Force Close</code> 对话框提示用户.</p>
<figure class='code'><figcaption><span>ActivityManagerService</span><a href='https://android.googlesource.com/platform/frameworks/base/+/refs/tags/android-4.2_r1/services/java/com/android/server/am/ActivityManagerService.java'>link</a></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
</pre></td><td class='code'><pre><code class='java'><span class='line'><span class="kd">public</span> <span class="kt">void</span> <span class="nf">handleApplicationCrash</span><span class="o">(</span><span class="n">IBinder</span> <span class="n">app</span><span class="o">,</span> <span class="n">ApplicationErrorReport</span><span class="o">.</span><span class="na">CrashInfo</span> <span class="n">crashInfo</span><span class="o">)</span> <span class="o">{</span>
</span><span class='line'> <span class="n">ProcessRecord</span> <span class="n">r</span> <span class="o">=</span> <span class="n">findAppProcess</span><span class="o">(</span><span class="n">app</span><span class="o">,</span> <span class="s">"Crash"</span><span class="o">);</span>
</span><span class='line'> <span class="kd">final</span> <span class="n">String</span> <span class="n">processName</span> <span class="o">=</span> <span class="n">app</span> <span class="o">==</span> <span class="kc">null</span> <span class="o">?</span> <span class="s">"system_server"</span>
</span><span class='line'> <span class="o">:</span> <span class="o">(</span><span class="n">r</span> <span class="o">==</span> <span class="kc">null</span> <span class="o">?</span> <span class="s">"unknown"</span> <span class="o">:</span> <span class="n">r</span><span class="o">.</span><span class="na">processName</span><span class="o">);</span>
</span><span class='line'>
</span><span class='line'> <span class="n">EventLog</span><span class="o">.</span><span class="na">writeEvent</span><span class="o">(</span><span class="n">EventLogTags</span><span class="o">.</span><span class="na">AM_CRASH</span><span class="o">,</span> <span class="n">Binder</span><span class="o">.</span><span class="na">getCallingPid</span><span class="o">(),</span>
</span><span class='line'> <span class="n">UserHandle</span><span class="o">.</span><span class="na">getUserId</span><span class="o">(</span><span class="n">Binder</span><span class="o">.</span><span class="na">getCallingUid</span><span class="o">()),</span> <span class="n">processName</span><span class="o">,</span>
</span><span class='line'> <span class="n">r</span> <span class="o">==</span> <span class="kc">null</span> <span class="o">?</span> <span class="o">-</span><span class="mi">1</span> <span class="o">:</span> <span class="n">r</span><span class="o">.</span><span class="na">info</span><span class="o">.</span><span class="na">flags</span><span class="o">,</span>
</span><span class='line'> <span class="n">crashInfo</span><span class="o">.</span><span class="na">exceptionClassName</span><span class="o">,</span>
</span><span class='line'> <span class="n">crashInfo</span><span class="o">.</span><span class="na">exceptionMessage</span><span class="o">,</span>
</span><span class='line'> <span class="n">crashInfo</span><span class="o">.</span><span class="na">throwFileName</span><span class="o">,</span>
</span><span class='line'> <span class="n">crashInfo</span><span class="o">.</span><span class="na">throwLineNumber</span><span class="o">);</span>
</span><span class='line'>
</span><span class='line'> <span class="n">addErrorToDropBox</span><span class="o">(</span><span class="s">"crash"</span><span class="o">,</span> <span class="n">r</span><span class="o">,</span> <span class="n">processName</span><span class="o">,</span> <span class="kc">null</span><span class="o">,</span> <span class="kc">null</span><span class="o">,</span> <span class="kc">null</span><span class="o">,</span> <span class="kc">null</span><span class="o">,</span> <span class="kc">null</span><span class="o">,</span> <span class="n">crashInfo</span><span class="o">);</span>
</span><span class='line'>
</span><span class='line'> <span class="n">crashApplication</span><span class="o">(</span><span class="n">r</span><span class="o">,</span> <span class="n">crashInfo</span><span class="o">);</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>
<a href="/blog/2012/11/21/to-introduce-android-dropboxmanager-service/" class="more-link">Read on →</a>
</div>
</article>
<article class="post" itemprop="blogPost" itemscope itemtype="http://schema.org/BlogPosting">
<div class="meta">
<div class="date">
<time datetime="2012-10-16T12:59:00+08:00" data-updated="true" itemprop="datePublished">Oct 16<span>th</span>, 2012</time></div>
<div class="tags">
<a class='category' href='/blog/categories/bbb/'>bbb</a>, <a class='category' href='/blog/categories/grunt-dot-js/'>grunt.js</a>, <a class='category' href='/blog/categories/javascript/'>javascript</a>, <a class='category' href='/blog/categories/yeoman/'>yeoman</a>
</div>
</div>
<h1 class="title" itemprop="name"><a href="/blog/2012/10/16/yeoman-a-new-javascript-build-tool/" itemprop="url">Yeoman: 一个新的 Javascript 构建工具</a></h1>
<div class="entry-content" itemprop="articleBody">
<p><a href="http://gruntjs.com/" title="Grunt is a task-based command line build tool for JavaScript projects.">Grunt</a> 是一个非常优秀的 Javascript 构建工具, 虽然它的 Build-in 的任务非常有限, 但是它提供了一套非常灵活的插件机制, 可以进行任务扩展. 目前在官网上的第三方任务插件数目已经达到 160+, 并且在持续增长中… 对于通用的功能基本上都能找到对应的任务插件, 当然你也可以自己写扩展任务来满足特殊的构建需求.</p>
<p>我通常会直接使用 <a href="https://github.com/backbone-boilerplate/grunt-bbb" title="Backbone Boilerplate framework tool.">bbb</a>, 因为 <a href="https://github.com/backbone-boilerplate/grunt-bbb" title="Backbone Boilerplate framework tool.">bbb</a> 已经收集齐了我想用到的任务插件, 非常顺手.</p>
<p>对我而言 <a href="https://github.com/backbone-boilerplate/grunt-bbb" title="Backbone Boilerplate framework tool.">bbb</a> 已经足够用了, 尽管这样, 在第一次尝试 <a href="http://yeoman.io/" title="Yeoman is a robust and opinionated set of tools, libraries, and a workflow that can help developers quickly build beautiful, compelling web apps.">Yeoman</a> 之后, 我还是忍不住想向大家推荐这个新的工具.</p>
<blockquote><p>Yeoman is a robust and opinionated client-side stack, comprised of tools and frameworks that can help developers quickly build beautiful web applications. We take care of providing everything needed to get started without any of the normal headaches associated with a manual setup.<br/>With a modular architecture that can scale out of the box, we leverage the success and lessons learned from several open-source communities to ensure the stack developers use is as intelligent as possible.<br/>As firm believers in good documentation and well thought out build processes, Yeoman includes support for linting, testing, minification and much more, so developers can focus on solutions rather than worrying about the little things.<br/>Yeoman is fast, performant and is optimized to work best in modern browsers.</p><footer><strong>Yeoman Community</strong> <cite><a href='http://yeoman.io/whyyeoman.html'>WHY YEOMAN?</a></cite></footer></blockquote>
<p>想对比其他 Javascript 构建工具, Yeoman 具有下面非常吸引人的特点:</p>
<h2>根据定制模板快速生成程序框架</h2>
<p><a href="http://yeoman.io/" title="Yeoman is a robust and opinionated set of tools, libraries, and a workflow that can help developers quickly build beautiful, compelling web apps.">Yeoman</a> 能根据你选择的框架初始化生成程序框架, 目前已经支持大量的程序模板, 看趋势似乎是想把所有框架的初始化模板都包含进去:</p>
<pre><code>Yeoman:
generator
controller
Angular:
angular:service
angular:all
angular:directive
angular:view
angular:route
angular:filter
angular:controller
angular:app
Testacular:
testacular:app
Quickstart:
quickstart:all
Bbb:
bbb:all
Ember:
ember:controller
ember:all
ember:view
ember:model
ember:app
Chromeapp:
chromeapp:all
Ember-starter:
ember-starter:all
Backbone:
backbone:model
backbone:view
backbone:router
backbone:collection
backbone:app
backbone:all
</code></pre>
<p>虽然目前我只用到了 Bbb 模板, 但还是得赞一下其模板的齐全.</p>
<a href="/blog/2012/10/16/yeoman-a-new-javascript-build-tool/" class="more-link">Read on →</a>
</div>
</article>
<article class="post" itemprop="blogPost" itemscope itemtype="http://schema.org/BlogPosting">
<div class="meta">
<div class="date">
<time datetime="2012-10-09T19:20:00+08:00" data-updated="true" itemprop="datePublished">Oct 9<span>th</span>, 2012</time></div>
<div class="tags">
<a class='category' href='/blog/categories/backbone-dot-js-backbone-dot-layoutmanager-bbb/'>backbone.js backbone.layoutmanager bbb</a>
</div>
</div>
<h1 class="title" itemprop="name"><a href="/blog/2012/10/09/use-backbone-dot-layoutmanager-to-assemble-layouts-with-backbone-views/" itemprop="url">在Backbone项目中使用backbone.layoutmanager来组织页面布局</a></h1>
<div class="entry-content" itemprop="articleBody">
<p><a href="https://github.com/backbone-boilerplate/grunt-bbb" title="Backbone Boilerplate framework tool.">bbb</a> 的 <code>init</code> 命令生成的初始化模板工程中包含有 <a href="https://github.com/tbranyen/backbone.layoutmanager">backbone.layoutmanager</a> 插件, 该插件提供了一种页面的结构化组织方式, 将 <code>Backbone Views</code> 组装成页面布局 <code>Layout</code>.</p>
<p><a href="https://github.com/tbranyen/backbone.layoutmanager">backbone.layoutmanager</a> 主要的目的是提供一种规则来管理 <code>Backbone.View</code> 的渲染, 程序员只需要遵循这套规则, 就能简化页面渲染的实现.
<a href="https://github.com/tbranyen/backbone.layoutmanager">backbone.layoutmanager</a> 主页已经很详细地介绍了使用方法, 这里就不再赘述. 下面是个人感觉在学习使用过程中感觉应当注意的几点:</p>
<h2>完全受管理的 render</h2>
<p><code>Backbone.LayoutView</code> 仅仅是一个将 <code>manage</code> 属性设置成 <code>true</code> 的 <code>Backbone.View</code>.</p>
<figure class='code'><figcaption><span>backbone.layoutmanager V0.6.6</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">Backbone</span><span class="p">.</span><span class="nx">LayoutView</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
</span><span class='line'> <span class="nx">manage</span><span class="o">:</span> <span class="kc">true</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>
<p>只有当 <code>manage</code> 属性被设置为 <code>true</code>, <code>LayoutManager</code> 才会接管 <code>Backbone.View</code> 的渲染.</p>
<h2>数据和模板</h2>
<p>视图的渲染需要 <code>template</code> 和 <code>serialize</code> 属性, 分别对应HTML模板和数据模型. <code>LayoutManager</code> 缺省使用 <a href="http://underscorejs.org/">underscore</a> 的 <code>template</code> 函数进行页面的渲染.</p>
<h2>嵌套视图</h2>
<p>可以通过 <code>setView</code>, <code>setViews</code>, <code>insertView</code>, <code>insertViews</code> 等函数在<strong>视图</strong>中嵌套多个其他的<strong>子视图</strong>.</p>
<h2>BeforeRender 和 AfterRender</h2>
<p><code>render</code> 完全处在 <code>LayoutManager</code> 的管理下, 因此, 如果你想在每次视图渲染前后做一些特殊的处理, 必须定义 <code>beforeRender</code> 和 <code>afterRender</code> 函数.
由于 <code>LayoutManager</code> 内部会在渲染<strong>视图</strong>前移除所有附加模式的<strong>子视图</strong>, 因此, 通常在 <code>beforeRender</code> 函数中调用 <code>setView</code> 和 <code>insertView</code> 来增加和设置<strong>子视图</strong>.</p>
<p><em>如果你不想在每次渲染时移除子视图, 自己控制子视图的增删, 可以设置子视图的 <code>keep</code> 属性为 <code>true</code>.</em></p>
<h2>Cleanup 函数</h2>
<p>很多视图(View)都有数据模型(model)的事件绑定函数, 因此, 必须在视图被删除后解除绑定. 可以通过定义视图的 <code>cleanup</code> 函数来完成这个解绑操作:</p>
<figure class='code'><figcaption><span>cleanup函数</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kd">var</span> <span class="nx">MyView</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
</span><span class='line'> <span class="c1">// The constructor binds the model's "change" event to the view's render function. </span>
</span><span class='line'> <span class="nx">initialize</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'> <span class="k">this</span><span class="p">.</span><span class="nx">model</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s2">"change"</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">render</span><span class="p">,</span> <span class="k">this</span><span class="p">);</span>
</span><span class='line'> <span class="p">}</span><span class="err">,</span>
</span><span class='line'>
</span><span class='line'> <span class="c1">// This is a custom cleanup method that will remove the model events owned by</span>
</span><span class='line'> <span class="c1">// this View.</span>
</span><span class='line'> <span class="nx">cleanup</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'> <span class="k">this</span><span class="p">.</span><span class="nx">model</span><span class="p">.</span><span class="nx">off</span><span class="p">(</span><span class="kc">null</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="k">this</span><span class="p">);</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>
<h2>自定义获取模版</h2>
<p><code>LayoutManager</code> 缺省只支持 <code>script</code> 标签的模版, 但是在实际软件项目中, 通常会将不同的模版放置在不同的单独的 html 文件中, 这样便于模版文件的管理.
<code>LayoutManager</code> 提供了 <code>fetch</code> 配置项让我们有机会来自己获得模版文件:</p>
<figure class='code'><figcaption><span>从script标签中获得模版内容</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='coffeescript'><span class='line'> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">LayoutManager</span><span class="p">.</span><span class="nx">configure</span>
</span><span class='line'> <span class="c1"># Default fetch implementation, get template from `script` tag</span>
</span><span class='line'> <span class="nv">fetch: </span><span class="nf">(path)-></span>
</span><span class='line'> <span class="nx">_</span><span class="p">.</span><span class="nx">template</span> <span class="nx">$</span><span class="p">(</span><span class="nx">path</span><span class="p">).</span><span class="nx">html</span><span class="p">()</span>
</span></code></pre></td></tr></table></div></figure>
<figure class='code'><figcaption><span>同步方式获取模版文件</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
</pre></td><td class='code'><pre><code class='coffeescript'><span class='line'> <span class="nv">JST = </span><span class="nb">window</span><span class="p">.</span><span class="nv">JST = </span><span class="nb">window</span><span class="p">.</span><span class="nx">JST</span> <span class="o">or</span> <span class="p">{}</span>
</span><span class='line'> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">LayoutManager</span><span class="p">.</span><span class="nx">configure</span>
</span><span class='line'> <span class="nv">manage: </span><span class="kc">true</span>
</span><span class='line'> <span class="nv">paths:</span>
</span><span class='line'> <span class="nv">layout: </span><span class="s">"templates/layouts/"</span>
</span><span class='line'> <span class="nv">template: </span><span class="s">"templates/"</span>
</span><span class='line'>
</span><span class='line'> <span class="nv">fetch: </span><span class="nf">(path) -></span>
</span><span class='line'> <span class="nv">path = </span><span class="nx">path</span> <span class="o">+</span> <span class="s">".html"</span>
</span><span class='line'> <span class="k">unless</span> <span class="nx">JST</span><span class="p">[</span><span class="nx">path</span><span class="p">]</span>
</span><span class='line'> <span class="nx">$</span><span class="p">.</span><span class="nx">ajax</span><span class="p">(</span>
</span><span class='line'> <span class="nv">url: </span><span class="nx">app</span><span class="p">.</span><span class="nx">root</span> <span class="o">+</span> <span class="nx">path</span>
</span><span class='line'> <span class="nv">async: </span><span class="kc">false</span>
</span><span class='line'> <span class="p">).</span><span class="nx">then</span> <span class="nf">(contents) -></span>
</span><span class='line'> <span class="nx">JST</span><span class="p">[</span><span class="nx">path</span><span class="p">]</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">template</span><span class="p">(</span><span class="nx">contents</span><span class="p">)</span>
</span><span class='line'> <span class="nx">JST</span><span class="p">[</span><span class="nx">path</span><span class="p">]</span>
</span></code></pre></td></tr></table></div></figure>
<p>下面是作者的教学视频, 初学者一定要看看.</p>
<iframe src="http://player.vimeo.com/video/32765088" width="500" height="313" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>
<p> <p><a href="http://vimeo.com/32765088">backbone.layoutmanager</a> from <a href="http://vimeo.com/user5699767">tbranyen</a> on <a href="http://vimeo.com">Vimeo</a>.</p></p>
</div>
</article>
</div>
<nav id="pagenavi">
<a href="/blog/page/2/" class="next">Next</a>
<div class="center"><a href="/blog/archives">Blog Archives</a></div>
</nav></div>
</div>
<footer id="footer" class="inner"><p>
Copyright © 2014 - Xiaocong He -
<span class="credit">Powered by <a href="http://octopress.org">Octopress</a></span>
</p>
Design credit: <a href="http://shashankmehta.in/archive/2012/greyshade.html">Shashank Mehta</a></footer>
<script type="text/javascript">
var disqus_shortname = 'xiaocong';
var disqus_script = 'count.js';
(function () {
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
dsq.src = 'http://' + disqus_shortname + '.disqus.com/' + disqus_script;
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
}());
</script>
<div id="fb-root"></div>
<script>(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) {return;}
js = d.createElement(s); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js#appId=212934732101925&xfbml=1";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));</script>
<script type="text/javascript">
(function() {
var script = document.createElement('script'); script.type = 'text/javascript'; script.async = true;
script.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(script, s);
})();
</script>
<script type="text/javascript">
(function(){
var twitterWidgets = document.createElement('script');
twitterWidgets.type = 'text/javascript';
twitterWidgets.async = true;
twitterWidgets.src = '//platform.twitter.com/widgets.js';
document.getElementsByTagName('head')[0].appendChild(twitterWidgets);
})();
</script>
</div>
</div>
</body>
</html>