0%

How does the repo of android source code work ?

.repo

通常情况下, Android 的 .repo 里面有如下内容:

1
2
$ ls .repo
manifests manifests.git manifest.xml project.list project-objects projects repo

manifests

manifests 路径是项目 manifest 仓的 git checkout,其中的 .gitmanifest.git 的软链接,追踪 repo init --manifest-branch 指定的分支。

1
2
3
4
5
6
7
.repo$ ls manifests/.git/
config HEAD index logs ORIG_HEAD refs shallow
description hooks info objects packed-refs rr-cache svn

.repo$ ls manifests.git/
branches description HEAD info objects refs svn
config FETCH_HEAD hooks logs packed-refs rr-cache

不管远程分支名字是什么,manifests 的本地分支命名为 default。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.repo$ cat manifests/.git/HEAD 
ref: refs/heads/default

.repo$ cat manifests.git/config
# cat manifests/.git/config
[core]
repositoryformatversion = 0
filemode = true
[filter "lfs"]
smudge = git-lfs smudge --skip -- %f
[remote "origin"]
url = https://<url>/platform/manifest.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "default"]
remote = origin
merge = refs/heads/<remote_branch_name>

manifests.git

manifests.git 是当前项目 manifest 仓的一个没有工作空间的 checkout,即只 checkout .git ,追踪repo init --manifest-url 指定的 Git 仓。不能手动修改这部分,如果需要修改的话,可重新运行 repo init 来更新设置。

.repo_config.json

缓存 manifests.git/config,用来提升 repo 的速度。

manifest.xml

repo 使用的 manifest , 此文件由 repo init --manifest-name 指定链接到 manifests 中的哪一个文件,如下:

1
manifest.xml -> manifests/<manifest-name>.xml # 指向用户希望用来同步源码的 manifest
Read more »

俗话说“雨过留痕,雁过留声”,之前因为工作需要折腾了小几个月的性能 BUG,还是得留下一点东西,这是第一篇:Android 性能调试手册,这篇文章简单聊聊工作中应该怎么进行性能分析。因为没有深入研究 Performance 相关内容,所以保留出错的权利。

0. 写在开头

在我司处理 Performance 问题时,大多数情况不会像顶级大厂那样优化每一帧,尽量榨干每一个硬件的性能。因为没有前人提供经验,全是自己总结的,如果存在有失偏颇的地方,你也只能看着。我理解的主要处理方式如下:

  • 第一种,推不解。

    • gaps 小, 个人经验是 10% 以内即可以尝试推不解,譬如:问题机 Chrome 启动时间为 800 ms, 对比机为 750 ms。
    • 分析出时间消耗,列出与对比机的对比, 详细阐述差分部分,一般来说大部分差分是原生代码引起,或者 gaps 很小。
  • 第二种嘛,当然就是想办法解决或优化了。

1. 怎么开始?

针对任何性能问题,我觉得第一步都先需要做如下三个确认:

  1. 确认问题现象,最好自己复现一次。
  2. 确认有没有大量 crash 发生。
  3. 查看 kernel footprint(config), 确认是否使用 perf config: msmxxx-perf_defconfig。
Read more »

“雨过留痕,雁过留声”的第二篇:APP 启动,触摸事件和 UI 绘制的简单分析示例,此文通过 systrace 分析一个示例 APP 的启动、触摸事件和 UI 绘制的流程和时间消耗。本文的示例 APP (SimpleApplication.apk)只有一个简单的按钮, 点击按钮时会改变屏幕的颜色。同样因为没有深入研究 Performance 相关内容,所以保留出错的权利。

如果对第一篇感兴趣,请查看: Android 性能调试手册.

0. 写在开头

我一开始看到 systrace 文件时,是一脸懵逼的,所以在开始正文之前先简单说一下 systrace 文件中的一些基本信息,如下:

  • Frames: 一个圆圈代表一帧。
    • 绿色:正常;
    • 黄色、红色: 异常,如卡顿、掉帧(Jank) 等,可能是它的渲染时间超过了 16.67ms(60fps)。
    • 点击圆圈可查看详细信息
  • Alerts: 右侧标签,跟踪记录中出现的问题以及这些问题导致出现卡顿的频率
  • system_server iq: 第一帧的触发
  • gfx3d_clk : GPU 频率
  • iq in systemsever : 触发中断
  • bindApplication, activityStart ...: 表示冷启动, 热启动不会有这些信息。
  • surfaceflinger->UI Thread->HIDL::IComposerClient:setPowerMode_2_2:client: 代表 LCD 上电时间

    一般使用 Chrome 打开 systrace.html, 右上角的 也可以提供一些基本的帮助

1. 获取 systrace

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
a. python systrace.py gfx input view sched am wm dalvik freq idle power video app -b 40960 -t 10 -o traceout.html

Explaination of these categories:
gfx - Graphics
input - Input
view - View System
wm - Window Manager
am - Activity Manager
hal - Hardware Modules
res - Resource Loading
dalvik - Dalvik VM
power - Power Management
sched - CPU Scheduling
freq - CPU Frequency
idle - CPU Idle

b. Motion: Click icon of SimpleApplication to open it, click first time to change background as white, click sencond time to change background as black.
Read more »

之前折腾局域网搭建 Gitbook,并写了一篇简易教程:Gitbook + Jenkins + Gitlab 搭建内网自动构建的 Gitbook。最近兴趣使然又用 docker 搭建了一套方便部署的内网 Gitbook 镜像,因此也总结一篇简易教程如下。

Install Docker

1
sudo apt install docker

Gitbook

Gitbook Image

下载 Gitbook Docker 镜像,我选择了 billryan/gitbook 镜像

1
docker pull billryan/gitbook

mkdir gitbook 创建一个 gitbook 路径,我们也可以将启动的镜像存储为另一个镜像:

1
2
3
4
5
6
7
8
# init
docker run --rm -v "$PWD/gitbook:/gitbook" -p 4000:4000 billryan/gitbook gitbook init
# serve
docker run --rm -v "$PWD/gitbook:/gitbook" -p 4000:4000 billryan/gitbook gitbook serve


docker ps # Get CONTAINER ID of gitbook
docker commit <CONTAINER ID> andylee/gitbook:1.0
Read more »

detached HEAD is a common situation, sometimes useful, sometimes dangerous. It doesn’t point to any branches, so it will be cleaned by git.

The current commit history is as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ git log --oneline --all --graph
* 5ea3cec (HEAD -> master) Modify README.md of src
* 2b6e826 Same file, same blob
* 1ff08f2 Modify README.md.
* 8c19a38 Add Copyright notice.
* 318c11a Copy css to lib.
| * 1134f9e (dev) Make graph more readability
| * 71c40d3 Modify README.md in dev branch.
|/
* ce4297f Add image.
| * 2cb23ac (dev-1.0) README for dev-1.0 branch.
|/
* 6fc4b44 (tag: kikoff_tag) Copy doc README.md
* 726c6c0 Add source README.md
* c8ff9c5 Add README
Read more »

.git directory acts a major role in git VCS. We can do local verson management directly depended on .git directory. I will parse .git in current topic.

Directory tree

First, I created a project and managed it through git, its directory tree is as follows:

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
.
├── doc
│   └── README.md
├── .git
│   ├── COMMIT_EDITMSG
│   ├── config
│   ├── description
│   ├── HEAD
│   ├── hooks
│   │   ├── applypatch-msg.sample
│   │   ├── commit-msg.sample
│   │   ├── fsmonitor-watchman.sample
│   │   ├── post-update.sample
│   │   ├── pre-applypatch.sample
│   │   ├── pre-commit.sample
│   │   ├── prepare-commit-msg.sample
│   │   ├── pre-push.sample
│   │   ├── pre-rebase.sample
│   │   ├── pre-receive.sample
│   │   └── update.sample
│   ├── index
│   ├── info
│   │   └── exclude
│   ├── logs
│   │   ├── HEAD
│   │   └── refs
│   │   └── heads
│   │   ├── dev
│   │   ├── dev-1.0
│   │   └── master
│   ├── objects
│   │   ├── 02
│   │   │   ├── 40351d75b3f451e0ec4b399c38c3758f007152
│   │   │   └── d8eae705ebf203142fd2f381d3b216dde2b28f
| | |...
│   │   ├── c8
│   │   │   └── ff9c55ce2651d8380a14bee5b43b37e14fa7fc
│   │   ├── f0
│   │   │   └── 45488f3fa9a350ac01f48f2b000fe51a53f5aa
│   │   ├── info
│   │   └── pack
│   ├── ORIG_HEAD
│   └── refs
│   ├── heads
│   │   ├── dev
│   │   ├── dev-1.0
│   │   └── master
│   └── tags
│   └── kikoff_tag
├── img
│   └── check.png
├── lib
│   └── css_practice_1.html
├── README.md
└── src
└── README.md
Read more »

Command Interface

We can enter command interface via the following ways.

  1. Excute init 3 with root.

    init run at runlevel 3.

  2. Hotkey: Ctrl + ALt + F1/2/3/…

init

init is the first process, it commonly locates on /sbin/init, if kernel can’t find init, it will try to run /bin/sh, if the operation fails , the OS will fail to start successfully.

init has 7 runlevels, we can check the default runlevel and runlevels in /etc/inittab. As follows:

1
2
3
4
5
6
7
8
9
10
# Default runlevel. The runlevels used are:
# 0 - halt (Do NOT set initdefault to this)
# 1 - Single user mode(root)
# 2 - Multiuser, without NFS (The same as 3, if you do not have networking)
# 3 - Full multiuser mode(standard runlevel)
# 4 - unused(secure mode)
# 5 - X11(user interface)
# 6 - reboot (Do NOT set initdefault to this)
#
id:5:initdefault:
Read more »

在使用 Ubuntu 的时候,有时候会遇到卡死的问题,然后电脑完全不能使用。这时候怎么办呢,我通常是通过如下两种方式进行处理:

Kill process

当我们明确知道什么进程导致系统卡死的时候,譬如文件管理器,我们可以通过如下两种方式进入字符终端找到假死的进程然后 kill 掉。

  1. Ctrl + Alt + F1 进入,Ctrl + Alt + F7 回到 UI 。
  2. ssh user@ip 远程登入。

杀死进程的方式,我常用的有三种,如下:

  1. Top 或者 htop 找到造成假死的进程并 kill
  2. 通过名字或者进程 PID 去杀进程。
    1
    2
    3
    4
    5
    ps -A |grep nautilus  # 查看文件管理器的 PID
    kill PID

    # 以名字的形式杀掉进程
    killall nautilus

Log out

注销桌面重新登录:

1
2
3
sudo pkill Xorg
或者
sudo restart lightdm