在Android 8.1系统开发过程中,我们发现一个有趣的现象:相同1.5GB分区大小的system.img,Rockchip(RK)平台编译生成的镜像比MediaTek(MTK)平台多占用约350MB存储空间。这个差异在存储资源紧张的嵌入式设备上尤为关键,直接影响OTA更新包大小和系统运行效率。
具体数据对比:
注意:这个差异是在相同Android版本(8.1)、相同分区大小配置下出现的,说明问题根源在于平台特定的编译策略和文件组织方式。
在Ubuntu环境下(推荐18.04 LTS及以上版本),需要安装以下工具:
bash复制sudo apt update
sudo apt install -y simg2img e2fsprogs tree ncdu
simg2img用于处理Android的sparse image格式转换,e2fsprogs提供ext4文件系统支持,tree和ncdu则是分析目录结构的利器。
Android系统镜像通常以sparse格式分发,需要转换为raw镜像才能挂载:
bash复制# 转换RK平台镜像
simg2img rk_system.img rk_system_raw.img
# 转换MTK平台镜像
simg2img mtk_system.img mtk_system_raw.img
创建挂载点并挂载镜像(需要root权限):
bash复制# 创建挂载目录
mkdir -p /mnt/{rk_system,mtk_system}
# 挂载RK镜像
mount -o loop,rw rk_system_raw.img /mnt/rk_system
# 挂载MTK镜像
mount -o loop,rw mtk_system_raw.img /mnt/mtk_system
避坑指南:如果在macOS环境下操作会遇到ext4支持问题。建议使用Docker创建Ubuntu容器:
bash复制docker run -it --privileged -v $(pwd):/data ubuntu:18.04
使用du命令进行目录大小统计:
bash复制# RK平台分析
du -h --max-depth=1 /mnt/rk_system | sort -hr > rk_size.txt
# MTK平台分析
du -h --max-depth=1 /mnt/mtk_system | sort -hr > mtk_size.txt
关键差异点统计表:
| 目录 | RK大小 | MTK大小 | 差异 |
|---|---|---|---|
| priv-app | 615MB | 497MB | +118MB |
| framework | 243MB | 176MB | +67MB |
| lib64 | 166MB | 0MB | +166MB |
| 总计 | 1024MB | 673MB | +351MB |
priv-app存放系统核心应用,使用以下命令深入分析:
bash复制# 生成详细文件列表
find /mnt/rk_system/priv-app -type f -exec du -h {} + | sort -hr > rk_priv_app_detail.txt
发现RK平台多包含以下应用:
这些是RK定制化的系统应用,虽然可以裁剪但会影响平台特定功能。
framework目录包含系统框架jar文件,差异主要来自:
bash复制du -h /mnt/rk_system/framework/* | sort -hr
关键发现:
RK平台独有的lib64目录包含:
Android支持三种ABI(应用二进制接口):
RK平台默认同时包含32位和64位支持,而MTK选择仅保留32位。这种策略差异体现在:
库文件冗余:
ART优化文件重复:
Framework双备份:
通过分析build/core/main.mk,发现关键差异点:
makefile复制# RK的TARGET_PREFER_32BIT配置
PRODUCT_PROPERTY_OVERRIDES += ro.zygote=zygote64_32
TARGET_SUPPORTS_64_BIT_APPS := true
# MTK的配置
TARGET_PREFER_32BIT := true
TARGET_SUPPORTS_64_BIT_APPS := false
修改device/rockchip/common/BoardConfig.mk:
makefile复制# 强制32位模式
TARGET_PREFER_32BIT := true
TARGET_SUPPORTS_64_BIT_APPS := false
# 禁用64位 zygote
PRODUCT_PROPERTY_OVERRIDES += ro.zygote=zygote32
预期效果:
在device/rockchip/common/device.mk中移除非必要应用:
makefile复制# 移除预装应用
PRODUCT_PACKAGES := \
$(filter-out RkVideoPlayer RkGallery, \
$(PRODUCT_PACKAGES))
预期效果:
bash复制make clean
source build/envsetup.sh
lunch rk3328-eng
make -j8
bash复制# 检查lib64是否存在
ls out/target/product/rk3328/system/lib64
# 检查zygote模式
adb shell getprop ro.zygote
优化前后数据对比表:
| 指标 | 优化前 | 优化后 | 变化 |
|---|---|---|---|
| system.img大小 | 1.4GB | 1.1GB | -300MB |
| 启动时间 | 12.3s | 11.8s | -0.5s |
| 内存占用 | 1.2GB | 1.0GB | -200MB |
应用兼容性测试:
bash复制adb install --abi armeabi-v7a test.apk
性能基准测试:
bash复制adb shell am start -n com.futuremark.dmandroid/.activity.DMAndroidActivity
稳定性测试:
bash复制adb shell monkey -p your.package -v 10000
通过与MTK工程师交流,了解到他们的策略基于:
虽然本文建议移除64位支持来节省空间,但需要注意:
因此,对于新项目建议:
TARGET_PREFER_32BIT但保留64位能力