news 2026/4/15 18:16:42

小白也能懂的Android 8.0开机启动脚本保姆级教程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
小白也能懂的Android 8.0开机启动脚本保姆级教程

小白也能懂的Android 8.0开机启动脚本保姆级教程

你是不是也遇到过这样的问题:想让自己的程序在Android设备一开机就自动运行,比如自动开启某个服务、设置系统属性、或者执行一些初始化操作?但一看到“init.rc”“SELinux”“te文件”这些词就头大?别担心,这篇教程就是为你准备的——不讲晦涩理论,不堆专业术语,只说你能听懂的话,带你从零开始,亲手完成一个真正能跑起来的开机启动脚本。

本文基于真实工程实践整理,所有步骤均在Android 8.0(Oreo)系统上实测通过,适配主流MTK平台,也适用于高通、展锐等常见方案。哪怕你没编译过Android源码、没碰过SELinux,只要会用adb、能看懂shell命令,就能跟着一步步做完。我们不追求一步到位的“完美方案”,而是先让你的脚本稳稳跑起来,再逐步优化。

1. 先搞清楚:开机启动到底要动哪几块地方?

很多新手卡住,不是因为技术难,而是不知道整个流程分几步、每步干什么。其实Android 8.0的开机脚本启动,就四个核心环节,像搭积木一样,缺一不可:

  • 写一个能干活的shell脚本:这是你的“任务清单”,告诉系统开机后具体做什么
  • 告诉系统“这个脚本是可信的”:也就是SELinux权限配置,Android 8.0默认强制启用,跳不过
  • 告诉系统“开机时记得叫它”:通过init.rc或其子文件注册为一个service
  • 确保它真能被系统找到并执行:路径、权限、解释器都得对,一个都不能错

这四步环环相扣。很多人试了十次都不成功,往往是因为只改了其中一两处,比如写了脚本却忘了加SELinux规则,或者加了规则但init.rc里路径写错了。所以咱们不着急写代码,先理清逻辑。

2. 第一步:写一个最简单的开机脚本(5分钟搞定)

别一上来就想做复杂功能。我们先写一个“打个招呼”的脚本,目标只有一个:开机后设置一个系统属性,然后我们用adb命令立刻验证它是否生效。这是最轻量、最可控的测试方式。

2.1 创建脚本文件

新建一个纯文本文件,命名为init.test.sh(注意名字必须以init.开头,这是Android init机制的约定),内容如下:

#!/system/bin/sh # 这是Android专用的shell解释器路径,千万别写成 /bin/sh 或 /usr/bin/sh # 如果你不确定,可以先用 adb shell ls /system/bin/sh 确认一下 # 设置一个测试属性,值为 "booted" setprop test.boot_status "booted" # 可选:写一行日志,方便后续调试(需要logcat权限) # log -t INIT_TEST "Script executed successfully"

关键提醒:

  • 第一行#!/system/bin/sh必须严格写对。Android和Linux的shell路径不同,写错直接静默失败;
  • 不要用Windows编辑器保存(避免换行符问题),推荐用VS Code、Sublime Text或Linux/macOS自带编辑器;
  • 文件编码必须是UTF-8无BOM。

2.2 手动测试:确认脚本能独立运行

这一步极其重要!很多问题其实出在脚本本身。先别急着放进系统,我们把它临时推到手机上手动执行一次:

# 将脚本推送到手机的/system/bin目录(需要root权限) 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.boot_status

如果最后输出booted,恭喜!你的脚本语法正确、路径可用、解释器匹配。如果报错,比如not foundpermission denied,请回头检查上面的提醒点。

3. 第二步:让系统“信任”这个脚本(SELinux配置)

Android 8.0起,SELinux处于enforcing模式,任何进程访问资源(包括执行脚本)都必须有明确授权。你的脚本再完美,没有SELinux许可,init进程根本不会让它启动。

别被“te文件”“file_contexts”吓到,它们本质就是两张“通行证”:

  • te文件:定义“谁(test_service)能对什么(test_service_exec)做什么(execute)”;
  • file_contexts:定义“哪个文件(/system/bin/init.test.sh)属于哪个类型(test_service_exec)”。

我们按顺序来,全部用最简配置。

3.1 创建SELinux类型定义文件(test_service.te)

新建一个文件test_service.te,内容如下:

# 定义一个新的域(domain),叫 test_service type test_service, domain; # 定义一个新的文件类型,叫 test_service_exec type test_service_exec, exec_type, file_type; # 告诉init:test_service 是一个守护进程域 init_daemon_domain(test_service); # 允许 test_service 域执行 test_service_exec 类型的文件 allow test_service test_service_exec:file { execute read open getattr };

说明:

  • 这比参考博文里的内容更清晰、更安全。我们没用permissive(宽容模式),而是精准放行execute权限;
  • init_daemon_domain是关键宏,它自动赋予test_service域访问init所需的基础权限(如读取property_service);
  • 这个文件通常放在device/your_company/sepolicy/vendor/non_plat/目录下(不同厂商路径略有差异,MTK多在basic/non_plat)。

3.2 关联脚本文件与SELinux类型(file_contexts)

device/your_company/sepolicy/vendor/non_plat/file_contexts文件末尾,添加一行:

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

注意:

  • 路径中的点.需要转义为\.,这是正则表达式语法,表示匹配字面量的点;
  • 这行必须独占一行,前后不能有空格;
  • 即使你临时关闭了SELinux(setenforce 0),这行也必须加,否则init无法识别该文件类型。

4. 第三步:把脚本“注册”进开机流程(修改init.rc)

Android 8.0采用模块化init设计,不再建议直接修改顶层init.rc。芯片厂商通常提供专门的扩展入口,比如init.mtk.rcinit.qcom.rcinit.vendor.rc。我们要把服务加到对应的位置。

4.1 找到正确的init.rc扩展文件

进入你的Android源码目录,执行:

find device/ -name "init.*.rc" | grep -E "(mtk|qcom|vendor)"

假设你用的是MTK平台,大概率会找到device/mediatek/sepolicy/basic/init.mtk.rc或类似路径。打开它,在合适位置(比如末尾)添加:

# 定义一个名为 test_service 的服务 service test_service /system/bin/init.test.sh class main user root group root oneshot seclabel u:object_r:test_service_exec:s0

字段解释:

  • service test_service ...:服务名,任意取,但需唯一;
  • /system/bin/init.test.sh:脚本绝对路径,必须和你push的路径一致;
  • class main:表示它属于main类,会在init启动main类服务时被拉起;
  • user/group root:以root身份运行,确保有足够权限;
  • oneshot:执行完即退出,适合一次性初始化任务(如设属性);
  • seclabel:关联前面定义的SELinux类型,必须完全一致。

4.2 验证init.rc语法(可选但强烈推荐)

Android提供工具检查rc文件语法:

# 在源码根目录执行 m -j32 checkinit # 或单独检查 ./system/core/init/checkinit init.mtk.rc

如果报错,根据提示修正路径或格式即可。

5. 第四步:编译、烧录与最终验证

前三步都是“纸上谈兵”,现在到了见证奇迹的时刻。

5.1 编译并打包system镜像

# 清理旧产物(可选) m clean # 编译sepolicy和init.rc相关模块 m sepolicy_policy.conf init.mtk.rc # 编译整个system.img(或使用增量编译) m systemimage

编译完成后,生成的out/target/product/xxx/system.img就是你要烧录的镜像。

5.2 烧录并重启

用fastboot将新system.img烧录到设备:

fastboot flash system out/target/product/xxx/system.img fastboot reboot

等待设备完全启动(约1-2分钟)。

5.3 终极验证:开机后立刻检查

设备启动完毕后,立即执行:

adb shell getprop test.boot_status

如果返回booted,说明你的开机脚本已100%成功运行!
你还可以用以下命令查看服务是否被init拉起过:

adb shell dmesg | grep -i "test_service" # 或查看init日志 adb shell logcat -b events | grep -i "test_service"

6. 常见问题与避坑指南(血泪总结)

实际操作中,90%的问题都集中在以下几个点。如果你失败了,请优先对照这里排查:

6.1 脚本根本没执行?先看这三点

  • 路径写错:init.rc里写的路径,必须和你实际存放脚本的路径完全一致(包括大小写、.sh后缀);
  • 权限不足/system/bin/init.test.sh必须是755权限,且属主为root:root
  • 解释器失效:确认/system/bin/sh存在且可执行(adb shell ls -l /system/bin/sh)。

6.2 SELinux报错?看log最准

如果开机后getprop查不到值,立即执行:

adb shell dmesg | grep avc

你会看到类似这样的拒绝日志:

avc: denied { execute } for path="/system/bin/init.test.sh" dev="sda31" ino=123456 scontext=u:r:init:s0 tcontext=u:object_r:default_file:s0 tclass=file permissive=0

这说明:

  • tcontext(目标上下文)是default_file,但我们需要的是test_service_exec
  • 解决方案:回去检查file_contexts文件,确认路径正则是否匹配、是否漏掉转义、是否多空格。

6.3 修改后不生效?记住两个“必须”

  • 必须重新编译system.img:只改te或rc文件,不重新编译,改动不会进镜像;
  • 必须完整烧录system分区:用fastboot flash system,不要用adb remount && adb push替代,后者无法更新SELinux策略。

6.4 进阶建议:让脚本更健壮

当你跑通第一个脚本后,可以逐步升级:

  • 加日志:在脚本里用log -t YOUR_TAG "message"记录关键步骤;
  • 加判断:用if [ -f "/data/local/tmp/done" ]; then exit 0; fi避免重复执行;
  • 加延时:某些服务依赖网络或GPU,可在脚本开头加usleep 5000000(5秒);
  • 用vendor分区:把脚本放到/vendor/bin/,对应修改file_contexts为/vendor/bin/init\.test\.sh,更符合Android Treble规范。

7. 总结:你已经掌握了Android开机启动的核心能力

回顾一下,我们完成了什么:

  • 写了一个功能明确、可独立验证的shell脚本;
  • 配置了最小集的SELinux策略,理解了te和file_contexts的作用;
  • 将服务注册进init流程,知道如何选择正确的rc文件;
  • 经历了从编译、烧录到验证的完整闭环;
  • 掌握了dmesg和getprop这两个最实用的调试武器。

这不再是“照着抄就能跑”的教程,而是你亲手搭建的一条可靠路径。以后无论是启动一个守护进程、预置配置文件,还是集成第三方SDK的初始化逻辑,你都有了可复用的方法论。

下一步,你可以尝试把一个真实的业务脚本(比如自动挂载U盘、初始化传感器校准参数)套用这个流程。记住:先让最简版本跑通,再叠加功能;先验证单点,再串联流程。这才是工程落地的正确姿势。


获取更多AI镜像

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

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

木马病毒:数字时代的“特洛伊刺客”与全面防御指南

在数字时代,木马病毒已成为网络安全的首要威胁之一。这种以古希腊“特洛伊木马”故事命名的恶意软件,正像古代的刺客一样,悄无声息地潜入我们的计算机系统,造成巨大破坏。本文将全面解析木马病毒的演变历程、技术架构、危害方式以…

作者头像 李华
网站建设 2026/4/9 19:45:27

3步提升游戏体验:智能辅助工具让你秒变电竞高手

3步提升游戏体验:智能辅助工具让你秒变电竞高手 【免费下载链接】champ-r 🐶 Yet another League of Legends helper 项目地址: https://gitcode.com/gh_mirrors/ch/champ-r 你是否也曾在《英雄联盟》中遭遇这样的困境:版本更新后面对…

作者头像 李华
网站建设 2026/4/11 9:23:04

解锁跨平台音乐自由:GoMusic无缝同步歌单全指南

解锁跨平台音乐自由:GoMusic无缝同步歌单全指南 【免费下载链接】GoMusic 迁移网易云/QQ音乐歌单至 Apple/Youtube/Spotify Music 项目地址: https://gitcode.com/gh_mirrors/go/GoMusic 在数字音乐时代,我们的歌单常常被困在单一平台的"围墙…

作者头像 李华
网站建设 2026/4/13 10:19:26

解锁微信数据:3个鲜为人知的备份技巧

解锁微信数据:3个鲜为人知的备份技巧 【免费下载链接】PyWxDump 获取微信账号信息(昵称/账号/手机/邮箱/数据库密钥/wxid);PC微信数据库读取、解密脚本;聊天记录查看工具;聊天记录导出为html(包含语音图片)。支持多账户信息获取&a…

作者头像 李华
网站建设 2026/4/7 11:54:16

开源日志聚合系统API设计与实战:从基础到进阶

开源日志聚合系统API设计与实战:从基础到进阶 【免费下载链接】loki Loki是一个开源、高扩展性和多租户的日志聚合系统,由Grafana Labs开发。它主要用于收集、存储和查询大量日志数据,并通过标签索引提供高效检索能力。Loki特别适用于监控场景…

作者头像 李华
网站建设 2026/4/15 14:41:50

机器人车轮设计在仓储物流中的实际应用

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 为仓储物流机器人设计车轮结构,要求能够承载50kg重量,在光滑地面和轻微不平地面上都能稳定运行。考虑轮子材质、直径、宽度和胎纹设计,生成具体…

作者头像 李华