news 2026/3/9 13:30:07

用测试开机脚本实现属性设置,开机自动触发任务

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用测试开机脚本实现属性设置,开机自动触发任务

用测试开机脚本实现属性设置,开机自动触发任务

在嵌入式Android系统开发中,经常需要在设备启动完成的第一时间执行一些初始化操作——比如设置特定系统属性、启动后台服务、挂载调试工具或触发自定义逻辑。这类需求看似简单,但实际落地时容易踩坑:脚本不执行、权限被拦截、SELinux拒绝访问、执行时机错乱……尤其在Android 8.0及以后版本,init进程重构、SELinux策略收紧、vendor分区隔离等机制让传统做法频频失效。

本文聚焦一个轻量、稳定、可验证的实践方案:通过一个精简的开机启动shell脚本,安全地设置系统属性,并确保其在系统就绪后可靠触发。不依赖复杂服务框架,不修改核心init.rc主文件,不绕过SELinux,所有步骤均基于标准Android构建流程,已在主流MTK平台实测通过。你将看到:如何写一个真正能跑起来的脚本、为什么te文件和file_contexts缺一不可、怎样避免“写了却没执行”的隐形失败,以及最关键的——如何用setprop这一最基础的能力,撬动后续自动化任务链。

全文无抽象理论,只有可粘贴、可调试、可复现的操作路径。即使你刚接触Android底层,也能照着一步步完成验证。

1. 核心目标与适用场景

1.1 这篇文章能帮你解决什么问题

  • 设备每次开机后自动设置一个系统属性(如test.prop=111),供其他模块读取判断
  • 脚本在class main阶段启动,确保zygote已就绪、property service可用
  • 避免因SELinux拒绝导致脚本静默失败(常见于关闭adb但未关SELinux的调试机)
  • 不修改/system/etc/init/hw/init.rc等主配置,降低升级冲突风险
  • 提供快速验证方法:push后手动执行 → 检查属性 → 确认开机生效

1.2 它不是什么

  • ❌ 不是通用服务管理方案(如需长期守护进程,请用service+restart
  • ❌ 不涉及App层自动启动(如BroadcastReceiver监听BOOT_COMPLETED)
  • ❌ 不提供跨Android大版本的兼容性封装(本文验证环境为Android 8.0,适配思路可迁移)
  • ❌ 不绕过SELinux或降级安全策略(所有权限声明清晰、最小化)

1.3 为什么选择setprop作为首个任务

setprop是Android中最轻量、最底层的系统交互方式之一:

  • 执行快(毫秒级)、无依赖(仅需property_service运行)
  • 效果可验证(getprop test.prop立即返回)
  • 是后续任务的“开关”:其他模块可通过轮询或watch该属性,决定是否启动自身逻辑
  • 失败反馈明确:setprop返回非零码即失败,便于日志定位

因此,它是最理想的“开机第一跳”验证点。

2. 脚本编写与本地验证

2.1 编写可执行的init脚本

新建文件init.test.sh,内容如下:

#!/system/bin/sh # 设置一个测试属性,值为字符串"111" setprop test.prop 111 # 可选:写入log便于调试(需确保logd已启动) log -t "INIT_TEST" "setprop test.prop=111 executed"

关键细节说明

  • 第一行#!/system/bin/sh必须严格匹配Android系统实际shell路径。MTK平台通常为/system/bin/sh,高通平台可能为/system/bin/sh/system/xbin/sh切勿写成/bin/sh,否则init会因找不到解释器而静默跳过。
  • setprop命令在Android 8.0+中默认可用,无需额外链接。
  • 避免在此处创建文件、修改权限、挂载目录等高风险操作。初期验证务必保持脚本极简,排除干扰项。

2.2 手动推送与执行验证

在设备已启用adb调试的前提下,执行以下命令:

# 将脚本推送到/system/bin/(需remount) adb root adb remount adb push init.test.sh /system/bin/ # 赋予可执行权限 adb shell chmod 755 /system/bin/init.test.sh # 手动执行一次 adb shell /system/bin/init.test.sh # 检查属性是否设置成功 adb shell getprop test.prop # 预期输出:111 # 查看log确认执行 adb logcat -t "INIT_TEST" -b events

getprop返回111且logcat可见日志,则脚本本身功能正常。这是后续所有步骤的前提。

❌ 若失败,请检查:

  • adb remount是否成功(adb shell mount | grep system确认/system为read-write)
  • chmod权限是否正确(adb shell ls -l /system/bin/init.test.sh应显示-rwxr-xr-x
  • setprop是否被SELinux拦截(adb shell dmesg | grep avc查看拒绝日志)

3. SELinux策略配置(关键!不可跳过)

Android 8.0起,init启动的每个服务都受SELinux域约束。即使setprop本身允许,脚本文件的类型、执行域、访问权限也必须显式声明,否则init会直接拒绝启动。

3.1 定义服务类型与执行文件类型

device/mediatek/sepolicy/basic/non_plat/目录下(MTK平台路径,其他厂商请对应调整)新建test_service.te文件:

# 定义服务域类型 type test_service, coredomain; # 定义脚本文件类型 type test_service_exec, exec_type, vendor_file_type, file_type; # 允许init_daemon_domain(即init)以test_service域运行该服务 init_daemon_domain(test_service); # 允许test_service域读取、执行该脚本文件 allow test_service test_service_exec:file { read open getattr execute };

说明

  • coredomain表示该域属于核心服务范畴,可继承init的基本能力。
  • exec_typevendor_file_type确保该类型能被正确识别为可执行文件。
  • init_daemon_domain()是必需宏,建立init与新服务域的信任关系。
  • 最后一行allow规则明确授予执行权限,不可省略

3.2 关联脚本文件到SELinux类型

在同一目录下的file_contexts文件末尾添加一行:

/system/bin/init\.test\.sh u:object_r:test_service_exec:s0

注意正则转义.sh中的点号需用\.转义,否则匹配失败。

此行作用是告诉SELinux:当系统看到路径为/system/bin/init.test.sh的文件时,将其安全上下文标记为u:object_r:test_service_exec:s0,从而与test_service_exec类型关联。

3.3 构建并验证SELinux策略

执行完整编译(或仅编译sepolicy):

m sepolicy

烧录镜像后,检查策略是否生效:

# 查看脚本文件的安全上下文 adb shell ls -Z /system/bin/init.test.sh # 预期输出中应包含:u:object_r:test_service_exec:s0 # 检查test_service域是否存在 adb shell sesearch -s test_service -t test_service_exec -c file -p execute # 应返回允许规则

上述两项均通过,表明SELinux策略已正确加载。

4. 在init中注册服务

4.1 创建独立的init配置片段

强烈建议不要直接修改/system/etc/init/hw/init.rc。芯片厂商通常提供专用扩展点,例如MTK平台的init.mtk.rcinit.vendor.rc。在device/mediatek/sepolicy/basic/non_plat/同级目录(如device/mediatek/common/rootdir/etc/)中,新建init.test.rc

# 测试开机脚本服务 service test_service /system/bin/init.test.sh class main user root group root oneshot seclabel u:object_r:test_service_exec:s0

参数解析

  • class main:确保在main类服务组中启动,此时property_service、logd等基础服务均已就绪。
  • user root&group root:以root权限运行,满足setprop要求。
  • oneshot:执行完即退出,符合一次性设置属性的语义。
  • seclabel:显式指定SELinux标签,与file_contexts中定义的类型一致。

4.2 引入配置片段

在主init配置(如init.mtk.rc)中添加导入语句:

import /system/etc/init/init.test.rc

或在BoardConfig.mk中确保该文件被包含进最终init.rc

4.3 验证init配置加载

烧录后检查:

# 查看init是否识别到该服务 adb shell getprop | grep init.svc.test_service # 开机后应短暂出现:init.svc.test_service=running,随后变为=stopped # 查看init日志(需串口或开启init log) adb shell dmesg | grep -i "test_service"

5. 开机全流程验证与排错指南

5.1 标准验证流程

  1. 烧录含上述修改的完整镜像
  2. 冷启动设备(非reboot,确保完整init流程)
  3. 等待30秒后执行
    adb shell getprop test.prop # 成功:返回 111 # ❌ 失败:返回空或报错

5.2 常见失败现象与精准定位

现象可能原因快速定位命令
getprop test.prop无输出脚本根本未执行`adb shell dmesg
dmesg显示avc: deniedSELinux权限缺失`adb shell dmesg
getprop返回旧值或错误值脚本执行但setprop失败adb shell logcat -b events -t "INIT_TEST"查脚本内log;adb shell setprop test.prop 222 && adb shell getprop test.prop手动测试setprop是否可用
init.svc.test_service状态为stopping脚本执行异常退出adb shell cat /proc/$(pidof init)/fd/2(需root)或检查logcat -b events中init的错误输出

5.3 进阶:从属性触发后续任务

test.prop设为开关后,其他模块可主动响应:

  • Native进程:用property_get("test.prop", buf, "")轮询或监听
  • Java层SystemProperties.get("test.prop")(需android.permission.READ_FRAME_BUFFER,仅系统App)
  • Shell脚本:在其他init服务中加入while [ "$(getprop test.prop)" != "111" ]; do sleep 1; done等待

这实现了“开机设置→条件触发”的解耦设计,比硬编码启动更灵活。

6. 总结:一个可靠开机任务的最小可行实践

本文带你走通了一条经过实测的Android开机脚本落地路径。它没有炫技,只做三件事:写对脚本、配对SELinux、注册对init。每一步都直指实际开发中最易卡壳的环节。

回顾关键要点:

  • 脚本必须用/system/bin/sh解释器,且仅做setprop等确定性操作,规避权限与路径陷阱;
  • SELinux不是可选项te文件定义域、file_contexts绑定类型、init.rcseclabel三者缺一不可;
  • class main是黄金时机:它平衡了“足够早”(系统服务就绪)与“足够稳”(无竞态);
  • 验证必须分层:先手动执行 → 再检查SELinux → 最后看开机效果,层层递进,拒绝黑盒。

当你下次需要在开机瞬间点亮一个标志、启动一个探测、或打开一个开关时,这套方法就是你的起点。它足够小,小到可以今天就集成;也足够坚实,坚实到能支撑起更复杂的自动化链条。

获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/8 1:35:33

零基础掌握开源字体:设计师必备的多语言排版解决方案

零基础掌握开源字体:设计师必备的多语言排版解决方案 【免费下载链接】source-han-sans-ttf A (hinted!) version of Source Han Sans 项目地址: https://gitcode.com/gh_mirrors/so/source-han-sans-ttf 在全球化设计项目中,选择一款既能完美支持…

作者头像 李华
网站建设 2026/3/4 12:35:33

保姆级教程:ollama部署Qwen2.5-VL-7B视觉代理AI

保姆级教程:ollama部署Qwen2.5-VL-7B视觉代理AI 你是否试过把一张商品截图扔给AI,让它直接告诉你“这是什么品牌、多少钱、有没有促销信息”,甚至还能帮你比价?或者上传一段手机录屏,让AI自动总结操作步骤、指出卡点问…

作者头像 李华
网站建设 2026/3/4 8:14:38

Java技术八股学习Day27

Linux基础知识 初探 Linux (1)核心定义与本质 Linux 是自由开源的类 Unix 操作系统,核心是 Linux 内核(由 Linus Torvalds 发起开源项目),单独内核无法构成完整系统,需搭配软件、文档及管理工…

作者头像 李华
网站建设 2026/3/8 16:45:43

零基础也能行!用YOLOv9官方镜像快速实现工业质检实战

零基础也能行!用YOLOv9官方镜像快速实现工业质检实战 在汽车零部件产线发现微米级划痕、在电路板检测中识别0.5mm焊点虚焊、在食品包装流水线上实时拦截破损包装——这些曾需资深工程师盯屏数小时的工业质检任务,如今正被AI悄然接管。但摆在很多制造企业…

作者头像 李华
网站建设 2026/3/4 10:50:08

ReTerraForged地形生成革新:Minecraft世界构建完全指南

ReTerraForged地形生成革新:Minecraft世界构建完全指南 【免费下载链接】ReTerraForged a 1.19 port of https://github.com/TerraForged/TerraForged 项目地址: https://gitcode.com/gh_mirrors/re/ReTerraForged 你是否曾厌倦了Minecraft中千篇一律的地形生…

作者头像 李华
网站建设 2026/3/8 8:42:39

AMD Ryzen处理器性能优化指南:用SMUDebugTool解决三大核心问题

AMD Ryzen处理器性能优化指南:用SMUDebugTool解决三大核心问题 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址: ht…

作者头像 李华