swap设置大小建议

1
2
3
4
5
6
7
8
9
10
11
- 安装系统时,选择swap分区;swap不是越大越好,越大的时候说明内存不够用,应该增加内存。
- redhat官方建议:
物理内存小于等于2GB的swap, 设置为物理内存的2倍
物理内存大于2GB小于等于8G时swap, 置为等同与物理内存的大小
物理内存大于8GB时swap, 置为大于等于4GB但不超过8GB。
- 建议
内存小于 4GB 时,推荐不少于 2GB 的 swap 空间
内存 4GB~16GB,推荐不少于 4GB 的 swap 空间
内存 16GB~64GB,推荐不少于 8GB 的 swap 空间
内存 64GB~256GB,推荐不少于 16GB 的 swap 空间
//实际我本机内存32G分配ubantu24G,仍然会报错,建议wsap大于16G

新建或修改swap分区

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
方案一:修改原有文件大小方式
第一步:进入系统根目录cd /;
第二步:执行:sudo dd if=/dev/zero of=/swap bs=1M count=16384 //每段块1M
共16384块,即16G
第三步:执行:sudo mkswap /swap // 激活swap空间
第四步:执行:sudo swapon /swap
最后,使用free -m命令,验证是否ok。

方案二:设置新的交换分区
进入根目录:cd /
创建一个新的交换分区文件:sudo dd if=/dev/zero of=/swap bs=1M count=16384
创建swap文件系统sudo mkswap -f swap;
开启新的swap sudo swapon swap
关闭并删除原有的swap文件sudo swapoff swapfile && sudo rm /swapfile
设置开机启动:将/etc/fstab中的swapfile改为swap
最后,使用free -h命令,验证是否ok。

设置linux物理内存使用多少开始使用swap的阈值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1.查询默认的值
- cat /proc/sys/vm/swappiness
- centos7默认值可能是30;就是当内存使用>=(100-30=70)%内存总量时,开始使用内存;
- 当值为0时,表示内存使用率>100%时使用内存,则表明不使用swap;
- 当值为100时,表示内存使用率>0%时使用内存,这样则无时无刻不使用swap;

2.如何修改swappiness(开启的阀值)
- 当使用内存>=90%时才使用内存;
- `临时设置`
sudo -i
echo 20 > /proc/sys/vm/swappiness
sysctl -p #生效
- `永久设置`
sudo -i
echo "vm.swappiness=20" >> /etc/sysctl.conf #永久修改
sysctl -p #生效
- 能有效使用内存,增强性能;如果机器一直长期超过70%的内存使用量,实际应该想想是不是要增加内存;

系统应用编译有2种方式:

1
2
3
4
5
1.源码编译(Aidegen):适用于需要与framework代码统一版本或修改较少的情况,
缺点是修改后无法直接运行需要单编后整编再运行查看效果;
2.源码导入Studio:适用于修改的地方较多的情况,
需要手动去把原生源码的代码提出来,手动剔除无用代码;
和普通app一样调试方便,但是需要注意与framework的版本管理;

下载指定版本的源码:

1
2
3
4
5
官网地址:https://android.googlesource.com/platform/packages/apps/
git clone https://android.googlesource.com/platform/packages/apps/Launcher3
如Launcher3:git clone -b android-13.0.0_r6 https://android.googlesource.com/platform/packages/apps/Launcher3
清华镜像:https://mirrors.tuna.tsinghua.edu.cn/git/AOSP
git clone -b android-13.0.0_r6 https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/packages/apps/Launcher3

问题:Failed to find Platform SDK with path: platforms;android-S

1
2
3
4
原因:gradle.properties中的COMPILE_SDK=android-S找不到,缺少sdk;
解决:
1.通过tool-SDK Manager-Android SDK中查看已安装的sdk版本如:android-13(对应的API LEVEL 33)
2.gradle.properties中的COMPILE_SDK修改为COMPILE_SDK=android-33

问题: Failed to connect to android.googlesource.com port 443 after 21168 ms: Timed out

1
2
3
4
5
6
7
8
9
10
原因:使用了vpn,浏览器可以正常访问aomedia.googlesource.com,但是使用git就报错,需要设置git也是用vpn
解决方案1:git config --global http.proxy 127.0.0.1:你的vpn所用端口号
//比如vpn默认代理端口是1080,那上面的命令就是git config --global http.proxy 127.0.0.1:1080
解决方案2:
在使用时,将 https://android.googlesource.com/ 全部使用清华镜像:
https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/ 代替即可。
例如:原来为
git clone https://android.googlesource.com/platform/packages/apps/Launcher3
替换为
git clone https://mirrors.tuna.tsinghua.edu.cn/git/AOSP//platform/packages/apps/Launcher3

整体目录介绍:

Android源码根目录 描述
art Android Runtime,一种App运行模式,区别于传统的Dalvik虚拟机,旨在提高Android系统的流畅性
abi abi 相关代码,abi:application binary interface,应用程序二进制接口
bionic bionic C 库
bootable 启动引导相关代码
build 存放系统编译规则及 generic 等基础开发配置包
compatibility 兼容性的一些资源
cts Android 兼容性测试套件标准
dalvik dalvik Java 虚拟机
developers Android开发者参考文档
development 应用程序开发相关
device 设备相关代码
disregard 清空 Android.mk 内容,以阻止 Android 构建系统更深入地扫描 Android.mk 的子目录。
docs 介绍开源的相关代码
external Android 使用的一些开源的模组
frameworks 核心框架 - Java 及 C++语言,是 Android 应用程序的框架
gdk 即时通信模块
hardware 主要是硬件适配层 HAL 代码
kernel Linux 的内核文件
libcore 核心库相关
libnativehelper 是 Support functions for Android‘s class libraries 的缩写,表示动态库,是实现 JNI 库的基础
ndk ndk 相关代码。Android NDK(Android Native Development Kit)是一系列的开发工具,允许程序开发人员在 Android 应用程序中嵌入 C/C++ 语言编写的非托管代码。
out 编译完成后的代码输出在此目录
packages 应用程序包
pdk Plug Development Kit 的缩写,是本地开发套件
platform_testing Android平台测试程序
prebuilts x86 和 ARM 架构下预编译的一些资源
sdk SDK 及模拟器
shortcut-fe 根据手机平台芯片改变,这里是高通xx加速
system 文件系统和应用及组件,是用 C 语言实现的
test Android Vendor测试框架
toolchain Android工具链
tools 工具文件夹
vendor 厂商定制代码
Makefile 全局的 Makefile

详细目录介绍:

art 目录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|-  benchmark    // 程序测试基准。
|- build // 编译文件。
|- cmdline // 命令行工具的初始化与解析。
|- compiler // 编译套件。
|- dalvikvm // Dalvik虚拟机启动程序。
|- dex2oat // 文件dex格式转换为oat格式的转换程序。
|- dexdump // 文件dex格式的内容获取程序。
|- dexlayout // 文件dex格式的布局。
|- dexlist // 文件dex格式的函数获取程序。
|- dexoptanalyzer //文件dex格式的分析程序
|- disassembler // 几种反汇编实现,包括arm64、arm、mips和x86。
|- imgdiag // image诊断程序。
|- libart_fake // 一个虚假的art库,用于那些企图链接ark库的作弊程序。
|- oatdump // 文件oat格式的内容获取程序。
|- patchoat // 文件oat格式的补丁管理程序。
|- profman // 程序性能分析助手。
|- runtime // art库实现,主要为C++和汇编文件。
|- sigchainlib // 信号处理库。
|- test // 测试程序。
|- tools // 一些工具,包括python和shell脚本。

bionic 目录

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
|-  libc    (C库)
|- arch-arm (ARM架构,包含系统调用汇编实现)
|- arch-mips (mips架构,包含系统调用汇编实现)
|- arch-x86 (x86架构,包含系统调用汇编实现)
|- bionic (由C实现的功能,架构无关)
|- include (头文件)
|- kernel (Linux内核中的一些头文件)
|- netbsd (nesbsd系统相关,具体作用不明)
|- private (一些私有的头文件)
|- stdio (标准输入输出的实现)
|- stdlib (标准库函数的实现)
|- string (标准字符串函数的实现)
|- tools (几个工具)
|- tzcode (时区相关代码)
|- unistd (unistd实现)
|- upstream-dlmalloc (包含由Doug Lea实现的malloc / free例程)
|- upstream-freebsd (这个目录包含上游FreeBSD的来源)
|- upstream-netbsd (这个目录包含上游NetBSD的来源)
|- wchar (字符串函数,具体作用不明)
|- zoneinfo (时区信息)
|- libdl (提供访问动态链接库的功能)
|- libm (libm数学库的实现)
|- arm (arm架构)
|- i386 (i386架构)
|- i387 (i387架构)
|- include (头文件)
|- mips (mips架构)
|- upstream-freebsd (这个目录包含上游FreeBSD的来源)
|- libstdc++ (libstdc++ C++实现库)
|- include (头文件)
|- src (源码)
|- libthread_db (多线程调试器库)
|- include (头文件)
|- linker (动态链接器)
|- tests (一些测试用例)
|- benchmarks // 程序测试基准。
|- build // 编译文件。

bootable目录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|-  recovery(系统恢复相关)
|- applypatch(二进制补丁文件)
|- edify(升级脚本使用的edify脚本语言)
|- etc(init.rc恢复脚本)
|- fonts(字体文件夹)
|- minadb(精简版的adbd守护进程)
|- minelf(updater的子项目使用的库)
|- minui(一个简单的UI)
|- minzip(一个简单的压缩工具)
|- mtdutils(读写flash的库)
|- res(在recovery模式中显示的一些图片)
|- simg2img (一个工具,将VMS Alpha executable文件转换成镜像文件)
|- testdata(里面的文件用于测试更新过程)
|- tools(工具)
|- ubi
|- updater(可执行文件运行更新脚本)

build目录

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
|-  core    (核心编译规则)
|- libs
|- host (主机端库,有android “cp”功能替换)
|- target (目标机编译对象)
|- board (开发平台)
|- emulator (模拟器)
|- generic (通用)
|- generic_armv5 (armv5)
|- generic_mips (mips)
|- generic_x86 (x86)
|- vbox_x86 (虚拟x86)
|- product (开发平台对应的编译规则)
|- security (密钥相关)
|- tools (编译中主机使用的工具及脚本)
|- acp (Android "acp" 命令)
|- apicheck (api检查工具)
|- atree (tree工具,类似于ls命令)
|- check_prereq (检查编译时间戳工具)
|- droiddoc (文档模板,用于生成使用Javadoc文档)
|- fs_config (主机工具的一部分)
|- fs_get_stats (获取文件系统状态)
|- imgpack
|- releasetools (生成镜像的工具及脚本)
|- rgb2565 (rgb转换为565)
|- signapk (apk签名工具)
|- zipalign (zip归档对齐工具)

dalvik目录

1
2
3
4
5
6
7
8
9
10
11
12
13
|-  dexdump (dex反汇编)
|- dexgen (敏捷项目代码生成器,使用gradle工具编译dex文件的解析工具)
|- dexlist (在一个或多个敏捷文件中列出所有具体类中的所有方法)
|- dexopt (预验证与优化)
|- docs (文档)
|- dx (dx工具,将多个java转换为dex)
|- hit (读HPRO文件)
|- libdex (dex相关的库)
|- opcode-gen (已定义的操作码和Dalvik的指令格式)
|- tests (测试代码)
|- tools (工具)
|- unit-tests (测试单元)
|- vm (虚拟机实现)

developers

1
2
3
|-  build   //gradle编译系统。
|- demos //使用了gradle的例子。
|- samples //AndroidSDK中的例子。

development目录

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
|-  apps(一些核心应用程序)
|- BluetoothDebug(蓝牙调试程序)
|- BuildWidget (定义一个简单小部件)
|- CustomLocale(自定义区域设置)
|- Development(开发系统应用)
|- DevelopmentSettings(开发系统应用设置)
|- Fallback(和语言相关的一个程序)
|- GestureBuilder(手势动作)
|- launchperf(装载前的预处理)
|- NinePatchLab // 点九图片相关
|- OBJViewer(OBJ查看器)
|- SdkSetup(SDK安装器)
|- SettingsInjectorSample // 高级设置
|- WidgetPreview(预览应用的小部件)
|- build(编译文件,包括打包用的atree文件)
|- cmds(有个monkey工具)
|- docs(文档)
|- host(主机端USB驱动等)
|- ide(集成开发环境)
|- libraries (立体相机库)
|- ndk(c/c++开发套件)
|- python-packages // python工具包,包括adb、fastboot和gdbrunner。
|- samples // 示例代码。
|- AccelerometerPlay // 展示加速计用法App
|- AdaptiveIconSample // 自适应图标App
|- Alarm // 紧急报警App
|- AliasActivity // 应用程序命别名App
|- AndroidBeamDemo // Android光束示例App
|- ApiDemosAPI // 演示程序
|- AppNavigation // 导航
|- BackupRestore // 备份
|- BasicGLSurfaceView // 基础GL界面展示
|- BluetoothChat // 蓝牙聊天
|- BluetoothHDP // 蓝牙传输
|- BluetoothLeGatt // 蓝牙4.0模块
|- BrokenKeyDerivation //
|- browseable // 浏览
|- BusinessCard // 车卡
|- Compass // 指南针
|- ContactManager // 联系人管理器
|- ControllerSample // 管理员示例
|- CrossCompatibility // 跨平台兼容
|- CubeLiveWallpaper // 动态壁纸的一个简单例程
|- DataWiper // 数据擦除
|- devbytes // 二进制读取
|- FixedGridLayout // 自动布局
|- HeavyWeight // 超重
|- HelloActivity // Hello
|- HelloEffects // Hello接收
|- Home // 家
|- HoneycombGallery // 动态图
|- JetBoy // jetBoy游戏
|- KeyChainDemo // 密码管理
|- LceDemo // 天线设备参数示例
|- LunarLander // LunarLander游戏
|- MultiResolution // 多任务处理应用
|- MultiWindow // 分屏应用
|- MySampleRss // RSS
|- NotePad // 记事本
|- Obb // 安卓游戏通用数据包示例
|- OpenGL // 图像库示例
|- RandomMusicPlayer // 音乐播放器
|- ReceiveShareDemo // 接收分享示例
|- RenderScript // 提升轮廓提取速度示例
|- RSSReader // RSS阅读器
|- samples_source.prop_template //
|- SampleSyncAdapter // 更新接口
|- SearchableDictionary // 目录搜索
|- ShortcutDemo // 小图标
|- ShortcutSample // 小图标示例
|- SimpleJNI // JNI例程
|- SipDemo // 支持会话发起协议(SIP)应用示例
|- SkeletonApp // 空壳APP
|- Snake // snake程序
|- SoftKeyboard // 软键盘
|- SpellChecker // 拼写检查
|- Spinner // Spinner控件
|- SpinnerTest // Spinner控件测试
|- StackWidget // 小部件堆叠示例
|- TicTacToeLib // 多库示例
|- TicTacToeMain // 主库示例
|- ToyVpn // vpn示例
|- training // 训练
|- TtsEngine // 文字语音转换(TTS)引擎
|- UiAutomator // ui自动测试
|- USB // usb使用
|- Vault // 缺陷控制
|- VoicemailProviderDemo // 读邮件应用示例
|- VoiceRecognitionService // 语音识别
|- WeatherListWidget // 天气小部件
|- WiFiDirectDemo // WIFI直连
|- WiFiDirectServiceDiscovery // WiFi直连服务发现
|- Wiktionary // 维基百科
|- WiktionarySimple // 维基百科示例
|- XmlAdapters // xml接口应用
|- scripts(脚本)
|- sdk(sdk配置)
|- sdk_overlay (覆盖资源文件用于不同的设备)
|- sys-img // 系统镜像信息。
|- testrunner(运行基于python的测试用例)
|- tools(一些工具)
|- tutorials (记事本教程和应用开发教程)
|- vndk // 供应商本地开发工具包

device 目录

1
2
3
4
5
6
7
8
9
|-  asus//华硕
|- common//设备间共有的配置。
|- generic//不同的CPU架构,包括arm、goldfish、emulator、mips、x86等。
|- google//谷歌
|- huawei//华为
|- lge//LG
|- linaro//Linario
|- qcom//高通
|- sample//例子

external目录

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
|-  aac    // Advanced Audio Coding,高级音频编码。
|- abi-compliance-checker // ABI兼容性分析工具。
|- abi-dumper // ABI数据解析工具。
|- alsa-lib
|- alsa-utils
|- android-clat // Android中用NAT64/DNS64支持IPv4的程序运行于IPv6的网络。
|- androidplot // Android中用以创建动态的或静态的图表。
|- android-mock (简单模拟的包装器)
|- ant-glob // ANT模式匹配工具。
|- antlr (语言识别工具// Language Recognition,一款语法分析器,可根据输入自动生成语法树并显示出来。 )
|- apache-commons-math // Apache数学库。
|- apache-harmony (一个具有类库和相关工具的模块化的java运行时,// Apache Java SE运行时类库及一些工具。 )
|- apache-http (网页服务器)// Apache HTTP服务。
|- apache-xml // Apache XML解决方案。
|- archive-patcher // 补丁管理库
|- arm-neon-tests // arm基于NEON指令的数学库
|- autotest // 自动测试框架,Python实现,起初用于Linux Kernel,后扩展到Chrome OS和Android。
|- avahi // Zeroconf规范的一种实现,可以在本地网络中发布和获知各种服务和主机。
|- avb // Ethernet Audio/Video Bridging,以太网音视频桥接技术。
|- arduino
|- bison (生成语法分析器)
|- blktrace (阻塞IO跟踪) // 收集磁盘IO信息中当IO进行到块设备层即block设备时的详细信息
|- boringssl // BoringSSL为OpenSSL的一个分支,优化了一些加密算法。
|- bluetooth (蓝牙相关、协议栈)
|- bouncycastle (加密的Bouncycastle.org项目)
|- bsdiff (bsdiff和bspatch项目)
|- busybox
|- bzip2 (压缩工具)// 基于Burrows-Wheeler算法的无损压缩技术。
|- c-ares // DNS请求异步处理库。
|- caliper // 基准测量工具。
|- cblas // C interface to Legacy BLAS。
|- ceres-solver
|- checkpolicy
|- chromium (chromium 工程)
|- chromium_org
|- chromium_libpac // 基于proxy_resolver_v8。
|- chromium_trace // 以HTML的形式显示数据使用情况。
|- chromium-webview // Webview。
|- clang (Clang 工程)
|- cmockery // 用于C程序的单元测试。
|- clearsilver
|- compiler-rt // Compiler Routine。
|- conscrypt // A Java Security Provider。
|- crcalc // Constructive Real Calculator。
|- cros // 一些常量和定义,只有一些头文件和proto文件。
|- curl // 文件传输
|- dagger2 // A fast dependency injector for Android and Java。
|- dbus // 数据总线,是一个低延迟,低开销,高可用性的ipc机制
|- dbus-binding-generator // dbus bind。
|- deqp // GPU测试框架。
|- dexmaker // dex maker
|- dhcpcd // DHCP client daemon(dhcp客户端的示例)
|- dlmalloc // malloc/free routines implemented by Doug Lea。
|- dng_sdk // DNG文件读写库。
|- dnsmasq (一个轻量级的、易于配置DNS转发器和DHCP服务器的工具)
|- doclava (生成文档的工具)
|- doclava // Javadoc工具。
|- drm_gralloc // gralloc for drm,Direct Rendering Manager。
|- drm_hwcomposer // hwcompositor for drm。
|- droiddriver // Android UI testing library
|- dropbear (小型的ssh服务器和客户端)
|- dtc // Device Tree Compiler。
|- e2fsprogs (维护ext2、ext3和ext4文件系统的工具)// 文件系统工具集
|- easymock (一个提供了简单方法的在单元测试时使用mock对象的工具)// 单元测试模拟框架
|- eclipse-basebuilder // eclipe插件编译相关
|- eclipse-windowbuilder // eclipse编译相关
|- eigen // 用于线性代数的C++模板库
|- elfutils (ELF文件相关的库和工具)
|- embunit (一个针对嵌入式C系统的单元测试框架)
|- emma // 单元测试覆盖率统计
|- esd // 音频相关
|- ethtool
|- exfat-fuse
|- expat (一个用于解析XML的C库)
|- eyes-free // 语音交互
|- fdlibm (一个用于可以支持IEEE 754浮点运算的机器的c数学库)
|- f2fs-tools // Flash Friendly File System。
|- fec // Forward error correction。
|- fio / io测试工具。
|- flatbuffers //
|- fmtlib // format。
|- fonttools // 字体处理工具。
|- freetype // 字体引擎。
|- fsck_msdos // 文件系统检查工具
|- ffmpeg
|- flac (FLAC工程的源码)// Free Lossless Audio Codec
|- fsck_msdos (ms-dos文件系统的检查代码)
|- fw_env
|- ganymed-ssh2
|- gcc-demangle
|- genext2fs (在普通用户的权限之下生成ext2文件系统)
|- giflib (gif图片库)
|- google-diff-match-patch
|- grub (多操作系统引导程序)
|- gtest (在不同的平台上编写C++测试用例的框架)
|- guava (开源的实用工具集合)// Google Core Libraries for Java
|- glide // media管理框架
|- gemmlowp // low-precision for general matrix multiplication。
|- google-benchmark // 支持benchmark的库,类似于单元测试。
|- google-breakpad // crash报告系统,包括client、server。
|- google-fonts // 字体。
|- googletest // C++ test framework。
|- google-tv-pairing-protocol // tv配对协议。
|- gptfdisk // 文本模式的磁盘分区工具。
|- guice // 依赖注入框架。
|- hamcrest (一个布局引擎库)// 用于测试的可以合成各种表达式的匹配器类库
|- harfbuzz
|- harfbuzz_ng // 字体排版引擎
|- hyphenation (一个使用tex断字模式的断字库)
|- hyphenation-patterns // 各种语言的字体连接模式。
|- icu // Unicode组件
|- icu4c (使用c/c++和java库来对应用程序提供Unicode和全球化支持)
|- iproute2 (iproute2是在Linux中控制tcp/ip网络的工具集合)
|- ipsec-tools (IPsec-Tools工程)// 加密的ip协议工具包
|- iptables (iptables工程)// IP信息包过滤系统
|- iputils // 网络工具包
|- ImageMagick // bitmap图片管理,支持多种格式。
|- ims // IP Multi-media System,包括rcs融合通信。
|- iw // Netlink 802.11
|- jacoco // 测试覆盖率工具。
|- jarjar // Java包管理工具。
|- javasqlite // sqlite
|- javassist // Java字节码编辑。
|- jcommander // 参数解析。
|- jdiff // Java代码比较工具。
|- jemalloc // 更好的内存管理工具,解决内存碎片问题。
|- jetty // servlet容器。
|- jline // 处理控制台输入。
|- jmdns // 多播DNS实现,可在本地局域网中发现和注册服务。
|- jsilver // HTML模板系统。
|- jsmn // JSON解析。
|- jsoncpp // C++处理JSON,序列化和反序列化。
|- jsr305 // Java Specification Request。
|- jsr330 // Java Specification Request。
|- junit // Java单元测试框架。
|- junit-params // jnit升级版,添加了更好用的参数化测试。
|- jhead (jpeg头部信息工具)
|- jmonkeyengine
|- jpeg (jpeg图像的压缩和解压缩)
|- jsr305
|- kernel-headers // Kernel级别头文件。
|- ksoap2 // 访问Web Service。
|- libavc // 流媒体
|- libcap-ng
|- libffi (libffi项目)
|- libgsm (网络数据包捕获函数)
|- liblzf (liblzf项目,一个非常快速的压缩算法)
|- libmtp
|- libnfc-nci
|- libnfc-nxp (来自NXP半导体的nfc库)
|- libnl-headers (网络相关的库)
|- libogg
|- libpcap (libcap的源码)
|- libphonenumber (google处理电话号码的库)
|- libpng (png格式的库)
|- libppp
|- libselinux
|- libsepol
|- libusb
|- libusb-compat
|- libvorbis
|- libvpx
|- libxml2 (xml解析库)
|- libxslt (XLST工具包的源代码)
|- libyuv
|- linux-kselftest // linux test。
|- libzvbi
|- linux-tools-perf
|- littlemock // mock框架
|- lld // LLVM linker
|- llvm (一个低级的虚拟机)// Low Level Virtual Machine
|- ltp // Linux Test Project
|- lz4 // 快速的无损压缩算法
|- lzma // 压缩
|- marisa-trie
|- markdown (文本转成html工具)
|- mdsnresponder // Appple Bonjour组件,方便IP网络配置。
|- mksh (最小的mkshrc应用程序的实现)// MirBSD Korn Shell
|- mockwebserver (用于测试http和https客户端的库)
|- mtd-utils
|- mesa3d // 三维计算机图形库
|- messageformat // International Components for Unicode for Java。
|- Microsoft-GSL // Guideline Support Library。
|- minijail // 沙盒,运行不信任的程序。
|- mmc-utils // mmc卡管理。
|- mockftpserver // 模拟FTP服务以进行FTP客户端测试。
|- mockito // 测试框架。
|- modp_b64 // base64编码、解码。
|- mp4parser // mp4解析。
|- mtpd // Media Transfer Protocol
|- netcat (简单的unix读写数据工具)// 网络使用查看工具
|- netperf (简单的unix网络性能测量工具)// 网络性能测试
|- nist-skip (VOIP实现的代码)// nist实现的sip协议,ip电话
|- ntfs-3g
|- nanohttpd // HTTP Server,用于嵌入其它的程序。
|- nanopb-c // ANSI-C实现的Protocol Buffer。
|- naver-fonts // 字体。
|- neven // 人脸识别算法。
|- nfacct // 流量统计。
|- nist-pkits // NIST PKI Test Suite。
|- noto-fonts // 汉语、日语、韩语字体。
|- oauth (oauth身份验证项目的代码)// 关于授权的开放网络标准
|- opencv (opencv的一个优化端口)// 计算机视觉库
|- openfst
|- openssh (ssh相关)
|- openssl (SSL加密相关)
|- open-vcdiff
|- oprofile (OProfile是一个低开销的分析器)
|- objenesis // Java对象实例化库。
|- okhttp // HTTP&SPDY Client。
|- opencv3 // 计算机视觉库。
|- owasp // Web Application。
|- pixman
|- pppoe (pppoe协议的源码)
|- proguard (ProGuard的源码)
|- parameter-framework // system-wide parameter management。
|- pcre // Perl兼容的正则表达式库。
|- pdfium // PDF渲染引擎。
|- piex // Preview Image Extractor。
|- ppp // Point to Point Protocol,链路层协议。
|- proguard // Java class file shrinker, optimizer, obfuscator and preverifier.
|- qemu (arm模拟器)
|- qemu-pc-bios (生成bios.bin和vgabios-cirrus.bin的源码)
|- remoteconf
|- regex-re2 // 正则表达式库。
|- replicaisland // A side scrolling video game for Android。
|- rmi4utils // Remote Method Invoke。
|- robolectric // 黑盒测试。
|- roboto-fonts // roboto font。
|- rootdev // Chromium OS version of rootdev。
|- safe-iop (safe-iop工程的源码)// safe integer operation
|- sepolicy
|- sil-fonts
|- skia (一个完整的2D图形库)
|- smack
|- sonivox (嵌入式音频合成项目的源码和二进制文件)
|- speex (一个开源的音频压缩格式)
|- sqlite (数据库)
|- srec (嵌入式语音识别引擎)
|- srtp (提供安全的实时传输协议的实现)
|- stlport (完整的ANSI C++标准库)
|- strace (系统跟踪工具)// system call tracer
|- stressapptest
|- svox (文字-语音转换工具)
|- scrypt // 加密相关。
|- seccomp-tests // Seccomp-BPF Kernel Self-Test Suite。
|- selinux // Secure Linux。
|- sfntly // 字体库。
|- shflags // shell script。
|- sl4a // Scripting Layer for Android。
|- slf4j // Simple Logging Facade for Java。
|- smali // Dalvik虚拟机的dex格式的汇编与反汇编。
|- snakeyaml // 用于Java虚拟机的YAML文件解析器。
|- sonic // 语音开发库。
|- sonivox // 语音开发库。
|- spirv-llvm // Khronos LLVM-SPIRV图形渲染语言格式转换
|- squashfs-tools // 只读的高压缩的文件系统。
|- swiftshader
|- syslinux
|- tagsoup (一个Java开发符合SAX的HTML解析器)
|- tcpdump (抓TCP包的软件)// 网络监听
|- tinyalsa (提供基本pcm和混合器API)// ALSA处理
|- tinyxml (用来解析某个特定的xml文件)
|- tinyxml2 // XML解析
|- tremolo (针对arm进行了优化的tremolo)
|- testng // 实机测试及数据收集。
|- timezonepicker-support // Time Zone。
|- tinycompress // 用于ALSA格式的读取,如mp3。
|- tinyxml // XML解析工具,C++实现。
|- tlsdate // 时间更新服务,TCP实现。
|- toybox // 命令行工具包。
|- tpm2 // Trusted Platform Module。
|- tremolo // ogg音频解压。
|- unicode // Unicode。
|- universal-tween-engine // Java对象插值
|- v8 (java脚本引擎)// JavaScript引擎,C++实现
|- valgrind (提供大量的调试和分析工具)// 内存、性能分析工具
|- verity
|- vboot_reference // Chrome OS verified boot in firmware。
|- vixl // ARMv8 Runtime Code Generation Library。
|- vogar // vogar.
|- volley/
|- vulkan-validation-layers // Vulkan组件,包括ICD Loader和Validation Layer。
|- webo (浏览器核心)
|- wpa_supplicant_6 (无线网卡管理)
|- webp // 处理WebP格式的图片。
|- webrtc // 支持浏览器、移动App的Real-time Communication。
|- wpa_supplicant_8 // WIFI Protected Access。
|- wycheproof
|- xmlwriter (XML 编辑工具)
|- x264
|- xmlrpcpp // XmlRpc协议的C++实现。
|- xmp_toolkit // xmp
|- yaffs2 (快速可靠的文件系统,针对nand flash和nor flash)
|- zlib (一个通用的数据压缩库)// 使用了DEFLATE算法的数据压缩库
|- zxing (一个大规模的精致低调的压缩库)// Java库,用于识别1D/2D条形码
|- zopfli // C库,一种压缩算法。

frameworks

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
|-  base    (基本内容)
|- api (api android application interface)
|- awt (AWT库)
|- build
|- camera (摄像头服务程序库)
|- cmds (重要命令:am、app_proce等)
|- core (核心库)
|- data (字体和声音等数据文件)
|- docs (文档)
|- graphics (图形相关)
|- include (头文件)
|- keystore (和数据签名证书相关)
|- libs (库)
|- location (地区库)
|- media (媒体相关库)
|- obex (蓝牙传输库)
|- opengl (2D-3D加速库)
|- packages (设置、TTS、VPN程序)
|- sax (XML解析器)
|- services (各种服务程序)
|- telephony (电话通讯管理)
|- test-runner (测试工具相关)
|- tests (各种测试)
|- tools (一些叫不上名的工具)
|- vpn (VPN)
- wifi (无线网络)
|- opt (可选部分)
|- com.google.android (有个framework.jar)
|- com.google.android.googlelogin (有个client.jar)
|- emoji (standard message elements)
|- policies (Product policies are operating system directions aimed at specific uses)
|- base
|- mid (MID设备)
|- phone (手机类设备,一般用这个)
|- av // 多媒体框架
|- camera // 多媒体的相机相关部分
|- cmds // 命令源码
|- drm // 数据保护
|- include // 头文件
|- media // 多媒体部分
|- radio // 无线射频部分
|- services // 服务部分
|- soundtrigger // 语音识别架构
|- tools // 工具包
|- base // base,包括以下几个目录。
|- apct-tests // 性能优化测试
|- api // java的api接口,修改了接口文件请及时更新此目录下的文件(make update-api)
|- cmds // 重要命令:am、app_proce等的源码
|- core // framework层核心库
|- java // java库
|- jni // jni层
|- proto // 协议层
|- res // 资源文件
|- tests // 测试工具
|- data // 字体和声音等数据文件
|- docs // 文档
|- drm // 数据保护
|- graphics // 图形相关
|- keystore // 和数据签名证书相关
|- legacy-test // 安全相关测试
|- libs // lib库
|- androidfw // fw功能库
|- common_time // 常用功能和工具集合,缓存,包括图片缓存、预取缓存、网络缓存;公共 View,即功能封装好的部件,包括下拉获得最新和上拉加载更多 ListView、底部加载更多 ScrollView、滑动一页 Gallery 等等。;常用工具类,包括网络、下载、资源操作、Shell、文件读写、Json、序列化/反序列化、随机数、集合(Array、List、Map)、APK 包等等。
|- hwui // 硬件渲染库
|- incident // 事件驱动机制库
|- input // 输入库
|- services // 服务库
|- storage // 存储库
|- usb // USB库
|- location // 定位功能
|- media // 媒体相关库
|- native // native框架
|- nfc-extras // nfc额外框架
|- obex // 蓝牙传输库
|- opengl // 2D-3D加速库
|- packages // 设置、TTS、VPN程序
|- proto // 协议框架
|- rs // 资源框架
|- samples // 例子程序
|- sax // XML解析器
|- services // 各种服务程序
|- telecomm // Telecom通信框架
|- telephony // 电话通讯框架
|- test-runner // 测试工具相关
|- tests // 各种测试
|- tools // 工具
|- vr // 虚拟现实相关
|- wifi // 无线
|- compile // 编译相关
|- libbcc // 用于Linux性能监视的动态跟踪工具的库
|- bcinfo // 获取硬件设备信息库
|- gdb_plugin // gdb插件
|- include // 头文件
|- lib // 库文件
|- tests // 测试程序
|- tools // 测试工具
|- mclinker // MCLinker链接器
|- include // 头文件
|- lib // 库文件
|- templates // 模板
|- tools // 工具
|- unittests // 单元测试工具
|- slang // 异常框架
|- data-binding // 数据绑定。
|- ex // ex文件解析器
|- camera2 // 相机相关
|- common // 共有的
|- framesequence // GIF图片工具包
|- photoviewer // 图片预览
|- widget // 小部件
|- hardware // 硬件适配接口
|- interfaces // 接口文件
|- current.txt // 接口记录文件
|- displayservice // 显示服务
|- schedulerservice // JobScheduler主要用于在未来某个时间下满足一定条件时触发执行某项任务的情况
|- sensorservice // 传感器服务
|- update-makefiles.sh // 更新makefile文件脚本
|- vr // 虚拟现实硬件接口
|- minikin // Android原生字体,连体字效果
|- ml // 机器学习
|- bordeaux //
|- learning // 学习算法
|- service // 服务
|- multidex // Multi-dex Loader。
|- native // native实现
|- aidl // aidl层,Android 接口定义语言
|- build // 编译配置
|- cmds // 命令行
|- data // 数据文件
|- docs // 文档
|- include // 头文件
|- libs // 库
|- arect // 图形库
|- binder // binder通信库
|- diskusage // 硬盘读取库
|- gui // ui显示库
|- hwc2on1adapter //
|- input // 输入库
|- math // 数学库
|- nativewindow // native窗口库
|- sensor // 传感器库
|- ui // ui库
|- vr // 虚拟现实库
|- opengl // 2D-3D接口框架
|- services // 服务
|- audiomanager // 音频服务
|- batteryservice // 电源服务
|- displayservice // 显示服务
|- inputflinger // 输入框架服务
|- nativeperms // 属性服务
|- powermanager // 电池管理
|- schedulerservice //事件消息服务
|- sensorservice // 传感器服务
|- surfaceflinger // 显示服务
|- vr // 虚拟现实服务
|- vulcan // 隐式框架
|- opt // 一些软件。
|- bitmap // 二进制图
|- bluetooth // 蓝牙
|- calendar // 日历
|- chips // 芯片工具
|- colorpicker // 色彩拾取工具
|- datetimepicker // 时间选择工具
|- emoji // standard message elements 表情
|- inputconnectioncommon // 输入连接工具
|- inputmethodcommon // 输入方法工具
|- net // 网络相关工具
|- ethernet // 有线网络
|- ims // ims
|- voip // 数据网络
|- wifi // 无线网络
|- photoviewer // 照片预览工具
|- setupwizard // 开机向导工具
|- telephony // 通信工具
|- timezonepicker // 时区工具
|- vcard // 芯片卡片工具
|- rs // Render Script,可创建3D接口。
|- support // framework支持文件
|- webview // webview framework层的接口
|- wilhelm // Wilhelm,基于Khronos的OpenSL ES/OpenMAX AL的audio/multimedia实现。

hardware

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
|-  libhardware    (硬件库)
|- include (头文件)
|- modules (Default (and possibly architecture dependents) HAL modules)
|- gralloc (gralloc显示相关)
|- overlay (Skeleton for the "overlay" HAL module.)
|- libhardware_legacy (旧的硬件库)
|- flashlight (背光)
|- gps (GPS)
|- include (头文件)
|- mount (旧的挂载器)
|- power (电源)
|- qemu (模拟器)
|- qemu_tracing (模拟器跟踪)
|- tests (测试)
|- uevent (uevent)
|- vibrator (震动)
|- wifi (无线网络)
|- msm7k (高通7k处理器开源抽象层)
|- boot (启动)
|- libaudio (声音库)
|- libaudio-qsd8k (qsd8k的声音相关库)
|- libcamera (摄像头库)
|- libcopybit (copybit库)
|- libgralloc (gralloc库)
|- libgralloc-qsd8k (qsd8k的gralloc库)
|- liblights (背光库)
- librpc (RPC库)
|- ril (无线电抽象层)
|- include (头文件)
|- libril (库)
|- reference-cdma-sms (cdma短信参考)
|- reference-ril (ril参考)
|- rild (ril后台服务程序)
- ti (ti公司开源HAL)
|- omap3 (omap3处理器)
|- dspbridge (DSP桥)
|- libopencorehw (opencore硬件库)
|- liboverlay (overlay硬件库)
|- libstagefrighthw (stagefright硬件库)
|- omx (omx组件)
|- wlan (无线网卡)
|- akm // AK8975传感器,包括SensorControl和HAL层的libsensors。
|- broadcom // Boradcom,包括libbt和wlan。
|- google // Google,包括Android Packet Filter。
|- intel // Intel,包括audio、media、bootstub、img、sensor等。
|- interfaces // HAL接口
|- audio // 音频
|- automotive // 车载
|- benchmarks // 标准库
|- bluetooth // 蓝牙
|- boot // 内核
|- broadcastradio // 无线广播
|- camera // 相机
|- libhardware // 硬件库
|- include // 头文件
|- modules //模块
|- audio // 音频
|- audio_remote_submix // 音频
|- camera // 相机
|- consumerir // 红外的脉冲序列
|- fingerprint // 指纹
|- gralloc // Gralloc模块,封装了对帧缓冲区的所有访问操作
|- hwcomposer // 视频渲染
|- input // 输入
|- local_time // 本地时钟
|- nfc // 短程通信
|- nfc-nci // 短程通信
|- power // 电源
|- radio // 射频
|- sensors // 传感器
|- soundtrigger // 音频触发
|- thermal // 终端
|- tv_input // 电视输入
|- usbaudio // usb音频
|- usbcamera // usb相机
|- vehicle // 车载
|- vibrator // 震动
|- vr // 虚拟
|- libhardware_legacy // hardware legacy
|- audio // 音频
|- include // 头文件
|- power.c // 电源
|- uevent.c // 事件

libcore

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|-  crypto
|- dex
|- dom(DOM的测试类)
|- expectations(测试的一些情况信息)
|- harmony-tests
|- include(头文件)
|- json(给予json的java实现)
|- libdvm
|- luni(加载.jar和.dex文件的测试源码)
|- support(测试虚拟机的测试类)
|- xml(xml的pull和push解析的实现)
|- benchmarks//标准库
|- dalvik//dalvik虚拟机
|- include//头文件
|- jsr166-tests//JSR是指向JCP提出新增标准化技术规范的正式请求,以向Java平台增添新的API和服务。JSR-166主要是关于J.U.C的技术规范(jdk5)
|- libart//art虚拟机库
|- ojluni//openjdkAPI
|- test-rules//测试规则
|- tools//工具
|- tzdata//时区解析

libnativehelper

1
2
3
|-  include // 头文件
|- platform_include // 平台头文件
|- tests // 测试程序。

ndk

1
2
3
4
5
6
7
8
9
10
11
12
13
14
|-  build
|- awk (辅助从应用的androidmanifest.xml中提取信息的一些脚本)
|- core (创建NDK的一些makefile)
|- gmsl (GNU的make标准库)
|- tools (仅用于开发NDK的一些脚本)
|- docs (NDK相关的文档)
|- sources (NDK的源码和库)
|- android (cpufeatures和libthread_db的源码)
|- cpufeatures
|- cxx-stl
|- host-tools (linux主机的一些工具)
|- third_party
|- tests (测试相关)
|- toolchains (基于arm和x86架构的工具链)

packages

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
|-  apps     (应用程序库)
|- AlarmClock (闹钟)
|- Bluetooth (蓝牙)
|- Browser (浏览器)
|- Calculator (计算器)
|- Calendar (日历)
|- Camera (相机)
|- CertInstaller (在Android中安装数字签名,被调用)
|- Contacts (拨号(调用)、联系人、通话记录)
|- DeskClock (桌面时钟)
|- Email (Email)
|- Gallery (相册,和Camera类似,多了列表)
|- Gallery3D (3D相册)
|- GlobalSearch (为google搜索服务,提供底层应用)
|- GoogleSearch (google搜索)
|- HTMLViewer (浏览器附属界面,被浏览器应用调用,同时提供存储记录功能)
|- IM (即时通讯,为手机提供信号发送、接收、通信的服务)
|- Launcher (登陆启动项,显示图片框架等等图形界面)
|- Launcher2 (登陆启动项,负责应用的调用)
|- Mms (彩信业务)
|- Music (音乐播放器)
|- PackageInstaller (安装、卸载程序的响应)
|- Phone (电话拨号程序)
|- Provision (预设应用的状态,使能应用)
|- Settings (开机设定,包括电量、蓝牙、设备信息、界面、wifi等)
|- SoundRecorder (录音机,可计算存储所需空间和时间)
|- Stk (SIM卡开发工具)
|- Sync
|- Updater
|- VoiceDialer (语音通话)
|- inputmethods (输入法)
|- LatinIME (拉丁文输入法)
|- OpenWnn (OpenWnn输入法)
|- PinyinIME (拼音输入法)
|- providers (提供器,提供应用程序、界面所需的数据)
|- ApplicationsProvider (应用程序提供器,提供应用程序启动项、更新等)
|- CalendarProvider (日历提供器)
|- ContactsProvider (联系人提供器)
|- DownloadProvider (下载管理提供器)
|- DrmProvider (创建和更新数据库时调用)
|- GoogleContactsProvider (联系人提供器的子类,用以同步联系人)
|- GoogleSubscribedFeedsProvider(设置信息提供器)
|- ImProvider
|- ManagementProvider
|- MediaProvider (媒体提供器,提供存储数据)
|- TelephonyProvider (彩信提供器)
|- UserDictionaryProvider (用户字典提供器,提供用户常用字字典)
|- WebSearchProvider
|- services
|- EasService
|- LockAndWipe
|- wallpapers (墙纸)
|- Basic (基本墙纸,系统内置墙纸)
|- LivePicker (选择动态壁纸)
|- MagicSmoke (壁纸特殊效果)
|- MusicVisualization (音乐可视化,图形随音乐而变化)
|- apps // 各种app。
|- BasicSmsReceiver // 基础短信接收
|- Bluetooth // 蓝牙
|- Browser2 // 浏览器
|- Calendar // 日历
|- Camera2 // 相机
|- Car // 车载
|- CarrierConfig // 运营商配置
|- CellBroadcastReceiver // 小区广播服务
|- CertInstaller // 在Android中安装数字签名,被调用
|- Contacts // 联系人
|- DeskClock // 桌面时钟
|- DevCamera // 相机
|- Dialer // 拨号盘
|- DocumentsUI // 下载
|- Email // 邮件
|- EmergencyInfo // 工程信息
|- ExactCalculator // 计算器
|- Gallery // 图库
|- Gallery2 // 图库
|- HTMLViewer // HTML阅读器
|- KeyChain // 秘钥链
|- Launcher2 // 桌面启动器
|- Launcher3 // 桌面启动器
|- LegacyCamera // 安全相机
|- ManagedProvisioning //
|- Messaging // 短信
|- Music // 音乐
|- MusicFX // MusicFX是一款系统专用的音频控制面板
|- Nfc // 短程通信
|- OneTimeInitializer // 谷歌服务框架
|- PackageInstaller // 安装
|- Phone // 电话
|- PhoneCommon // 电话
|- Protips // 主屏幕提示
|- Provision // 预设应用的状态,使能应用
|- QuickSearchBox // 搜索框
|- RetailDemo //
|- SafetyRegulatoryInfo // 安全监管
|- Settings // 设置
|- SoundRecorder // 录音
|- SpareParts // 高级设置
|- SpeechRecorder // 录音机
|- Stk // SIM卡智能工具包
|- StorageManager // 存储管理
|- Tag // 标签
|- Terminal // 终端
|- Test // 测试
|- TV // 电视
|- TvSettings // 电视设置
|- UnifiedEmail // 未定义邮件
|- WallpaperPicker // 壁纸
|- experiment // 非release/public的测试程序。
|- BugReportSender // bug上传测试
|- Bummer // 懒汉测试
|- CameraPreviewTest // 相机预览测试
|- DreamTheater //
|- ExampleImsFramework // ims框架测试
|- FilledApp // apk上限测试
|- FillService // 服务上限测试
|- InstantCookieApp // 小程序
|- LoaderApp // 加载apk
|- MultiPackageApk // 安卓多渠道打包工具
|- NotificationListenerSample // 消息监听测试
|- NotificationLog // 消息log测试
|- NotificationShowcase // 消息展示测试
|- PermissionApp // 权限测试
|- PrintApp // 打印测试
|- PrintService // 打印服务测试
|- procstatlog //
|- RpcPerformance // 远程过程调用测试
|- StrictModeTest // StrictMode最常用来捕捉应用程序的主线程,它将报告与线程及虚拟机相关的策略违例
|- TestBack // 回测
|- inputmethods // 输入法,包括LatinIME和OpenWnn。
|- LatinIME // 拉丁文输入法
|- OpenWnn // OpenWnn输入法
|- providers // 各种provider。
|- ApplicationsProvider // 应用程序提供器,提供应用程序启动项、更新等
|- BlockedNumberProvider // 黑名单电话提供器
|- BookmarkProvider // 书签提供器
|- CalendarProvider // 日历提供器
|- CallLogProvider // 通话记录提供器
|- ContactsProvider // 联系人提供器
|- DownloadProvider // 下载管理提供器
|- MediaProvider // 媒体提供器,提供存储数据
|- PartnerBookmarksProvider // 浏览器书签提供器
|- TelephonyProvider // 彩信提供器
|- TvProvider // 电视提供器
|- UserDictionaryProvider // 用户字典提供器,提供用户常用字字典
|- screensavers // 屏保
|- Basic // 默认屏保应用
|- PhotoTable // 照片屏保应用
|- WebView // 网络屏保应用
|- services // 各种service。
|- BuiltInPrintService // 预览打印服务
|- Car // 车载服务
|- Mms // 短信服务
|- NetworkRecommendation // 网络建议
|- Telecomm // Telecom通信服务
|- Telephony // Telephony通话服务

pdk

1
2
3
4
5
6
|-  apps // 平台测试应用
|- HelloPDK // 平台测试示例
|- TestingCamera // 相机测试
|- TestingCamera2 // 相机测试
|- build // 编译配置
|- util // 工具包

platform_testing

1
2
3
4
5
|-  build // 平台测试       
|- libraries // lib库
|- scripts // 脚本
|- tests // 测试
|- utils // 工具包

prebuilts

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
|-  abi-dumps // applicationbinary interface,应用程序二进制接口的内存镜像调试工具
|- android-emulator // Android模拟器,由external/qemu/android/scripts/package-release.sh生成。
|- build-tools // Ninja编译系统的辅助工具。
|- checkcolor // 色彩规范检查
|- checkstyle // Java编码规范检查。
|- clang // c/c++/object-c代码编译器。
|- deqp // Draw Elements Quality Program,适用于OpenGL ES/OpenCL的GPU应用分析。
|- devtools // 开发工具,如常见的adt、android、ddms、lint等。
|- eclipse // eclipse。
|- gcc // gcc。
|- gdb // gdb。
|- go // go。
|- gradle-plugin // gradle插件。
|- libs // libedit,这是NetBSD Editline库(libedit)的自动工具和libtoolized端口。 这个Berkeley风格的授权命令行编辑器库提供了通用的行编辑,历史记录和标记化功能,与GNU Readline中的类似。
|- maven_repo // maven。
|- misc // 宏指令系统。
|- ndk // ndk。
|- python // python。
|- qemu-kernel // qemu 内核,QEMU是一套由法布里斯·贝拉(Fabrice Bellard)所编写的以GPL许可证分发源码的模拟处理器,在GNU/Linux平台上使用广泛。Bochs,PearPC等与其类似,但不具备其许多特性,比如高速度及跨平台的特性,通过KQEMU这个闭源的加速器,QEMU能模拟至接近真实电脑的速度。
|- sdk // 开发包。
|- tools // 工具
|- android-arm (arm-android相关)
|- gdbserver (gdb调试器)
|- kernel (模拟的arm内核)
|- android-x86 (x86-android相关)
|- kernel
|- common (通用编译好的代码,应该是java的)
|- darwin-x86 (drawin x86平台)
|- toolchain (工具链)
|- arm-eabi-4.2.1
|- arm-eabi-4.3.1
|- arm-eabi-4.4.0
|- darwin-x86_64 (drawin x86 64bit平台)
|- linux-x86 (linux x86平台)
|- toolchain (工具链,我们应该主要用这个)
|- arm-eabi-4.2.1
|- arm-eabi-4.3.1
|- arm-eabi-4.4.0
|- i686-unknown-linux-gnu-4.2.1 (x86版编译器)
|- linux-x86_64 (linux x86 64bit平台)
|- windows (windows平台)
|- windows-x86_64 (64bit windows平台)

sdk

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
|-  annotations // 注释源码  
|- apkbuilder // apk打包工具源码
|- apps // sdk自带的应用
|- DeviceConfig // 设备配置
|- NotificationStudio // 消息提示
|- SdkController // sdk管控
|- attribute_stats // 属性状态
|- avdlauncher // 模拟器启动
|- bash_completion // bash工具
|- build // sdk编译配置
|- docs // 文档
|- dumpeventlog // 事件记录log
|- eclipse // eclipse开发sdk配置
|- emulator // 模拟器源码
|- eventanalyzer // 事件分析
|- files // 文件
|- find_java // java文件查找
|- find_java2 // class文件查找
|- find_lock // 锁查找
|- hierarchyviewer // hierarchyviewer工具源码
|- icons //
|- sdklauncher // sdk加载源码
|- settings // sdk设置源码
|- templates // 模板
|- testapps // 测试应用

system

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
|-  bt // 蓝牙相关        
|- ca-certificates // 证书颁发机构
|- chre // 校验读出
|- connectivity // WIFI,包括wificond和wifilogd两个daemon。
|- wificond // WIFI配置
|- wifilogd // WIFI 的log系统
|- core // 系统核心工具盒接口。
|- adb // adb调试工具
|- adf // ADF file format解析库
|- base // 通用基础库
|- bootstat // 记录启动状态工具库
|- cpio // cpio工具,创建img
|- debuggerd // 调试工具
|- demangle // 还原库
|- fastboot // 快速启动相关
|- fingerprintd // 指纹库
|- fs_mgr // 磁盘引导头
|- gatekeeperd // 锁屏密码服务系统接口
|- healthd // healthd是android4.4之后提出来的一种中介模型,该模型向下监听来自底层的电池事件,向上传递电池数据信息给framework层的batteryservice用以计算电池电量相关状态信息,batteryservice通过传递来的数据来计算电池电量显示,剩余电量,电量级别等信息
|- include // 系统接口头文件
|- init // init程序源代码
|- libappfuse // AppFuse是一个集成了众多当前最流行开源框架与工具(包括Hibernate、ibatis、Struts、Spring、DBUnit、Maven、Log4J、Struts Menu、Xdoclet、SiteMesh、OSCache、JUnit、JSTL等(现在还有lucene的,无敌了))于一身的Web开发框架。AppFuse提供了Web系统开发过程中都需要开发的一些功能,如登陆、用户密码加密,用户管理、根据不同的用户可以展现不同的菜单.J2EE开发者也可以在此基础上开发加入自己的功能模块。利用这个框架可以大幅度的提高开发速度
|- libbacktrace // 进程堆栈库
|- libbinderwrapper // binder底层库
|- libcrypto_utils // 加密库
|- libcutils // 网络工具库
|- libdiskconfig // 磁盘配置库
|- libgrallocusage // 显示系统库
|- libion // ION是Google的下一代内存管理器,用来支持不同的内存分配机制,如CARVOUT(PMEM),物理连续内存(kmalloc), 虚拟地址连续但物理不连续内存(vmalloc), IOMMU等
|- liblog // log库
|- libmemtrack // 内存堆栈库
|- libmemunreachable //
|- libmetricslogger //
|- libnativebridge // native层库
|- libnativeloader // native加载库
|- libnetutils // 网络工具包库
|- libpackagelistparser //包解析库
|- libpixelflinger // Pixelflinger是Android系统中为OpenGLES引擎提供的一套软件渲染器(renderer)。OpenGLES引擎提供了一系列基础绘图功能。这些功能包括定义各种颜色格式像素位置、画点画线、绘制矩形及三角形、填充纹理等等。由于OpenGLES相当于一个状态机,配置OpenGLEs状态的函数也均由Pixelflinger提供
|- libprocessgroup // 进程组库
|- libprocinfo // 系统属性信息
|- libsparse // 稀疏矩阵库
|- libsuspend // 跟电源管理相关
|- libsync // 网络数据同步开发库
|- libsysutils // 系统工具库
|- libunwindstack // libunwind库为基于64位CPU和操作系统的程序提供了基本的堆栈辗转开解功能
|- libusbhost // usb库
|- libutils // 系统基本库
|- libziparchive // zip压缩算法库
|- lmkd // 低内存库
|- logcat // logcat工具源码
|- logd // log进程
|- logwrapper // log封装工具
|- mkbootimg // 制作启动boot.img的工具盒脚本
|- reboot // 重启
|- rootdir // rootfs,包含一些etc下的脚本和配置
|- run-as // 权限控制
|- sdcard // SD卡管理器
|- shell_and_utilities // shell工具包
|- storaged // 存储
|- toolbox // toolbox,类似busybox的工具集
|- trusty // 授权底层
|- tzdatacheck // 时区检查底层
|- extras // 核心库之外的程序,包括以下几个目录。
|- alloc-stress // 内存释放
|- ANRdaemon // 系统无响应库
|- app-launcher // launcher应用库
|- boot_control_copy // boot控制复制
|- bootctl // boot控制
|- brillo_config // Brillo 系统配置
|- cppreopts //
|- cpustats // cpu状态
|- crypto-perf // 加密性能分析工具
|- ext4_utils // ext4文件系统
|- f2fs_utils // f2fs文件系统
|- ioshark // io流操作泄露回收
|- iotop // io操作相关
|- kexec_tools // Kexec是Linux和Xen提供的软重启和崩溃转储工具。 这个页面是kexec各种工作的反弹点
|- ksmutils // KSM是一种节省内存的重复数据删除功能,可以合并匿名(专用)页面(不是页面缓存)。 虽然它是以这种方式开始的,但KSM目前适用于不止于虚拟机的使用,因为它对任何生成相同数据的许多实例的应用程序都是有用的
|- latencytop // a tool for software developers ,identifying system latency happen
|- libfec // fec库
|- libpagemap // pagemap库
|- librank // rank库
|- memcpy-perf // 内存性能分析
|- memory_replay // 内存重写
|- memtrack // 内存堆栈
|- micro_bench // sim相关
|- mmap-perf // 系统级性能分析工具
|- multinetwork // 多网络系统实现
|- pagecache //
|- perfprofd // 系统安装相关
|- postinst //
|- preopt2cachename // dex文件优化相关
|- procmem // 用于查看系统中的内存使用情况,procrank可以查看系统中所有进程的整体内存占用情况,并按照规则排序
|- procrank // 用于查看系统中的内存使用情况,procmem可以针对某个特定的进程分析其堆、栈、共享库等内存占用情况
|- puncture_fs //
|- runconuid //
|- sane_schedstat // 射频库
|- showmap // showmap工具
|- showslab // showslab工具
|- simpleperf // Simpleperf是Android平台的一个本地层性能分析工具。它的命令行界面支持与linux-tools perf大致相同的选项,但是它还支持许多Android特有的改进
|- slideshow // 幻灯片展示
|- sound // 声音相关
|- squashfs_utils // SquashFS是一套基于Linux内核使用的压缩只读文件系统。该文件系统能够压缩系统内的文档,inode以及目录,文件最大支持2^64字节。
|- su // su命令源码
|- systrace_analysis // 系统性能分析
|- taskstats // 任务管理
|- tests // 测试工具
|- tools // 工具
|- verity // 认证
|- zram-perf // ZRAM是linux的一种内存优化技术,基本工作原理是:通过划定一片区域,将压缩过后的硬盘数据放入该区域,以实现高速读取
|- gatekeeper // 防护程序,如锁屏密码等。
|- hardware //
|- hwservicemanager // Hardware Service Manager。
|- keymaster // HAL密钥管理。
|- libfmq // Message Queue。
|- libhidl // Hardware Interface Description Language。
|- libhwbinder // Hardware Binder。
|- libufdt // Unflattened Device Tree。
|- libvintf // Vendor Interface。
|- media // 包括alsa、audio、brillo、camera和radio。
|- nativepower // 用于Brillo的电源管理模块,包括客户端的libnativepower和服务端的nativepowerman以及示例代码。
|- netd // 网络模块,包括client和server。
|- nfc // Near Field Communication。
|- nvram // NVRAM访问控制。
|- security // 安全模块,包括keystore和软件模拟的softkeymaster。
|- sepolicy // Android SELinux policy configuration。
|- tools // 包括aidi和hidl。
|- tpm // Trusted Platform Module,一种安全防御工具。
|- update_engine // 系统升级。
|- vold // Volume服务,如sdk卡、usb等。

test 目录

1
2
|-  vts // Vendor Test Suite。       
|- vts-testcase // VTS测试用例,包括fuzz、kernel、performance和security。

tools 目录

1
2
3
4
5
6
7
8
|-  apksig // APK签名,包括一个Java库和一个Java命令行工具。      
|- external // 外部工具,包括以下几个目录。
|- fat32lib // 用于FAT文件系统。
|- gradle // Gradle各种版本的源码压缩包。
|- loganalysis // log分析的Java类库。
|- repohooks // 用于repo upload,报告各仓库的修改情况。
|- test // 测试框架,Python实现。
|- tradefederation // 服务于测试。

vendor

1
2
3
4
5
6
7
8
9
10
11
12
13
|-  aosp     (android open source project)
|- products (一些板级规则)
|- qcom (高通的配置)
|- sample (google提供的样例)
|- apps (应用)
|- client (用户)
|- upgrade (升级)
|- frameworks (框架)
|- PlatformLibrary (平台库)
|- products (产品)
|- sdk_addon (sdk添加部分)
|- skins (皮肤)
|- WVGAMedDpi (WVGA适用的图片)

cts 目录

1
2
3
4
5
6
7
8
9
|-  apps // cts测试所使用的apk源码        
|- build // cts套件的编译配置
|- common // cts套件的通用代码
|- development // cts套件兼容之前使用eclipse ADT开发apk的脚本
|- hostsidetests // cts套件新增host测试项
|- libs // cts套件使用的第三方库
|- suite // cts套件
|- tests // cts套件进行的测试项
|- tools // cts套件使用的测试工具源码

out // 编译产生的目录

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
|- host // 在主机PC host上使用的工具,包括二进制程序以及JAVA的程序)  
|- common
|- obj // JAVA 库
|- linux-x86
|- bin // 二进制程序
|- framework // JAVA 库,*.jar 文件
|- lib // 共享库*.so
|- obj // 中间生成的目标文件
|- target // 在目标机(如ARM)上运行的内容,多数编译资源会暂存在这里
|- common // common表示通用的内容
|- R // 资源文件
|- docs
|- obj // 目标文件,APPS中包含了打成APK包的JAVA应用程序, JAVA_LIBRARIES中包含了JAVA的库
|- product // product 中则是针对产品的内容
|- generic
|- android-info.txt
|- clean_steps.mk
|- symbols
|- obj // obj/APPS目录中包含了各种打成了APK包的JAVA应用,obj/SHARED_LIBRARIES中存放所有动态库,obj/STATIC_LIBRARIES中存放所有静态库
|- root/
|- ramdisk.img // 对应于root/目录,挂载在/
|- system/
|- system.img // 挂载在system/目录,包括了主要系统apps,priv-apps
|- data/
|- userdata.img // 挂载在data/目录,用户数据
|- userdata-qemu.img

常用CMake 语法

一. cmake 版本号声明

1
2
# 声明一个我们使用的最小版本
cmake_minimum_required(VERSION 3.10.2)

二. 设置项目名称

1
2
# 这个项目名称一般和生成的库名称相同
project(test)

三. 添加头文件搜索目录

1
include_directories(../../../include)

四. 添加源文件

1
2
3
4
# 使用变量添加
set(SOURCES test.cpp xxx.cpp)
# 添加所有
FILE(GLOB SRCS "*.CPP" "*.h")

五. 生成一个库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
动态库和静态库的区别:
动态库是共享的
静态库是独占的
举个例子就是,有两个应用程序,A和B,他们两个都依赖 test.so
,这个test.so在内存中就只有一份,占用也是一份内存

如果我们给test库打包成test.a,那么A和B会各自独占一份test.a那么在内存上,就会占用两份空间

add_library( # Sets the name of the library.
srt-lib # 库的名字

# Sets the library as a shared library.
SHARED # 动态库

# Provides a relative path to your source file(s).
srt-lib.cpp srt1-lib.cpp) # 源文件列表

六. 搜索一个库(预构建库)

1
2
3
4
5
6
7
find_library( # Sets the name of the path variable.
log-lib # 可以理解别名

# Specifies the name of the NDK library that
# you want CMake to locate.
log # 这个是liblog.so 在ndk目录中自带的一个库
)

七. 设置一个变量

1
2
# 设置LIBDIR为 ${CMAKE_CURRENT_SOURCE_DIR}/../../../libs/${ANDROID_ABI}
set(LIBDIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../libs/${ANDROID_ABI})

八. 导入预构建库

1
2
3
4
5
6
# 导入静态库
add_library(ssl STATIC IMPORTED)
set_target_properties(srt PROPERTIES IMPORTED_LOCATION ${LIBDIR}/libssl.a)
# 导入动态库
add_library(ssl SHARED IMPORTED)
set_target_properties(srt PROPERTIES IMPORTED_LOCATION ${LIBDIR}/libssl.so)

九. 链接库

1
2
3
4
5
6
target_link_libraries( # Specifies the target library.
test

# Links the target library to the log library
# included in the NDK.
${log-lib})

十. 设置库的输出目录

1
set_target_properties(test PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY_${ARCH}})

NDK概念及疑问

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
1.ndk是什么
NDK是一个工具集,允许你的App使用一些底层语言代码,例如C和C++。针对特定类型的应用,能使用C和C++的代码,
将会很有用,因为这样你可以复用已经存在的C和C++库代码。
2.jni是什么
- Java Native Interface Java本地接口,
- Java层调用本地C,C++等
- JNI是Java调用本Native语言的一种特性,与Android无直接关系
- 实际中的驱动都是C/C++开发的,通过JNI,Java可以调用C/C++实现的驱动,从而扩展Java虚拟机的能力。另外,
在高效的数学运算、游戏的实时渲染、音视频的编码和解码等方面,一般都是用C开发的。
3.为什么用ndk
- 进一步提升设备性能,以降低延迟或运行游戏或物理模拟等计算密集型应用。
- 重复使用您自己或其他开发者的 C 或 C++ 库。
4.ndk的开发资料
- 官方文档:https://developer.android.google.cn/ndk?hl=zh_cn
5.ndk的学习方法
- 参考官方文档学习
6.交叉编译概念
- 交叉编译就是程序的编译环境和实际运行环境不一致,即在一个平台上生成另一个平台上的可执行代码。
- 比如NDK,你在Mac、Win或者Linux上生成的C/C++的代码要在Android平台上运行,就需要使用到交叉编译了。
-通俗点说就是你的电脑和手机使用的CPU不同,所以CPU的指令集就不同,比如arm的指令集在X86上就不能运行。
7.预编译库及非预编译库是什么
- 预编译库是指已经经过编译的二进制文件,可以直接在 Android 应用中使用如静态库(.a)或共享库(.so)。
预编译库可以直接加载到应用程序中,并通过JNI与 Java 层进行交互
- 非预编译库是指将 C/C++ 代码直接放在 Android 项目中,并在构建时进行编译,这种方式会将 C/C++ 代码与 Java 代码一起
编译成最终的应用程序,而不是单独生成预编译库。
8.cmake是什么以及它的常用语法
- CMake 是一个跨平台的构建工具,用于管理和构建 C/C++ 项目。它提供了简洁易用的语法和命令来描述项目的构建过程,
并自动生成与构建环境相关的构建脚本,使项目能够方便地在不同的平台上进行构建。
- 见 CMake语法.md文件

常用CMake 语法

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

一. cmake 版本号声明
# 声明一个我们使用的最小版本
cmake_minimum_required(VERSION 3.10.2)

二. 设置项目名称
# 这个项目名称一般和生成的库名称相同
project(test)

三. 添加头文件搜索目录
include_directories(../../../include)

四. 添加源文件
# 使用变量添加
set(SOURCES test.cpp xxx.cpp)
# 添加所有
FILE(GLOB SRCS "*.CPP" "*.h")

五. 生成一个库
动态库和静态库的区别:
动态库是共享的
静态库是独占的
举个例子就是,有两个应用程序,A和B,他们两个都依赖 test.so
,这个test.so在内存中就只有一份,占用也是一份内存

如果我们给test库打包成test.a,那么A和B会各自独占一份test.a那么在内存上,就会占用两份空间

add_library( # Sets the name of the library.
srt-lib # 库的名字

# Sets the library as a shared library.
SHARED # 动态库

# Provides a relative path to your source file(s).
srt-lib.cpp srt1-lib.cpp) # 源文件列表

六. 搜索一个库(预构建库)
find_library( # Sets the name of the path variable.
log-lib # 可以理解别名

# Specifies the name of the NDK library that
# you want CMake to locate.
log # 这个是liblog.so 在ndk目录中自带的一个库
)

七. 设置一个变量
# 设置LIBDIR为 ${CMAKE_CURRENT_SOURCE_DIR}/../../../libs/${ANDROID_ABI}
set(LIBDIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../libs/${ANDROID_ABI})

八. 导入预构建库
# 设置LIBDIR为 ${CMAKE_CURRENT_SOURCE_DIR}/../../../libs/${ANDROID_ABI}
set(LIBDIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../libs/${ANDROID_ABI})

九. 链接库
target_link_libraries( # Specifies the target library.
test

# Links the target library to the log library
# included in the NDK.
${log-lib})


十. 设置库的输出目录
set_target_properties(test PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY_${ARCH}})

NDK中打印日志

1
2
3
4
5
6
7
8
9
10
11
#include <android/log.h>
#define LOG_TAG "tyl"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
//通过#define的宏定义组装我们的__android_log_print方法

extern "C"
JNIEXPORT jint JNICALL
Java_com_tyl_ndk_1study_MainActivity_add(JNIEnv *env, jobject thiz, jint a, jint b) {
LOGI("a+b=%d",a+b); //输出则为a+b=3,tag=tyl
return a+b;
}

NDK开发实际集成源码的场景

1.使用Android Studio 源码直接集成

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

- 新建项目时选择Table的时候滑倒最后选择Native C++,main目录下会自动添加一个cpp目录里面就是c++文件;
- 使用示例:
public native int add(int a, int b);//在MainActivity中新增方法,新建的方法会报红,
//鼠标放到报红的地方alt+enter出现Create JNI function for add按钮,点击会自动在cpp文件中创建jni的add方法;
extern "C"
JNIEXPORT jint JNICALL //java+包名+方法名
Java_com_tyl_myjnistudy_MainActivity_add(JNIEnv *env, jobject thiz, jint a, jint b) {
return a+b;
}
//上面是cpp文件中的代码,在方法中实现自己的逻辑代码即可;
//activity中使用再加载了库后 System.loadLibrary("ndkdemo"),直接调用方法执行即可;

完整代码:
//MainActivity
public class MainActivity extends AppCompatActivity {
static {
System.loadLibrary("ndkdemo");
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.e("tyl","add="+add(1,2));
}
public native String stringFromJNI();
public native int add(int a, int b);
}

//native-lib.cpp
#include <jni.h>
#include <string>
#include <android/log.h>
#define LOG_TAG "tyl"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)

extern "C" JNIEXPORT jstring JNICALL
Java_com_tyl_ndkdemo_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
extern "C"
JNIEXPORT jstring JNICALL
Java_com_tyl_ndk_1study_MainActivity_stringFromJNI(JNIEnv *env, jobject thiz) {
// TODO: implement stringFromJNI()
}
extern "C"
JNIEXPORT jint JNICALL
Java_com_tyl_ndk_1study_MainActivity_add(JNIEnv *env, jobject thiz, jint a, jint b) {
LOGI("a+b=%d",a+b);
return a+b;
}

2.使用命令编译出符合平台相关的预编译库

配置ndk环境

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1.下载并安装 NDK

打开 Android Studio。
点击菜单栏中的 “File”,选择 “Project Structure”。
在弹出的窗口中,选择 “SDK Location”。
在 “Android NDK location” 的文本框中,点击 “Download” 按钮。
在弹出的 “SDK Components Setup” 窗口中,勾选 “LLDB” 和 “CMake”,然后点击 “Next”。
在 “SDK Platforms” 窗口中,选择你需要的 NDK 版本,并点击 “Next”。
在 “SDK Tools” 窗口中,选择 “LLDB” 和 “CMake”,然后点击 “Finish”。
Android Studio 将自动下载并安装 NDK。
4. 配置 Android Studio 的 NDK 路径
现在,我们需要配置 Android Studio 的 NDK 路径,以便在项目中正确使用 NDK。

2.打开 Android Studio。
点击菜单栏中的 “File”,选择 “Project Structure”。
在弹出的窗口中,选择 “SDK Location”。
在 “Android NDK location” 的文本框中,填入你的 NDK 路径。
如果你使用默认的 Android Studio 安装路径,NDK 路径应为:<Android Studio 安装路径>/ndk/<NDK 版本号>。
例如:C:\android\android-studio\ndk\22.0.7026061
点击 “OK” 保存配置。

2.1.test.cpp 测试的c++文件

1
2
3
4
5
6
7
8
#include <iostream>
#include "test.h"
using namespace std;
int test::add(int a, int b) {

std::cout << "a: " << a << " b: " << b << std::endl;
return a + b;
}

2.2.test.h 测试的c++头文件

1
2
3
4
5
6
7
#ifndef TEMPLATE_TEST_H
#define TEMPLATE_TEST_H
class test {
public:
int add(int a, int b);
};
#endif

2.3.CMakeLists.txt cmake编译文件

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

cmake_minimum_required(VERSION 3.22.1)

project(test)
set(CMAKE_CXX_STANDARD 17)

# 设置NDK路径
set(ANDROID_NDK "/home/jiangc/Android/Sdk/ndk/25.1.8937393" CACHE PATH "Android NDK path")

# 设置架构,用来设置输出目录
set(ARCHS "armeabi-v7a" "arm64-v8a" "x86" "x86_64")

# 设置Android API级别
set(ANDROID_API_LEVEL 22)

# 添加每个架构的输出目录
foreach(ARCH ${ARCHS})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${ARCH} ${CMAKE_CURRENT_SOURCE_DIR}/libs/${ARCH})
endforeach()

# 设置头文件
include_directories(.)

# 设置源文件
set(SOURCES test.cpp)

# 编译某一个架构的
function(build_library ARCH)
set(CMAKE_ANDROID_ARCH_ABI ${ARCH})
set(CMAKE_ANDROID_NDK ${ANDROID_NDK})
set(CMAKE_SYSTEM_NAME Android)
set(CMAKE_SYSTEM_VERSION ${ANDROID_API_LEVEL})
add_library(test SHARED ${SOURCES})
set_target_properties(test PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY_${ARCH}})
endfunction()

message("--------------------------------------------- ${ANDROID_ABI}")
build_library(${ANDROID_ABI})

2.4.build.sh

1
2
3
4
5
6
7
8
9
10
11
//遇到的问题:
1. bash: ./build.sh: /bin/bashsM: bad interpreter: No such file or directory
原因是window环境过去的文件,用vim -b 打开会看到很多^M的字符
解决方式:vim -b 打开,shift+: 组合键输入: %s/\r//g 回车后后:wq保存退出
2./build.sh: line 2: cmake: command not found
原因是未安装cmake,
解决方式:sudo apt install cmake
3.Make Error at CMakeLists.txt:1 (cmake_minimum_required):
CMake 3.22.1 or higher is required. You are running version 3.16.3
原因是CMakeLists.txt文件中的最低版本号过高,
解决方案是:打开CMakeLists.txt将cmake_minimum_required(VERSION 3.22.1)修改为cmake_minimum_required(VERSION 3.16.3)
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
#!/bin/bash

rm build -rf
rm libs -rf

mkdir build
cd build

ANDROID_NDK="/home/jiangc/Android/Sdk/ndk/25.1.8937393"

ARCHS=('armeabi-v7a' 'arm64-v8a' 'x86' 'x86_64' )

function compile(){

for i in ${ARCHS[@]}; do
cmake -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \
-DANDROID_ABI="$i" \
-DANDROID_NDK=$ANDROID_NDK \
-DANDROID_PLATFORM=android-22 \
..
make
done
}

compile

:<<!

cmake -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \
-DANDROID_ABI="armeabi-v7a" \
-DANDROID_NDK=$ANDROID_NDK \
-DANDROID_PLATFORM=android-22 \
..

make

cmake -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \
-DANDROID_ABI="arm64-v8a" \
-DANDROID_NDK=$ANDROID_NDK \
-DANDROID_PLATFORM=android-22 \
..

make

cmake -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \
-DANDROID_ABI="x86" \
-DANDROID_NDK=$ANDROID_NDK \
-DANDROID_PLATFORM=android-22 \
..

make


cmake -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \
-DANDROID_ABI="x86_64" \
-DANDROID_NDK=$ANDROID_NDK \
-DANDROID_PLATFORM=android-22 \
..

make

!

1
2
./build.sh //执行编译
成功后生成lib包,里面包含有各个版本的so文件

3.使用Android Studio 直接集成预编译库

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
//1.导入资源
app目录下新建include文件夹,将test.h文件导入
将so包复制到lib路径下

//2.修改CMakeLists.txt添加资源

cmake_minimum_required(VERSION 3.16.3)
project("ndkdemo")

# 包含头文件
include_directories(../../../include)
# 设置依赖库路径
set(LIBDIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../libs/${ANDROID_ABI})
# 库的导入
add_library(test SHARED IMPORTED)
set_target_properties(test PROPERTIES IMPORTED_LOCATION ${LIBDIR}/libtest.so)

add_library( # Sets the name of the library.
ndkdemo
SHARED
native-lib.cpp)

foreach(item RANGE 1 5 2)
message("item = ${item}")
endforeach(item)


find_library( # Sets the name of the path variable.
log-lib
log)
#添加 test
target_link_libraries( # Specifies the target library.
ndkdemo
test
${log-lib})

//3.make androidStudio同步文件后,导入test.h及使用示例
#include <jni.h>
#include <string>
#include <android/log.h>
#include "../../../include/test.h"

#define LOG_TAG "tyl"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
extern "C"
JNIEXPORT jint JNICALL
Java_com_tyl_ndk_1study_MainActivity_add(JNIEnv *env, jobject thiz, jint a, jint b) {
LOGI("a+b=%d",a+b);
test t;
int c= t.add(3,4);
LOGI("A+B=%d",c);
return a+b;
}

Retrofit简介

1
2
Retrofit 是一个Square开发的安卓客户端请求库。其中内部封装了okhttp库。
官方的介绍是使用非常简短 Retrofit使用注解,能够极大的简化网络请求数据的代码;

与其它网络库的对比

1
2
3
4
AndroidAsynHttp
- 基于HttpClient作者已停止维护,Android5.0不再使用HttpClient,因此不推荐使用。
Volley
- 基于HttpUrlConnection,Google官方推出,只适合轻量级网络交互如数据传输小,不适合大文件下传下载场景;

Retrofit优点

1
API设计简洁易用、注解化配置高度解耦、支持多种解析器、支持Rxjava

Retrofit使用

1.Retrofit开源库、OkHttp网络库、数据解析器集成注册网络权限

1
2
3
4
5
6
//依赖包导入
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.okhttp3:okhttp:3.14.9'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
//网络权限
<uses-permission android:name="android.permission.INTERNET"/>

2.创建接口设置请求类型与参数

1
2
3
4
5
新建UserInfoModel类和UserMgrService接口
public interface RequestInterface {
@GET("login")
Call<LoginBean> getCloseTime(@Query("ip") String devideIp);
}

请求示例

//假设BASE_URL = “http://192.168.0.1/

@Url

1
2
3
//整个地址都要变化,甚至是baseUrl
@GET
Call<List<Repo>> getData(@Url String user);

@Path

1
2
3
4
//用于替换Url路径中的变量字符。
@GET("weather/{city_name}")
Observable<Object> getWeather(@Path("city_name") String city_name);
//完整结果:http://192.168.0.1/weather/北京

2.1Get请求

@Query

1
2
3
4
//主要用于Get请求数据,用于拼接在拼接在Url路径后面的查询参数,一个@Query相当于拼接一个参数,多个参数中间用,隔开。
@GET("weather")
Observable<WeatherEntity> getWeather(@Query("city") String city);
//完整结果:http://192.168.0.1/weather?city=北京

@QueryMap

1
2
3
4
//主要的效果等同于多个@Query参数拼接,主要也用于Get请求网络数据。
@GET("weather/{city_name}")
Observable<Object> getWeather(@Path("city_name") String city_name, @QueryMap Map<String, String> queryParams);
//完整结果:http://192.168.0.1/weather/北京?user_id=1&user_name=jojo

2.2Post请求

@Filed

1
2
3
4
5
6
//@Field的用法类似于@Query,于拼接在拼接在Url路径后面的查询参数。
@FormUrlEncoded //使用@Field时记得添加@FormUrlEncoded
@POST("comment")
void doComments(@Field("content") String content, @Field("user_id") String user_id);
//完整结果:http://192.168.0.1/comment
//body参数:{content":"我是评论","user_id":"1001"}

@FieldMap

1
2
3
4
5
6
7
//用法类似于@QueryMap,主要用于Map拼接多个参数
@FormUrlEncoded
@POST("comment")
void doComments(@FieldMap Map<String, String> paramsMap );
// HashMap<String, String> hashMap = new HashMap<>();
// hashMap.put("content","我是评论");
// hashMap.put("user_id","1001");

@Body

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//例1
@POST("comment")
void doComments(@Body Object reqBean);
//例2
@POST("comment")
void doComments(@Body List<Object> requestList);
//例3 文件上传
@POST("upload/")
Observable<Object> uploadFile(@Body RequestBody requestBody);
//只不过文件上传传入的是RequestBody类型,下面是构建RequestBody的方式:
File file = new File(mFilePath); //mImagePath为上传的文件绝对路径
//构建body
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("file", file.getName(), RequestBody.create(MediaType.parse("multipart/form-data"), file))
.build();

2.3Put请求

1
2
3
@PUT("comment/{comment_id}")
void comment(@Path("comment_id") String comment_id);
//完整结果:http://192.168.0.1/comment/88
1
2
3
@PUT("comment/{comment_id}")
void comment(@Path("comment_id") String comment_id @Query("user_id") String user_id);
//完整结果:http://192.168.0.1/comment/88?user_id=1001
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//加body参数:{"content":"我是评论","type":"1"}
//此类请求的应用场景:适合于body中需要传入多个请求参数,这样可以将多个请求的参数字段封装到一个实体中,这样就不用写多个@Filed了
public class RequestBean {
public String content;
public String type;
//实际中可能还有多个请求字段
}
...
RequestBean requestBean = new RequestBean();
requestBean .content = "我是评论";
requestBean .type = "1";
...
@PUT("comment/{comment_id}")
void comment(@Path("comment_id") String comment_id @Query("user_id") String user_id @Body RequestBean reqBean);

2.4Delete

1
2
3
@DELETE("comment/{comment_id}")
void comment(@Path("comment_id") String comment_id);
//假如删除评论:http://192.168.0.1/comment/88

综上所述,可以归纳出上面几个注解的用法:

1
2
3
4
5
6
@Path : 请求的参数值直接跟在URL后面时,用@Path配置
@Query: 表示查询参数,以?key1=value1&key2=value2的形式跟在请求域名后面时使用@Query
@QueryMap :以map的方式直接传入多个键值对的查询参数
@Field: 多用于post请求中表单字段,每个@Field后面,对应一对键值对。
@FieldMap :以map的方式传入多个键值对,作为body参数
@Body: 相当于多个@Field,以对象的形式提交

注意:Filed和FieldMap需要FormUrlEncoded结合使用,否则会抛异常!

3.创建Retrofit对象、设置数据解析器

1
2
Retrofit retrofit = new Retrofit.Builder().baseUrl("http://149.0.171.247:8088/")
.addConverterFactory(GsonConverterFactory.create().build();

baseUrl:

1
2
3
这里的baseUrl是自己访问的Url的基类地址,加上刚才@GET(“login”)中的login才是我们真正要访问的地址,
因为使用了@Query("ip"),所以最终的访问地址为http://149.0.171.247:8088/login?ip=devideIp,此处的ip为自己传入的参数。
注意: baseUrl必须要以/结尾!!!

4.生成接口对象

1
RequestInterface service= retrofit.create(RequestInterface.class);

5.调用接口方法返回Call对象

1
Call<LoginBean> call=service.login("zhangsan""123456")

6.发送请求(同步、异步)

1
2
3
4
5
6
7
8
9
10
11
12
13
同步:调用Call对象的execute(),返回结果的响应体
异步:调用Call对象的enqueue0,参数是一个回调

call.enqueue(new Callback<LoginBean>() {
@Override
public void onResponse(Call<LoginBean> call, Response<LoginBean> response) {

}
@Override
public void onFailure(Call<LoginBean> call, Throwable t) {

}
});

问题:

1
2
3
4
5
6
7
使用时别忘了申请网络权限哦,使用时可能会遇到以下问题:
CLEARTEXT communication to mock-api.com not permitted by network security policy

这是因为Android P不允许明文访问,而前面的mock地址是http开头的,
解决办法是在AndroidManifest中的application内加入下面这段代码即可:

android:usesCleartextTraffic="true"

一、Retrofit工具类的封装(核心类)

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
 /**
* Retrofit工具类
*/
public class RetrofitUtils {
public static final String BASE_URL = "http://XXX";
/**
* 超时时间
*/
public static final int TIMEOUT = 60;
private static volatile RetrofitUtils mInstance;
private Retrofit mRetrofit;

public static RetrofitUtils getInstance() {
if (mInstance == null) {
synchronized (RetrofitUtils.class) {
if (mInstance == null) {
mInstance = new RetrofitUtils();
}
}
}
return mInstance;
}

private RetrofitUtils() {
initRetrofit();
}

/**
* 初始化Retrofit
*/
private void initRetrofit() {
OkHttpClient.Builder builder = new OkHttpClient.Builder();
// 设置超时
builder.connectTimeout(TIMEOUT, TimeUnit.SECONDS);
builder.readTimeout(TIMEOUT, TimeUnit.SECONDS);
builder.writeTimeout(TIMEOUT, TimeUnit.SECONDS);
OkHttpClient client = builder.build();
mRetrofit = new Retrofit.Builder()
// 设置请求的域名
.baseUrl(BASE_URL)
// 设置解析转换工厂,用自己定义的
.addConverterFactory(ResponseConvert.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(client)
.build();
}

/**
* 创建API
*/
public <T> T create(Class<T> clazz) {
return mRetrofit.create(clazz);
}
}

代码很简单,创建后台请求接口,调用create即可。

二、Converter.Factory的封装

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
/**
* 自定义Gson解析转换
*/
public class ResponseConvert extends Converter.Factory {
public static ResponseConvert create() {
return new ResponseConvert();
}

/**
* 转换的方法
*/
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
return new BodyConverter<>(type);
}

private class BodyConverter<T> implements Converter<ResponseBody, T> {
private Gson gson;
private Type type;

public BodyConverter(Type type) {
this.type = type;
gson = new GsonBuilder()
.registerTypeHierarchyAdapter(List.class, new ListTypeAdapter())
.create();
}

@Override
public T convert(ResponseBody value) throws IOException {
String json = value.string();
return gson.fromJson(json, type);
}
}

/**
* 空列表的转换
*/
private static class ListTypeAdapter implements JsonDeserializer<List<?>> {
@Override
public List<?> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
if (json != null && json.isJsonArray()) {
JsonArray array = json.getAsJsonArray();
Type itemType = ((ParameterizedType) typeOfT).getActualTypeArguments()[0];
java.util.List list = new ArrayList<>();
for (int i = 0; i < array.size(); i++) {
JsonElement element = array.get(i);
Object item = context.deserialize(element, itemType);
list.add(item);
}
return list;
} else {
//和接口类型不符,返回空List
return Collections.EMPTY_LIST;
}
}
}
}

三、Retrofit网络请求基类的封装

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
/**
* 后台统一接口API
*/

public interface ServerApi {
// 联系人编辑
@POST(URLS.LOGIN)
Observable<ResponseBean<LoginBean>> login(@Body RequestBody requestBody);
}

/**
* 请求网络业务的基类,AppPresenterr 的封装
*/

public class AppPresenter {
protected ServerApi mApi = RetrofitUtils.getInstance().create(ServerApi.class);
private static final Gson gson = new Gson();

/**
* 1. 转换
* 统一处理一些动作
*/
public static <T> void convert(Observable<ResponseBean<T>> observable, Observer<T> observer) {
observable
.map(new Function<ResponseBean<T>, T>() {
@Override
public T apply(ResponseBean<T> httpResult) throws Exception {
// 打印响应的对象
LogUtils.object(httpResult);
// TODO 实际开发的时候统一处理一些东西
if (httpResult == null || httpResult.head == null) {
throw new RuntimeException("请求数据异常");
} else if (!"1".equals(httpResult.head.bcode)) {
throw new RuntimeException(httpResult.head.bmessage);
}
return httpResult.data;
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(observer);
}

/**
* 2. 执行的方法
*/
public static <T> void execute(Observable<ResponseBean<T>> observable, Observer<ResponseBean<T>> observer) {
observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(observer);
}

/**
* 3.请求数据是Json,Json转成RequestBody
*/
public static RequestBody createRequestBody(Object obj) {
RequestBean bean = new RequestBean<>(obj);
String json = gson.toJson(bean);
// 打印请求的Json
LogUtils.json(json);
RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), json);
return body;
}

}
有三个通用的方法:
1.convert方法,转换、统一处理网络请求,将公共处理部分放在这方法里面。
2.execute方法,只执行,不做任何处理操作,适用于一些不能统一处理的接口。
3.createRequestBody方法,就是统一创建请求的RequestBody。

四、具体网络请求业务类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* 登录的业务类
*/

public class LoginPresenter extends AppPresenter {
/**
* 登录的接口
*/
public void login(LoginData data, Observer<LoginBean> observer) {
Observable<ResponseBean<LoginBean>> login = mApi.login(createRequestBody(data));
// 转换
convert(login, observer);
}
}

五、测试和使用

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* 调用登录接口
*/
public void open(View view) {
LoginData loginData = new LoginData("135****5219", "12***56");
presenter.login(loginData, new DialogObserver<LoginBean>(getAppActivity()) {
@Override
public void onNext(LoginBean data) {
// TODO 做登录的成功的操作
Toast.makeText(getAppActivity(), "" + data.userInfo.nickName, Toast.LENGTH_SHORT).show();
}
});
}

六、补充,对于Observer需要再次封装。

1
2
3
4
1.如调用登录要显示Dialog
2.如Activity销毁要取消请求。
3.结合加载数据各种状态页面,如:加载中、加载失败、网络异常、数据为空等等
这些都是可以统一封装在Observer<T>里面。

工具类原文:https://www.jianshu.com/p/7f843d65a7c6

11.专项技术优化

一、列表页卡顿优化

常规方案

1
2
1.convertView复用、使用ViewHolder
2.耗时任务异步处理

布局相关

1
2
1.减少布局层级、避免过度绘制
2.异步inflate或者X2C

图片相关

1
2
1.避免过大尺寸:GC频繁、内存抖动
2.滑动时取消加载

线程相关

1
2
1.使用线程池收敛线程,降低线程优先级
2.避免UI线程时间片被抢占

TextView优化

1
2
3
4
5
6
1.原因:面对复杂文本性能不佳
2.BoringLayout 单行、StaticLayout 多行
3.DynamicLayout可编辑
4.展示类StaticLayout即可,性能优于DynamicLayout
5.异步创建StaticLayout
6.facebook/TextLayoutBuilder

其它

1
SysTrace跟踪

二、存储优化

常规方案

1
2
1.确保IO操作发生在非主线程
2.Hook或者是AOP辅助

SharePreferences相关

1
2
3
加载慢:初始化加载整个文件
全量写入:单次改动都会导致整体写入
卡顿:补偿策略导致

SharePreferences替代者MMKV

1
2
3
mmap和文件锁保证数据完整
增量写入、使用Protocol Buffer
支持从SharePreferences迁移

日志存储优化

1
2
大量服务需要日志库支持
对于性能的要求:不影响性能、日志不丢失、安全

常规实现

1
2
3
每产生一个日志,写一遍到磁盘中:不丢失、性能损耗
开辟一个内存buffer,先存buffer,再存文件:丢日志

mmap

1
2
内存映射文件
优势:高性能、不丢失

业界实现:Xlog、Logan

其它

1
2
常用数据的缓存,避免多次读取
合理选择缓冲区Buffer大小:4-8KB

三、WebView异常监控

简介

1
2
1.重要控件
2.问题:性能与适配

问题

1
WebView版本及对接业务方众多

思路

1
2
1.监控屏幕是否白屏,白屏则WebView有问题
2.确认白屏:所有像素一直则认为白屏
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
package com.optimize.performance.webview;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.os.Build;
import android.view.View;

import java.util.Arrays;

/**
* WebView白屏检测
*/
public class BlankDetect {

/**
* 判断Bitmap是否都是一个颜色
* @param bitmap
* @return
*/
public static boolean isBlank(View view) {
Bitmap bitmap = getBitmapFromView(view);

if (bitmap == null) {
return true;
}
int width = bitmap.getWidth();
int height = bitmap.getHeight();
if (width > 0 && height > 0) {
int originPix = bitmap.getPixel(0, 0);
int[] target = new int[width];
Arrays.fill(target, originPix);
int[] source = new int[width];
boolean isWhiteScreen = true;
for (int col = 0; col < height; col++) {
bitmap.getPixels(source, 0, width, 0, col, width, 1);
if (!Arrays.equals(target, source)) {
isWhiteScreen = false;
break;
}
}
return isWhiteScreen;
}
return false;
}

/**
* 从View获取转换到的Bitmap
* @param view
* @return
*/
private static Bitmap getBitmapFromView(View view){
Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
if (Build.VERSION.SDK_INT >= 11) {
view.measure(View.MeasureSpec.makeMeasureSpec(view.getWidth(), View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(view.getHeight(), View.MeasureSpec.EXACTLY));
view.layout((int) view.getX(), (int) view.getY(), (int) view.getX() + view.getMeasuredWidth(), (int) view.getY() + view.getMeasuredHeight());
} else {
view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
}
view.draw(canvas);
return bitmap;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//使用
public class TestBlankActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.testblank);
final TextView textView = findViewById(R.id.tv_testblank);
textView.postDelayed(new Runnable() {
@Override
public void run() {
boolean isBlank = BlankDetect.isBlank(textView);
LogUtils.i("isBlank "+ isBlank);
}
},2000);
}
}
10.稳定性优化
1
2
3
4
5
//稳定性优化
1.统一编码规范、增强编码功底、技术评审
2.架构优化:统一容错,功能模块解耦
3.回归测试,压力测试,兼容性测试,
4.容灾方案:热更新(bugly),功能开关,崩溃后自启等

一、如何提升App的稳定性

正确认识

1
2
1.稳定性是大问题,Crash是PO优先级
2.稳定性可优化的面很广

稳定性纬度

1
2
3
1.Crash纬度
2.性能纬度
3.业务高可用纬度

稳定性优化概述

1
2
3
1.重在预防、监控必不可少
2.思考更深一层、重视隐含信息
3.长效保持需要科学流程

二、高Crash率的破解之道

Crash相关指标

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1.UV、PV Crash率(uv主要针对用户使用量,用户使用崩溃率,pv是用户使用的频率,用户使用崩溃的频率)
- UV Crash率= Crash UV/DAU
- UV 方便评估用户影响范围,结合 PV
- 注意:沿用同一种衡量方式
2.Java、Native Crash率
3.启动、重点流程Crash率
4.增量、存量Crash率
5.启动Crash率(启动时崩溃)
- 影响最严重的Crash
- 结合客户端容灾
6.增量、存量Crash率(增量指新增的crash,存量指以前老版本就存在的crash)
- 增量Crash是新版本重点
- 存量Crash是持续啃的硬骨头
- 优先解决增量、持续跟进存量
7.Crash率评价
- 务必在千分之二以下
- Crash率万分位优秀

Crash关键问题

1
2
3
4
5
6
7
8
9
10
11
12
尽可能还原Crash现场
- 堆栈、设备、OS版本、进程、线程名、Logcat
- 前后台、使用时长、App版本、小版本、渠道
- CPU架构、内存信息、线程数、资源包信息、行为日志
APM后台聚合展示
- Crash现场信息
- Crash Top机型、OS版本、分布版本、区域
- Crash起始版本、上报趋势、是否新增、持续、量级
责任归属
- 专项小组轮值
- 自动匹配分配
- 处理流程全记录

整体结构

1
2
3
4
1.采集层:错误堆栈、设备信息、行为日志、其它信息
2.处理层:数据清洗、数据聚合、纬度分类、趋势对比
3.展示层:数据还原、纬度信息、起始版本、其它信息
4.报警层:环比、同比、邮件、IM、电话

单个Crash处理方案

1
2
3
1.根据堆栈及现场信息找答案
2.找共性:机型、OS、实验开关、资源包
3.线下复现、远程调试

Crash率治理方案

1
2
3
1.解决线上常规Crash
2.系统级Crash尝试Hook绕过
3.疑难Crash重点突破、更换方案

三、移动端业务高可用方案建设

业务高可用重要性

1
2
3
1.高可用:性能+业务
2.业务高可用侧重于用户功能完整可用
3.业务高可用真实的影响收入

业务高可用方案建设

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
数据采集
- 梳理项目主流程、核心路径、关键节点
- Aop自动采集、统一上报
报警策略
- 闽值报警
- 趋势报警
- 特定指标报警、直接上报
异常监控
- Catch代码块
- 异常逻辑
单点追查
- 需要针对性分析的特定问题
- 全量日志回捞,专项分析
兜底策略
- 配置中心,功能开关
- 跳转分发中心

四、移动端容灾方案

移动端容灾必要性

1
2
灾:性能、业务异常
传统流程:用户反馈、重新打包、渠道更新,不可接受

容灾方案建设

1
2
3
4
5
6
7
8
9
10
11
12
13
14
功能开关
- 配置中心,服务端下发配置控制
- 针对场景:功能新加或代码改动
统跳中心
- 界面切换通过路由,路由决定是否重定向
- eg:Native Bug不能热修则跳转到临时H5
动态化修复
- 热修复能力,可监控、灰度、回滚、清除
- 推拉结合、多场景调用保证到达率
- Weex、RN增量更新
安全模式
- 根据Crash信息自动恢复,多次启动失败重置App
- 严重Bug可阻塞性热修
- 异常熔断:多次请求失败则主动拒绝

容灾方案集合

1
功能开关->统跳中心->动态修复->安全模式

五、稳定性长效治理

全流程Crash长效治理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
开发阶段
- 统一编码规范、增强编码功底、技术评审、CodeReview机制
- 架构优化:能力收敛、统一容错
测试阶段
- 功能测试、自动化测试、 回归测试、覆盖安装
- 特殊场景、机型等边界测试
- 云测平台
合码阶段
- 编译检测、静态扫描
- 预编译流程、主流程自动回归
发布阶段
- 多轮灰度
- 分场景、纬度全面覆盖
运维阶段
- 灵敏监控
- 回滚、降级策略
- 热修、容灾方案

六、问题

你们做了哪些稳定性方面的优化

1
2
3
1.Crash专项优化
2.性能稳定性优化
3.业务稳定性优化

性能稳定性是怎么做的?

1
2
3
1.线下发现问题、优化为主
2.线上监控为主
3.Crash专项

业务稳定性如何保障 ?

1
2
1.数据采集+报警
2.异常监控 + 单点追查

如果发生了异常情况,怎么快速止损?

1
2
3
1.能力:功能开关、统跳中心
2.动态修复:热修、资源包更新
3.自主修复:安全模式
9.瘦身优化
1
2
3
4
5
6
7
8
//瘦身优化
1.代码混淆,统一三方库、删除无用代码
2.资源在线化
3.So:只保留Armeabi、或者只保留armeabi-v7a、arm64-v8a
4. 图片优化:
1.根据场景使用不同的文件,比如将png换成webp,像什么需要来回改变的简单的图可以使用svg替换,去除不需要的图片资源
2.图片压缩
5. 备用资源:默认情况下Android会有很多备用资源,比如string,包含了多国语言,我们可以指定需要的语言即可;

一、瘦身优化及Apk分析方案介绍

瘦身优势

1
2
3
1.最主要是转换率:下载转换率
2.头部App都有Lite版
3.渠道合作商要求

Apk组成

1
2
3
1.代码相关:classes.dex
2.资源相关:res、asserts、resources.arsc
3.So相关:lib

Apk分析

1
2
3
4
5
6
7
8
9
10
11
12
13
ApkTool,反编译工具
- 官网:https://ibotpeaches.github.io/Apktool/apktool d xx.apk
Analyze APK:Android Studio 2.2之后
- 查看Apk组成、大小、占比
- 插看Dex文件组成
- Apk对比
App性能分析 https://nimbledroid.com/
- 文件大小及排行
- Dex方法数、SDK方法数
- 启动时间、内存等
android-classyshark:二进制检查工具
- https://github.com/google/android-classyshark
- 支持多种格式:Apk、Jar、Class、So等

二、代码瘦身实战

代码混淆

1
2
3
4
5
6
7
8
9
10
花指令,功能等价但改变形式
- 代码中各个元素改写成无意义的名字
- 以更难理解的形式重写部分逻辑
- 打乱代码格式
Proguard:Java类文件处理工具,优化字节码
- 代码中元素名称改短,移除冗余代码
- 增加代码被反编译难度
- 使用:
- 配置minifyEnabled为true,debug下不要配置
- proguard-rules中配置相应规则

三方库处理

1
2
3
1.基础库统一
2.选择更小的库,Android Methods Count
3.仅引入所需的部分代码:Fresco的webp支持

移除无用代码

1
2
3
1.业务代码只加不减
2.代码太多不敢删除
3.AOP统计使用情况

三、资源瘦身实战

元余资源

1
studio中文件目录-右键-Refactor-Remove Unused Resource

图片压缩

1
2
3
1.快速发展期的App没有相关规范
2.https://tinypng.com/及TinyPngPlugin
3.图片格式选择

资源混淆

1
2
https://github.com/shwenzhang/AndResGuard
元长的资源路径变短

其它

1
2
1.图片只保留一份
2.资源在线化

四、so文件瘦身实战

So移除

1
2
3
4
1.So是Android上的动态链接库
2.七种不同类型的CPU架构
3.abiFilters:设置支持的So架构
4.一般选择armeabi(万金油可以支持其他架构,会损耗能效)

更优方案

1
2
1.完美支持所有类型设备代价太大
2.基础架构的都放在armeabi目录,根据CPU类型加载对应架构So(特定功能的so可以动态加载或放入其他架构包)

其它方案

1
2
1.So动态下载
2.插件化

五、问题

怎么降低Apk包大小

1
2
3
代码:Proguard、统一三方库、无用代码删除
资源:无用资源删除、混淆
So:只保留Armeabi、更优方案

Apk瘦身问题长效治理

1
2
发版之前与上个版本包体积对比,超过闯值则必须优化
推进插件化架构改造