网站网络推广优化哪家好汕尾网站seo
2026/5/24 2:12:39 网站建设 项目流程
网站网络推广优化哪家好,汕尾网站seo,医药包装设计公司,seo平台怎么样手把手教你写Android开机启动shell脚本#xff08;附测试#xff09; 1. 前言#xff1a;为什么需要开机启动脚本#xff1f; 在做Android系统级开发或定制时#xff0c;经常会遇到这样一个需求#xff1a;设备一开机#xff0c;就自动执行某个任务。比如#xff1a;…手把手教你写Android开机启动shell脚本附测试1. 前言为什么需要开机启动脚本在做Android系统级开发或定制时经常会遇到这样一个需求设备一开机就自动执行某个任务。比如自动开启某个后台服务设置系统属性用于后续流程判断挂载特殊分区或初始化硬件清理缓存、备份日志等维护操作这些任务如果靠应用层去监听BOOT_COMPLETED广播来做不仅延迟高还可能因权限问题失败。而通过init 进程启动的 shell 脚本可以在系统早期阶段运行权限更高、时机更早。本文将带你从零开始完整实现一个 Android 开机启动 shell 脚本并提供实际测试方法。内容基于 Android 8.0 环境验证通过适用于大多数 AOSP 或 MTK/高通平台的定制系统开发。你不需要是 SELinux 专家也不用对 init.rc 了如指掌——只要跟着步骤走就能成功跑通。2. 实现原理简述Android 的启动流程中init进程是第一个用户空间进程PID1它会解析/init.rc及其包含的.rc文件根据配置启动各种服务和执行命令。我们可以通过以下方式让一个 shell 脚本在开机时自动运行编写一个可执行的 shell 脚本将脚本放入系统镜像的指定路径如/system/bin/在.rc文件中定义一个service来调用该脚本配置 SELinux 策略允许该服务运行编译刷机后验证效果整个过程看似简单但最容易卡住的地方就是SELinux 权限问题。别担心我们会一步步解决。3. 第一步编写你的开机启动脚本3.1 创建脚本文件新建一个名为init.test.sh的文件内容如下#!/system/bin/sh # 设置一个系统属性用于验证脚本是否执行 setprop sys.boot.test 1 # 输出日志到 dmesg方便调试 log -t InitTest -p i 开机启动脚本已执行 # 可选创建一个标记文件需注意目录权限 # touch /data/local/tmp/boot_script_ran3.2 注意事项解释器路径必须正确Android 系统通常使用/system/bin/sh不是 Linux 常见的/bin/sh不要写错 shebang 行#!/system/bin/sh前不能有空格或 BOM避免操作敏感目录测试阶段建议只设置属性或打日志避免因文件权限导致失败脚本要可执行确保编译进系统时权限为755你可以先手动 push 到手机试试看能否运行adb push init.test.sh /data/local/tmp/ adb shell chmod 755 /data/local/tmp/init.test.sh adb shell /data/local/tmp/init.test.sh adb shell getprop sys.boot.test # 应该输出 1如果这步都跑不通说明脚本本身有问题请先修复。4. 第二步为脚本添加 SELinux 策略这是很多人踩坑最多的地方。即使关闭了 SELinuxenforcing0Android 仍然会检查类型标签file_contexts是否匹配否则init不会启动服务。4.1 新建 TE 策略文件在你的设备目录下创建 SELinux 策略文件例如 MTK 平台常见路径device/mediatek/sepolicy/basic/non_plat/test_service.te内容如下# 定义服务类型 type test_service, coredomain; # 定义可执行文件类型 type test_service_exec, exec_type, file_type, vendor_file_type; # 允许 init 启动这个域的服务 init_daemon_domain(test_service) # 如果你想调试可以临时设为宽容模式不推荐长期使用 # permissive test_service;4.2 添加 file_contexts 映射编辑或创建device/mediatek/sepolicy/basic/non_plat/file_contexts添加一行告诉系统这个脚本文件应该属于什么安全上下文/(system\/vendor|vendor)/bin/init\.test\.sh u:object_r:test_service_exec:s0注意这里路径是/system/bin/或/vendor/bin/取决于你把脚本放哪。正则表达式要用转义点号。如果你把脚本放在/system/bin/init.test.sh那最终打包时必须确保它在这个位置并且上下文正确。5. 第三步在 .rc 文件中注册服务不要直接修改/init.rc而是找厂商提供的扩展.rc文件比如init.mtk.rcinit.vendor.rc或者你自己加一个init.custom.rc推荐做法是在init.${project}.rc中添加服务定义。5.1 添加 service 定义在合适的.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 class 启动user/group root以 root 身份运行谨慎使用oneshot只运行一次适合脚本任务如果不加会不断重启seclabel必须与 file_contexts 中定义的类型一致5.2 替代方案直接执行 command如果你想更轻量也可以不用 service直接在.rc中写on property:sys.boot_completed1 exec u:object_r:test_service_exec:s0 root root -- /system/bin/init.test.sh这种方式更适合一次性命令且能控制触发时机比如等 boot_completed 再执行。6. 第四步编译并刷入系统6.1 放置脚本到源码目录将init.test.sh放入系统镜像中例如system/bin/init.test.sh并在Android.mk或Android.bp中声明为可执行文件。示例Android.mkLOCAL_PATH : $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE : init.test.sh LOCAL_SRC_FILES : init.test.sh LOCAL_MODULE_CLASS : EXECUTABLES LOCAL_MODULE_PATH : $(TARGET_OUT_EXECUTABLES) LOCAL_MODULE_TAGS : optional LOCAL_STRIP_MODULE : false include $(BUILD_PREBUILT)或者Android.bpprebuilt_executable { name: init.test.sh, srcs: [init.test.sh], owner: your_company, relative_install_path: bin, mode: 0755, }6.2 编译系统镜像mka systemimage -j$(nproc)烧写后重启设备。7. 第五步如何测试脚本是否生效7.1 方法一检查系统属性最简单的验证方式adb shell getprop sys.boot.test如果返回1说明脚本成功执行了。7.2 方法二查看内核日志使用dmesg查看是否有我们的日志输出adb shell dmesg | grep InitTest预期输出info[ 5.123456] InitTest: 开机启动脚本已执行7.3 方法三使用 logcat 查看日志因为我们用了log -t命令所以也能在 logcat 中看到adb logcat -s InitTest输出类似I/InitTest( 1234): 开机启动脚本已执行7.4 方法四串口日志高级调试如果有串口调试工具可以在早期阶段看到init解析.rc和执行脚本的过程。当出现如下错误时基本可以定位问题init: Unable to spawn service test_service... Permission denied这通常是 SELinux 上下文不匹配导致的。8. 常见问题与解决方案8.1 脚本没执行没有任何反应可能原因.rc文件未被加载路径拼写错误大小写、斜杠脚本没有放入最终镜像排查方法adb shell ls /system/bin/init.test.sh看是否存在adb shell getprop ro.product.device确认.rc是否针对当前设备加载检查 build log 是否包含你的脚本模块8.2 提示 “Permission denied” 或 SELinux 报错典型日志avc: denied { execute } for comminit nameinit.test.sh devsdaXX scontextu:r:init:s0 tcontextu:object_r:system_file:s0 tclassfile解决办法确保file_contexts正确映射了文件路径和类型确保.te文件中定义了exec_type使用permissive test_service;临时放开策略测试仅调试用8.3 脚本反复重启未加 oneshot如果你忘了加oneshotinit会认为服务异常退出并不断重启。加上oneshot后执行完即结束不会重复运行。8.4 脚本执行太早依赖的服务还没起来有些操作需要等到特定属性设置后才执行可以用on property:触发on property:sys.usb.configadb exec u:object_r:test_service_exec:s0 root root -- /system/bin/init.test.sh或者监听boot_completedon property:sys.boot_completed1 start test_service配合disabled使用更灵活service test_service /system/bin/init.test.sh class main user root group root oneshot disabled seclabel u:object_r:test_service_exec:s09. 最佳实践建议9.1 小心使用 root 权限尽量避免长期以 root 身份运行服务。如果只是初始化配置完全可以执行完就退出。9.2 日志先行结果可验每次调试都加一条log或setprop确保你能通过外部手段验证执行状态。9.3 使用专用命名空间不要用test_service这种通用名建议加上公司或项目前缀mycompany_init_service避免与其他模块冲突。9.4 脚本尽量简洁.rc启动的脚本应专注于“初始化”不要做耗时操作或网络请求。复杂逻辑建议交给后续服务处理。10. 总结通过本文的详细步骤你应该已经掌握了如何在 Android 系统中实现一个可靠的开机启动 shell 脚本。回顾一下关键点编写正确的 shell 脚本shebang 路径不能错将脚本编译进系统镜像并赋予可执行权限在.rc文件中定义service并设置oneshot和seclabel添加 SELinux 策略.tefile_contexts这是成败关键通过getprop、logcat、dmesg等方式验证执行结果虽然整个过程涉及多个系统组件init、SELinux、build 系统但只要按部就班操作完全可以掌握这一核心技能。无论是做 ROM 定制、自动化测试还是硬件适配这项能力都会成为你手中的一把利器。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询