0%

今天在Ubuntu 14.02 (64位)下安装了Android开发环境,其中遇到adb无法使用的情况,以为是没配置环境变量的问题,就添加一下:

1
sudo vim /etc/profile
1
2
export PATH="$PATH:/home/username/sdk/tools"
export PATH="$PATH:/home/username/sdk/paltform-tools"

但是系统注销后运行,还是会报错:没有该文件或文件夹。

经查阅发现Linux下SDK的adb命令是32位的,所以要在64位系统上要安装兼容包:

Ubuntu 13.10及以上的版本:

1
2
3
sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install libncurses5:i386 libstdc++6:i386 zlib1g:i386

以下的版本:

1
apt-get install ia32-libs

执行过后可发现adb可正常运行。

在国内下载Android可是不太容易,不过从Google断断续续地下载了几天源码后发现清华大学有个TUNA镜像源可以下载Android源码,甚是方便。

参考网站:

http://source.android.com/index.html

https://aosp.tuna.tsinghua.edu.cn/

一.环境准备:

现在Android源码的下载和编译在Linux和Mac OS上都可以了,但Mac OS上设置略微复杂点,所以我选择了Ubuntu 14.04 64位的虚拟机。(硬盘建议50G以上,编译的时候给虚拟机加大CPU和内存。)

编译Gingerbread (2.3.x) 及其以上的源码需要64位的系统,以下的可以在32位系统上编译。

1.Java下载和配置

Java 7:适用最新版的源码:

1
2
$ sudo apt-get update
$ sudo apt-get install openjdk-7-jdk

如果系统上有多个Java版本,可以设置默认的:

1
2
$ sudo update-alternatives --config java
$ sudo update-alternatives --config javac

Java 6: 适用于Gingerbread(2.3)~ KitKat(4.4)

Java 5:适用于 Cupcake(1.5)~ Froyo(2.2)

如果Java安装失败可到Java官网下载后自行安装,略去不表。

2.其它依赖包:

1
$ sudo apt-get install bison g++-multilib git gperf libxml2-utils make zlib1g-dev:i386 zip

但在编译过程中发现还需要两个包,所以也提前安装好吧:

1
$ sudo apt-get install flex libswitch-perl

如果是Ubuntu 12.04:

1
2
3
4
5
6
$ sudo apt-get install git gnupg flex bison gperf build-essential \
zip curl libc6-dev libncurses5-dev:i386 x11proto-core-dev \
libx11-dev:i386 libreadline6-dev:i386 libgl1-mesa-glx:i386 \
libgl1-mesa-dev g++-multilib mingw32 tofrodos \
python-markdown libxml2-utils xsltproc zlib1g-dev:i386
$ sudo ln -s /usr/lib/i386-linux-gnu/mesa/libGL.so.1 /usr/lib/i386-linux-gnu/libGL.so

如果是Ubuntu 10.04 – 11.10:

1
2
3
4
5
$ sudo apt-get install git gnupg flex bison gperf build-essential \
zip curl zlib1g-dev libc6-dev lib32ncurses5-dev ia32-libs \
x11proto-core-dev libx11-dev lib32readline5-dev lib32z-dev \
libgl1-mesa-dev g++-multilib mingw32 tofrodos python-markdown \
libxml2-utils xsltproc

11.10:

1
$ sudo apt-get install libx11-dev:i386

10.04:

1
$ sudo ln -s /usr/lib32/mesa/libGL.so.1 /usr/lib32/mesa/libGL.so

二、下载源码

1.下载repo:

repo是Google基于Git推出的一款版本管理工具,用python写的。

先配置目录:

1
2
$ mkdir ~/bin
$ PATH=~/bin:$PATH

下载repo并赋予其可执行权限:

1
2
$ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
$ chmod a+x ~/bin/repo

当然由于众所周知的原因,我们往往无法把repo下到本地。这里提供一个我下载并修改好的下载链接:http://jiezhiblog.com/wp-content/uploads/2015/04/repo1.txt

(wp的限制,只能把repo重命名为repo.txt,下载后改回repo即可)

下载放到~/bin目录下,并修改权限即可:

1
chmod a+x repo

2.初始化repo

进入放置源码的目录,如:

1
2
$ mkdir ~/android/android 4.3_r1
$ cd ~/android/android 4.3_r1

关键的来了,如果想体验好点,建议国内的从清华大学的镜像源下载:

1
$ repo init -u git://aosp.tuna.tsinghua.edu.cn/android/platform/manifest

或者指定要下载的分支:

1
$ repo init -u git://aosp.tuna.tsinghua.edu.cn/android/platform/manifest -b android-4.3_r1

完成后即可和服务器同步了:

1
$ repo sync

该服务器限制了每个IP并发数,也就是你可以使用:

1
$ repo sync -j4

设置并发数为4.,给别人留有余地。

现在应该在从服务器下载源码了,但是如果中途有中断了,继续执行repo sync即可。

如何让repo自动在断开后自动下载:

新建autorepo.sh:

1
2
3
4
5
6
#!/bin/sh
repo sync
while [ $? -ne 0 ]
do
repo sync
done

然后执行即可:

1
$ sh autorepo.sh

如果你之前已经下载了部分AOSP的代码的话,切换到TUNA服务器也很方便,如官网所示:

如果你之前已经通过某种途径获得了 AOSP 的源码(或者你只是 init 这一步完成后), 你希望以后通过 TUNA 同步 AOSP 部分的代码,只需要将 .repo/manifest.xml 把其中的 aosp 这个 remote 的 fetch 从 https://android.googlesource.com 改为 git://aosp.tuna.tsinghua.edu.cn/android/

diff<manifest>    <remote  name="aosp"-           fetch="https://android.googlesource.com"+           fetch="git://aosp.tuna.tsinghua.edu.cn/android/"            review="android-review.googlesource.com" />    <remote  name="github"

这个方法也可以用来在同步 Cyanogenmod 代码的时候从 TUNA 同步部分代码

三、编译:

当源码下载后,可以看到目录里多出很多源码文件夹:

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
[aosp@myserver android4.1_r1]$ ls -hl
total 100K
drwxrwxr-x 3 aosp aosp 4.0K Apr 7 11:27 abi
drwxrwxr-x 9 aosp aosp 4.0K Apr 7 11:27 bionic
drwxrwxr-x 5 aosp aosp 4.0K Apr 7 11:27 bootable
drwxrwxr-x 7 aosp aosp 4.0K Apr 7 11:27 build
drwxrwxr-x 11 aosp aosp 4.0K Apr 7 11:27 cts
drwxrwxr-x 18 aosp aosp 4.0K Apr 7 11:27 dalvik
drwxrwxr-x 19 aosp aosp 4.0K Apr 7 11:27 development
drwxrwxr-x 10 aosp aosp 4.0K Apr 7 11:27 device
drwxrwxr-x 3 aosp aosp 4.0K Apr 7 11:27 docs
drwxrwxr-x 144 aosp aosp 4.0K Apr 7 11:29 external
drwxrwxr-x 14 aosp aosp 4.0K Apr 7 11:32 frameworks
drwxrwxr-x 10 aosp aosp 4.0K Apr 7 11:32 gdk
drwxrwxr-x 10 aosp aosp 4.0K Apr 7 11:32 hardware
drwxrwxr-x 11 aosp aosp 4.0K Apr 7 11:32 libcore
drwxrwxr-x 4 aosp aosp 4.0K Apr 7 11:32 libnativehelper
-r--r--r-- 1 aosp aosp 87 Apr 7 11:27 Makefile
drwxrwxr-x 8 aosp aosp 4.0K Apr 7 11:32 ndk
drwxrwxr-x 4 aosp aosp 4.0K Apr 7 14:28 out
drwxrwxr-x 7 aosp aosp 4.0K Apr 7 11:33 packages
drwxrwxr-x 4 aosp aosp 4.0K Apr 7 11:33 pdk
drwxrwxr-x 12 aosp aosp 4.0K Apr 7 11:33 prebuilt
drwxrwxr-x 9 aosp aosp 4.0K Apr 7 11:34 prebuilts
drwxrwxr-x 48 aosp aosp 4.0K Apr 7 11:34 sdk
drwxrwxr-x 9 aosp aosp 4.0K Apr 7 11:34 system

如果你准备在模拟器里运行,则按照如下步骤编译即可,如果你想刷到手机上则还有一些任务要做(见第四步)。

0.其中由于配置问题,我的代码是放在服务器上编译的:

由于.repo这个隐藏文件夹里的文件占用空间很大,所以在压缩的时候将其排除:

1
$ tar -zcvf android4.3_r1.tar.gz android4.3_r1/ --exclude .repo

然后利用scp命令将压缩好的文件上传到服务器:

1
$ scp android4.3_r1.tar.gz username@host:/home/android/

其中username和host是你用户名和服务器地址。

解压:

1
$ tar -zxvf android4.3_r1.tar.gz /

1.初始化:

1
$ source build/envsetup.sh

2.使用lunch命令选择编译目标,如:

1
$ lunch aosp_arm-eng

或者直接lunch,会让你选择编译目标的。

其中参数说明:

BUILD NAME DEVICE NOTES
aosp_arm ARM emulator 包括所有语言、APP和输入法的配置
aosp_maguro maguro 运行在Galaxy Nexus GSM/HSPA+ (“maguro”)上
aosp_panda panda 运行在 PandaBoard (“panda”)上
BUILDTYPE USE
user limited access; suited for production(有权限限制,适合产品级)
userdebug preferred for debugging(适合调试)
eng development configuration with additional debugging tools(有额外的调试工具)

4.3.编译

1
$ make -j4

-jN表示用N个线程来编译,如果你是配置是2CPU,每个CPU有4核,每核可跑俩线程,那么你可以make -j16乃至-j32,这样速度将大大加快。.

4.成功

在android4.3_r1/out/target/product/generic目录下可以看到如下文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[aosp@myserver generic]$ ls -lh
total 205M
-rw-rw-r-- 1 aosp aosp 7 Apr 7 14:49 android-info.txt
-rw-rw-r-- 1 aosp aosp 25K Apr 7 14:48 clean_steps.mk
drwxrwxr-x 4 aosp aosp 4.0K Apr 7 15:19 data
drwxrwxr-x 3 aosp aosp 4.0K Apr 7 15:18 dex_bootjars
-rw-rw-r-- 1 aosp aosp 47K Apr 7 15:27 installed-files.txt
drwxrwxr-x 14 aosp aosp 4.0K Apr 7 15:27 obj
-rw-rw-r-- 1 aosp aosp 557 Apr 7 14:48 previous_build_config.mk
-rw-rw-r-- 1 aosp aosp 163K Apr 7 15:18 ramdisk.img
drwxrwxr-x 8 aosp aosp 4.0K Apr 7 15:18 root
drwxrwxr-x 5 aosp aosp 4.0K Apr 7 15:18 symbols
drwxrwxr-x 12 aosp aosp 4.0K Apr 7 15:27 system
-rw------- 1 aosp aosp 204M Apr 7 15:27 system.img
drwxrwxr-x 3 aosp aosp 4.0K Apr 7 15:05 test
-rw------- 1 aosp aosp 99K Apr 7 15:19 userdata.img

四、刷机

1.模拟器的话,其实直接运行emulator即可运行:

由于不涉及内核,我的做法是把ramdisk.img、system.img和userdata.img复制到sdk/system-images/android-18/default/armeabi-v7a/目录下替换掉原来的文件。(可以把原来的先备份)
然后新建对应的API虚拟机,运行即可。

2.真机

真机我是用Google三太子Galaxy Nexus [maguro] (GSM/HSPA+)做的实验,毕竟亲儿子,驱动方面都很好配置。

a.在第三步编译之前,先把驱动配置好:

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
$ cd ~/android/anddroid-4.3_r1

$ wget https://dl.google.com/dl/android/aosp/broadcom-maguro-jwr66y-5fa7715b.tgz

$ tar -zxvf broadcom-maguro-jwr66y-5fa7715b.tgz

$ ./extract-broadcom-maguro.sh # (view the license and then type "I ACCEPT")

...

$ wget https://dl.google.com/dl/android/aosp/imgtec-maguro-jwr66y-b0a4a1ef.tgz

$ tar -zxvf imgtec-maguro-jwr66y-b0a4a1ef.tgz

$ ./extract-imgtec-maguro.sh # (view the license and then type "I ACCEPT")

...

$ wget https://dl.google.com/dl/android/aosp/invensense-maguro-jwr66y-e0d2e531.tgz

$ tar -zxvf invensense-maguro-jwr66y-e0d2e531.tgz

$ ./extract-invensense-maguro.sh # (view the license and then type "I ACCEPT")

...

$ wget https://dl.google.com/dl/android/aosp/nxp-maguro-jwr66y-d8ac2804.tgz

$ tar -zxvf nxp-maguro-jwr66y-d8ac2804.tgz

$ ./extract-nxp-maguro.sh # (view the license and then type "I ACCEPT")

...

$ wget https://dl.google.com/dl/android/aosp/samsung-maguro-jwr66y-fb8f93b6.tgz

$ tar -zxvf samsung-maguro-jwr66y-fb8f93b6.tgz

$ ./extract-samsung-maguro.sh # (view the license and then type "I ACCEPT")

...

$ wget https://dl.google.com/dl/android/aosp/widevine-maguro-jwr66y-c49927ce.tgz

$ tar -zxvf widevine-maguro-jwr66y-c49927ce.tgz

$ ./extract-widevine-maguro.sh # (view the license and then type "I ACCEPT")

然后按照第三步编译即可。

b.连接手机,打开USB调试,进入bootloader模式:

1
$ adb reboot bootloader

如果bootloader被锁住的话,先解锁:

1
$ fastboot oem unlock

然后进入system.img等文件的目录:

1
2
3
4
5
$ fastboot flash boot boot.img

$ fastboot flash system system.img

$ fastboot flash userdata userdata.img

然后重启即可。

本人靠着《thinkpython》这本书算是对python入了门,但对第三方库的使用还不熟悉。

因为百度空间即将关闭,想借Evi1m0大神的一段python爬出代码来爬一下自己的网站的,结果其中缺少第三方库而无法运行。
1.在线安装
搜一些资料大多是用pip安装的,结果我的Mac上也没有pip。
首先安装pip:

1
sudo easy_install pip

如果我要安装wget模块,直接执行:

1
sudo pip install wget

2.离线安装
如果你已经把第三方模块下载好了,比如wget模块。其目录结构如下:

1
2
3
4
5
-rw-r--r--@ 1 jiezhi  staff   3.3K Jul 20  2014 PKG-INFO  
-rw-r--r--@ 1 jiezhi staff 2.0K Jul 20 2014 README.txt
drwxr-xr-x 3 jiezhi staff 102B Apr 14 21:49 build
-rw-r--r--@ 1 jiezhi staff 1.1K Jul 20 2014 setup.py
-rwxr-xr-x@ 1 jiezhi staff 13K Jul 20 2014 wget.py

其中只要执行下面的命令即可:

1
sudo python setup.py install

这两天在张罗着下载Android源码,结果在安装repo的时候老是提示找不到服务器。

1
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo

后来索性把代码找到直接复制到本地好了:

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
#!/bin/sh

## repo default configuration
##
REPO_URL='git://codeaurora.org/tools/repo.git'
REPO_REV='stable'

# Copyright (C) 2008 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

magic='--calling-python-from-/bin/sh--'
"""exec" python -E "$0" "$@" """#$magic"
if __name__ == '__main__':
import sys
if sys.argv[-1] == '#%s' % magic:
del sys.argv[-1]
del magic

# increment this whenever we make important changes to this script
VERSION = (1, 10)

# increment this if the MAINTAINER_KEYS block is modified
KEYRING_VERSION = (1,0)
MAINTAINER_KEYS = """

Repo Maintainer <repo@android.kernel.org>
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.4.2.2 (GNU/Linux)

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
=CMiZ
-----END PGP PUBLIC KEY BLOCK-----
"""

GIT = 'git' # our git command
MIN_GIT_VERSION = (1, 5, 4) # minimum supported git version
repodir = '.repo' # name of repo's private directory
S_repo = 'repo' # special repo reposiory
S_manifests = 'manifests' # special manifest repository
REPO_MAIN = S_repo + '/main.py' # main script


import optparse
import os
import re
import readline
import subprocess
import sys

home_dot_repo = os.path.expanduser('~/.repoconfig')
gpg_dir = os.path.join(home_dot_repo, 'gnupg')

extra_args = []
init_optparse = optparse.OptionParser(usage="repo init -u url [options]")

# Logging
group = init_optparse.add_option_group('Logging options')
group.add_option('-q', '--quiet',
dest="quiet", action="store_true", default=False,
help="be quiet")

# Manifest
group = init_optparse.add_option_group('Manifest options')
group.add_option('-u', '--manifest-url',
dest='manifest_url',
help='manifest repository location', metavar='URL')
group.add_option('-o', '--origin',
dest='manifest_origin',
help="use REMOTE instead of 'origin' to track upstream",
metavar='REMOTE')
group.add_option('-b', '--manifest-branch',
dest='manifest_branch',
help='manifest branch or revision', metavar='REVISION')
group.add_option('-m', '--manifest-name',
dest='manifest_name',
help='initial manifest file (deprecated)',
metavar='NAME.xml')
group.add_option('--mirror',
dest='mirror', action='store_true',
help='mirror the forrest')
group.add_option('--reference',
dest='reference',
help='location of mirror directory', metavar='DIR')

# Tool
group = init_optparse.add_option_group('repo Version options')
group.add_option('--repo-url',
dest='repo_url',
help='repo repository location', metavar='URL')
group.add_option('--repo-branch',
dest='repo_branch',
help='repo branch or revision', metavar='REVISION')
group.add_option('--no-repo-verify',
dest='no_repo_verify', action='store_true',
help='do not verify repo source code')


class CloneFailure(Exception):
"""Indicate the remote clone of repo itself failed.
"""


def _Init(args):
"""Installs repo by cloning it over the network.
"""
opt, args = init_optparse.parse_args(args)
if args or not opt.manifest_url:
init_optparse.print_usage()
sys.exit(1)

url = opt.repo_url
if not url:
url = REPO_URL
extra_args.append('--repo-url=%s' % url)

branch = opt.repo_branch
if not branch:
branch = REPO_REV
extra_args.append('--repo-branch=%s' % branch)

if branch.startswith('refs/heads/'):
branch = branch[len('refs/heads/'):]
if branch.startswith('refs/'):
print >>sys.stderr, "fatal: invalid branch name '%s'" % branch
raise CloneFailure()

if not os.path.isdir(repodir):
try:
os.mkdir(repodir)
except OSError, e:
print >>sys.stderr, \
'fatal: cannot make %s directory: %s' % (
repodir, e.strerror)
# Don't faise CloneFailure; that would delete the
# name. Instead exit immediately.
#
sys.exit(1)

_CheckGitVersion()
try:
if _NeedSetupGnuPG():
can_verify = _SetupGnuPG(opt.quiet)
else:
can_verify = True

if not opt.quiet:
print >>sys.stderr, 'Getting repo ...'
print >>sys.stderr, ' from %s' % url

dst = os.path.abspath(os.path.join(repodir, S_repo))
_Clone(url, dst, opt.quiet)

if can_verify and not opt.no_repo_verify:
rev = _Verify(dst, branch, opt.quiet)
else:
rev = 'refs/remotes/origin/%s^0' % branch

_Checkout(dst, branch, rev, opt.quiet)
except CloneFailure:
if opt.quiet:
print >>sys.stderr, \
'fatal: repo init failed; run without --quiet to see why'
raise


def _CheckGitVersion():
cmd = [GIT, '--version']
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)
ver_str = proc.stdout.read().strip()
proc.stdout.close()
proc.wait()

if not ver_str.startswith('git version '):
print >>sys.stderr, 'error: "%s" unsupported' % ver_str
raise CloneFailure()

ver_str = ver_str[len('git version '):].strip()
ver_act = tuple(map(lambda x: int(x), ver_str.split('.')[0:3]))
if ver_act < MIN_GIT_VERSION:
need = '.'.join(map(lambda x: str(x), MIN_GIT_VERSION))
print >>sys.stderr, 'fatal: git %s or later required' % need
raise CloneFailure()


def _NeedSetupGnuPG():
if not os.path.isdir(home_dot_repo):
return True

kv = os.path.join(home_dot_repo, 'keyring-version')
if not os.path.exists(kv):
return True

kv = open(kv).read()
if not kv:
return True

kv = tuple(map(lambda x: int(x), kv.split('.')))
if kv < KEYRING_VERSION:
return True
return False


def _SetupGnuPG(quiet):
if not os.path.isdir(home_dot_repo):
try:
os.mkdir(home_dot_repo)
except OSError, e:
print >>sys.stderr, \
'fatal: cannot make %s directory: %s' % (
home_dot_repo, e.strerror)
sys.exit(1)

if not os.path.isdir(gpg_dir):
try:
os.mkdir(gpg_dir, 0700)
except OSError, e:
print >>sys.stderr, \
'fatal: cannot make %s directory: %s' % (
gpg_dir, e.strerror)
sys.exit(1)

env = os.environ.copy()
env['GNUPGHOME'] = gpg_dir.encode()

cmd = ['gpg', '--import']
try:
proc = subprocess.Popen(cmd,
env = env,
stdin = subprocess.PIPE)
except OSError, e:
if not quiet:
print >>sys.stderr, 'warning: gpg (GnuPG) is not available.'
print >>sys.stderr, 'warning: Installing it is strongly encouraged.'
print >>sys.stderr
return False

proc.stdin.write(MAINTAINER_KEYS)
proc.stdin.close()

if proc.wait() != 0:
print >>sys.stderr, 'fatal: registering repo maintainer keys failed'
sys.exit(1)
print

fd = open(os.path.join(home_dot_repo, 'keyring-version'), 'w')
fd.write('.'.join(map(lambda x: str(x), KEYRING_VERSION)) + '\n')
fd.close()
return True


def _SetConfig(local, name, value):
"""Set a git configuration option to the specified value.
"""
cmd = [GIT, 'config', name, value]
if subprocess.Popen(cmd, cwd = local).wait() != 0:
raise CloneFailure()


def _Fetch(local, quiet, *args):
cmd = [GIT, 'fetch']
if quiet:
cmd.append('--quiet')
err = subprocess.PIPE
else:
err = None
cmd.extend(args)
cmd.append('origin')

proc = subprocess.Popen(cmd, cwd = local, stderr = err)
if err:
proc.stderr.read()
proc.stderr.close()
if proc.wait() != 0:
raise CloneFailure()


def _Clone(url, local, quiet):
"""Clones a git repository to a new subdirectory of repodir
"""
try:
os.mkdir(local)
except OSError, e:
print >>sys.stderr, \
'fatal: cannot make %s directory: %s' \
% (local, e.strerror)
raise CloneFailure()

cmd = [GIT, 'init', '--quiet']
try:
proc = subprocess.Popen(cmd, cwd = local)
except OSError, e:
print >>sys.stderr
print >>sys.stderr, "fatal: '%s' is not available" % GIT
print >>sys.stderr, 'fatal: %s' % e
print >>sys.stderr
print >>sys.stderr, 'Please make sure %s is installed'\
' and in your path.' % GIT
raise CloneFailure()
if proc.wait() != 0:
print >>sys.stderr, 'fatal: could not create %s' % local
raise CloneFailure()

_SetConfig(local, 'remote.origin.url', url)
_SetConfig(local, 'remote.origin.fetch',
'+refs/heads/*:refs/remotes/origin/*')
_Fetch(local, quiet)
_Fetch(local, quiet, '--tags')


def _Verify(cwd, branch, quiet):
"""Verify the branch has been signed by a tag.
"""
cmd = [GIT, 'describe', 'origin/%s' % branch]
proc = subprocess.Popen(cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
cwd = cwd)
cur = proc.stdout.read().strip()
proc.stdout.close()

proc.stderr.read()
proc.stderr.close()

if proc.wait() != 0 or not cur:
print >>sys.stderr
print >>sys.stderr,\
"fatal: branch '%s' has not been signed" \
% branch
raise CloneFailure()

m = re.compile(r'^(.*)-[0-9]{1,}-g[0-9a-f]{1,}$').match(cur)
if m:
cur = m.group(1)
if not quiet:
print >>sys.stderr
print >>sys.stderr, \
"info: Ignoring branch '%s'; using tagged release '%s'" \
% (branch, cur)
print >>sys.stderr

env = os.environ.copy()
env['GNUPGHOME'] = gpg_dir.encode()

cmd = [GIT, 'tag', '-v', cur]
proc = subprocess.Popen(cmd,
stdout = subprocess.PIPE,
stderr = subprocess.PIPE,
cwd = cwd,
env = env)
out = proc.stdout.read()
proc.stdout.close()

err = proc.stderr.read()
proc.stderr.close()

if proc.wait() != 0:
print >>sys.stderr
print >>sys.stderr, out
print >>sys.stderr, err
print >>sys.stderr
raise CloneFailure()
return '%s^0' % cur


def _Checkout(cwd, branch, rev, quiet):
"""Checkout an upstream branch into the repository and track it.
"""
cmd = [GIT, 'update-ref', 'refs/heads/default', rev]
if subprocess.Popen(cmd, cwd = cwd).wait() != 0:
raise CloneFailure()

_SetConfig(cwd, 'branch.default.remote', 'origin')
_SetConfig(cwd, 'branch.default.merge', 'refs/heads/%s' % branch)

cmd = [GIT, 'symbolic-ref', 'HEAD', 'refs/heads/default']
if subprocess.Popen(cmd, cwd = cwd).wait() != 0:
raise CloneFailure()

cmd = [GIT, 'read-tree', '--reset', '-u']
if not quiet:
cmd.append('-v')
cmd.append('HEAD')
if subprocess.Popen(cmd, cwd = cwd).wait() != 0:
raise CloneFailure()


def _FindRepo():
"""Look for a repo installation, starting at the current directory.
"""
dir = os.getcwd()
repo = None

olddir = None
while dir != '/' \
and dir != olddir \
and not repo:
repo = os.path.join(dir, repodir, REPO_MAIN)
if not os.path.isfile(repo):
repo = None
olddir = dir
dir = os.path.dirname(dir)
return (repo, os.path.join(dir, repodir))


class _Options:
help = False


def _ParseArguments(args):
cmd = None
opt = _Options()
arg = []

for i in xrange(0, len(args)):
a = args[i]
if a == '-h' or a == '--help':
opt.help = True

elif not a.startswith('-'):
cmd = a
arg = args[i + 1:]
break
return cmd, opt, arg


def _Usage():
print >>sys.stderr,\
"""usage: repo COMMAND [ARGS]

repo is not yet installed. Use "repo init" to install it here.

The most commonly used repo commands are:

init Install repo in the current working directory
help Display detailed help on a command

For access to the full online help, install repo ("repo init").
"""
sys.exit(1)


def _Help(args):
if args:
if args[0] == 'init':
init_optparse.print_help()
sys.exit(0)
else:
print >>sys.stderr,\
"error: '%s' is not a bootstrap command.\n"\
' For access to online help, install repo ("repo init").'\
% args[0]
else:
_Usage()
sys.exit(1)


def _NotInstalled():
print >>sys.stderr,\
'error: repo is not installed. Use "repo init" to install it here.'
sys.exit(1)


def _NoCommands(cmd):
print >>sys.stderr,\
"""error: command '%s' requires repo to be installed first.
Use "repo init" to install it here.""" % cmd
sys.exit(1)


def _RunSelf(wrapper_path):
my_dir = os.path.dirname(wrapper_path)
my_main = os.path.join(my_dir, 'main.py')
my_git = os.path.join(my_dir, '.git')

if os.path.isfile(my_main) and os.path.isdir(my_git):
for name in ['git_config.py',
'project.py',
'subcmds']:
if not os.path.exists(os.path.join(my_dir, name)):
return None, None
return my_main, my_git
return None, None


def _SetDefaultsTo(gitdir):
global REPO_URL
global REPO_REV

REPO_URL = gitdir
proc = subprocess.Popen([GIT,
'--git-dir=%s' % gitdir,
'symbolic-ref',
'HEAD'],
stdout = subprocess.PIPE,
stderr = subprocess.PIPE)
REPO_REV = proc.stdout.read().strip()
proc.stdout.close()

proc.stderr.read()
proc.stderr.close()

if proc.wait() != 0:
print >>sys.stderr, 'fatal: %s has no current branch' % gitdir
sys.exit(1)


def main(orig_args):
main, dir = _FindRepo()
cmd, opt, args = _ParseArguments(orig_args)

wrapper_path = os.path.abspath(__file__)
my_main, my_git = _RunSelf(wrapper_path)

if not main:
if opt.help:
_Usage()
if cmd == 'help':
_Help(args)
if not cmd:
_NotInstalled()
if cmd == 'init':
if my_git:
_SetDefaultsTo(my_git)
try:
_Init(args)
except CloneFailure:
for root, dirs, files in os.walk(repodir, topdown=False):
for name in files:
os.remove(os.path.join(root, name))
for name in dirs:
os.rmdir(os.path.join(root, name))
os.rmdir(repodir)
sys.exit(1)
main, dir = _FindRepo()
else:
_NoCommands(cmd)

if my_main:
main = my_main

ver_str = '.'.join(map(lambda x: str(x), VERSION))
me = [main,
'--repo-dir=%s' % dir,
'--wrapper-version=%s' % ver_str,
'--wrapper-path=%s' % wrapper_path,
'--']
me.extend(orig_args)
me.extend(extra_args)
try:
os.execv(main, me)
except OSError, e:
print >>sys.stderr, "fatal: unable to start %s" % main
print >>sys.stderr, "fatal: %s" % e
sys.exit(148)


if __name__ == '__main__':
main(sys.argv[1:])

保存为repo,然后修改权限即可:

比如保存在~/bin/repo

1
2
$ PATH=~/bin:$PATH
$ chmod a+x ~/bin/repo

1.我们可以把一个函数直接作为参数传入另一个参数:

1
2
3
4
5
6
import math

def add(x, y, f):
return f(x) + f(y)

print add(25, 9, math.sqrt)</pre>

2.map()函数

**map()**是 Python 内置的高阶函数,它接收一个函数 f 和一个 list,并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 list 并返回。

1
2
3
4
def format_name(s):
return s.capitalize()

print map(format_name, ['adam', 'LISA', 'barT'])</pre>

3.reduce()函数

**reduce()**函数也是Python内置的一个高阶函数。reduce()函数接收的参数和 map()类似,一个函数 f,一个list,但行为和 map()不同,reduce()传入的函数 f 必须接收两个参数,reduce()对list的每个元素反复调用函数f,并返回最终结果值。

1
2
3
4
def prod(x, y):
return x * y

print reduce(prod, [2, 4, 5, 7, 12])

4.filter()函数

**filter()**函数是 Python 内置的另一个有用的高阶函数,filter()函数接收一个函数 f 和一个list,这个函数 f 的作用是对每个元素进行判断,返回 True或 False,filter()根据判断结果自动过滤掉不符合条件的元素,返回由符合条件元素组成的新list。

利用filter()过滤出1~100(包括1和100)中平方根是整数的数

1
2
3
4
5
6
7
import math

def is_sqr(x):
i = int(math.sqrt(x))
return i * i == x

print filter(is_sqr, range(1, 101))

以上资料来自慕课网中《python进阶》课程。

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
private void parse() {
try {
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(false);
XmlPullParser xpp = factory.newPullParser();

xpp.setInput(new FileReader(filePath));
int eventType = xpp.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.START_DOCUMENT) {
System.out.println(&quot;Start document&quot;);
} else if (eventType == XmlPullParser.START_TAG) {
System.out.println(&quot;Start tag &quot; + xpp.getName());
} else if (eventType == XmlPullParser.END_TAG) {
System.out.println(&quot;end tag &quot; + xpp.getName());
} else if (eventType == XmlPullParser.TEXT) {
System.out.println(&quot;Text &quot; + xpp.getText());
}

eventType = xpp.next();
}
System.out.println(&quot;End docment&quot;);
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}