APM 模块开发基础 — module.prop、脚本、system 目录
模块的骨架
一个最小可用的 APM 模块需要两个东西:
module.prop— 模块元信息system/目录(或post-fs-data.sh脚本)— 具体做什么事
把它们打包成 zip 就行。
module.prop 格式
这是一个标准的 key=value 属性文件:
id=my-awesome-module
name=我的超棒模块
version=1.0
versionCode=1
author=你的名字
description=这个模块做了什么事,一两句话说清楚
字段说明:
| 字段 | 必填 | 说明 |
|---|---|---|
| id | ✅ | 模块唯一标识,只用字母数字和下划线,不能重名 |
| name | ✅ | 显示给用户看的名称 |
| version | ✅ | 人类可读的版本号 |
| versionCode | ✅ | 整数版本码,用于比较新旧 |
| author | ✅ | 作者名字 |
| description | ❌ | 模块描述 |
system/ 目录 — 叠加文件
最常用的模块类型就是往系统分区里叠加文件。举几个例子:
覆盖一个系统库:
module/
├── module.prop
└── system/
└── lib64/
└── libfoo.so # 叠加到 /system/lib64/libfoo.so
追加 build.prop 属性:
module/
├── module.prop
└── system.prop # 或 system/build.prop 追加
system.prop 里的写法:
ro.build.display.id=my_custom_build
persist.sys.safemode=1
覆盖字体:
module/
├── module.prop
└── system/
└── fonts/
├── Roboto-Regular.ttf
└── Roboto-Bold.ttf
脚本 — post-fs-data 和 service.d
如果文件叠加不够灵活,可以用脚本:
# post-fs-data.sh — 在 /data 分区挂载后、Zygote 启动前执行
#!/system/bin/sh
# 在日志里写一条
echo "模块已加载" > /data/local/tmp/my_module.log
# 修改某个文件权限
chmod 777 /data/local/tmp/some_file
# service.d/01-custom-service.sh — 在 boot_completed 之后执行,后台运行
#!/system/bin/sh
# 启动一个后台服务
while true; do
# 做一些定期任务
sleep 60
done
脚本文件要加上可执行权限。
sepolicy.rule
需要修改 SELinux 策略时:
# 允许某个域访问某个文件类型
domain:file rw_file_perms
APatch 直接引用了 Magisk 的 magiskpolicy 来处理 SELinux,所以规则格式和 Magisk 完全一致。
打包成 zip
用任意压缩工具把 module 目录打包。APatch 管理器和 fastboot 都能识别 zip 格式。
和 Magisk 模块开发的区别
几乎没有——最大的区别是脚本路径和 SELinux 处理。APatch 的 APM 代码来自 KernelSU,而 KernelSU 的模块实现就是从 Magisk 抄的。Magisk 模块开发者的经验可以无缝迁移过来。
更多细节可以看 APatch 官方文档里的 APM 开发指南。