2026/3/26 17:06:36
网站建设
项目流程
网站文站加入别人网站的链接是否对自己网站不好,网络管理app,wordpress 瀑布流布局,网站开发课程教学目标小白也能懂的Android 8.0开机启动脚本保姆级教程
你是不是也遇到过这样的问题#xff1a;想让自己的程序在Android设备一开机就自动运行#xff0c;比如自动开启某个服务、设置系统属性、或者执行一些初始化操作#xff1f;但一看到“init.rc”“SELinux”“te文件”这些词…小白也能懂的Android 8.0开机启动脚本保姆级教程你是不是也遇到过这样的问题想让自己的程序在Android设备一开机就自动运行比如自动开启某个服务、设置系统属性、或者执行一些初始化操作但一看到“init.rc”“SELinux”“te文件”这些词就头大别担心这篇教程就是为你准备的——不讲晦涩理论不堆专业术语只说你能听懂的话带你从零开始亲手完成一个真正能跑起来的开机启动脚本。本文基于真实工程实践整理所有步骤均在Android 8.0Oreo系统上实测通过适配主流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 found或permission 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; # 告诉inittest_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注意路径中的点.需要转义为\.这是正则表达式语法表示匹配字面量的点这行必须独占一行前后不能有空格即使你临时关闭了SELinuxsetenforce 0这行也必须加否则init无法识别该文件类型。4. 第三步把脚本“注册”进开机流程修改init.rcAndroid 8.0采用模块化init设计不再建议直接修改顶层init.rc。芯片厂商通常提供专门的扩展入口比如init.mtk.rc、init.qcom.rc或init.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_service6. 常见问题与避坑指南血泪总结实际操作中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 devsda31 ino123456 scontextu:r:init:s0 tcontextu:object_r:default_file:s0 tclassfile permissive0这说明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 50000005秒用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星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。