16、Android 10 新特性:Soong 配置、产品配置变化、系统分区动态化
Android 10 这个版本,说实话,对构建系统来说是个分水岭。我当年从 Android 9 升级到 10 的时候,第一感觉就是「嗯,Makefile 那套东西真的要退休了」。Google 在 Android 7 引入了 Soong,但到了 10 才真正把 Soong 推到前台,让它成为构建系统的绝对主角。
今天咱们就聊聊三个核心变化:Soong 配置怎么玩、产品配置有哪些坑、以及那个听起来很唬人的「系统分区动态化」到底是个啥。
16.1 Soong 配置:从 Android.mk 到 Android.bp
如果你之前写过 Android.mk,那你应该知道那玩意儿有多啰嗦。LOCAL_ 开头的一大堆变量,稍不注意就拼错。Soong 的 Android.bp 文件,说白了就是用 JSON 风格的语法来定义模块。
举个例子,一个简单的 native 库,在 Android.mk 里是这样:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libhello
LOCAL_SRC_FILES := hello.cpp
LOCAL_SHARED_LIBRARIES := liblog
include $(BUILD_SHARED_LIBRARY)
换成 Android.bp 呢?简洁多了:
cc_library_shared {
name: "libhello",
srcs: ["hello.cpp"],
shared_libs: ["liblog"],
}
我个人习惯是,新项目一律用 .bp,老项目能迁移就迁移。为什么?因为 Soong 的依赖解析比 Make 快得多,而且错误提示更友好。我在项目中遇到过好几次,Android.mk 里漏了个依赖,编译半天才报错,换成 .bp 后,编译前就能检测出来。
16.2 产品配置变化:BoardConfig 和 ProductConfig 分家
Android 10 之前,产品配置都堆在 BoardConfig.mk 里。你想想看,一个文件里既要管硬件相关的配置(比如 kernel、分区大小),又要管产品相关的配置(比如预装应用、系统属性),多乱啊。
Android 10 把这个拆成了两块:
- BoardConfig.mk:只放硬件相关的东西。比如 TARGET_BOARD_PLATFORM、BOARD_SYSTEMIMAGE_PARTITION_SIZE 这些。
- ProductConfig.mk(或者 .bp):放产品相关的。比如 PRODUCT_PACKAGES、PRODUCT_PROPERTY_OVERRIDES。
为什么要这么分?说白了,就是为了让硬件平台和产品定制解耦。同一个硬件平台,可以出多个产品变体,不用重复写 BoardConfig。
举个例子,我做过一个项目,同一块高通芯片,要出国内版和海外版。以前我得复制整个 BoardConfig.mk,然后改几个变量。现在呢?BoardConfig 共享一份,ProductConfig 各写各的,清爽多了。
16.3 系统分区动态化:dynamic partitions
这个特性,嗯,我得说它改变了 Android 分区的玩法。以前系统分区是固定的,比如 system 分区 2GB,vendor 分区 1GB,product 分区 500MB。你想想看,如果 system 分区不够用了,vendor 那边还有空闲,但你就是用不了——因为分区大小是编译时定死的。
动态分区就是解决这个问题的。它把 system、vendor、product 这些分区合并成一个 super 分区。这个 super 分区有多大,由你定。里面的子分区可以动态调整大小。
我画个图帮你理解:
动态分区的好处很明显:
- 空间利用率高:哪个分区需要更多空间,就给哪个。不用再纠结「system 分区设多大合适」这种问题了。
- OTA 升级更安全:配合 A/B 分区,升级失败可以回滚。动态分区在 OTA 时能自动调整大小,不用重新烧录整个分区表。
- 产品定制更灵活:不同产品可以有不同的分区大小组合,不用改 BoardConfig。
BOARD_SUPER_PARTITION_SIZE := 4294967296 # 4GB
BOARD_SUPER_PARTITION_GROUPS := group1
BOARD_SUPER_PARTITION_GROUP_group1_SIZE := 4294967296
BOARD_SUPER_PARTITION_GROUP_group1_PARTITION_LIST := system vendor product
我曾经踩过一个坑:动态分区的大小必须和实际镜像大小匹配。有次我改了 system 分区内容,但忘了更新 BOARD_SUPER_PARTITION_SIZE,结果编译出来的 super 镜像烧不进去。嗯,从那以后我养成了习惯,每次改分区内容都检查一下这个值。
16.4 总结一下
Android 10 这三个变化,其实都指向同一个方向:让构建系统更灵活、更高效。Soong 配置让模块定义更简洁,产品配置分家让硬件和产品解耦,动态分区让存储空间利用更合理。
如果你还在用 Android 9 或更早的版本,我建议你尽快升级。虽然迁移过程有点痛苦,但长期来看,这些新特性真的能省不少事。
好了,这一章就聊到这儿。动态分区这块内容比较多,如果你在实际项目中遇到问题,欢迎交流。
公众号:蓝海资料掘金营,微信deep3321