android init初始化流程介绍

Android init 语法包括了5类声明:Actions,Services,Commands,Options,和Imports。

所有这些语法都是以行为解析单位,中间需要以空格为语法间隔,行首有#的将被认为是注释而不会被解析.

section是init.rc中的基本组成单位,section分为两种类型:Actions和Services,所有的commands或者options都属于section的内容。在第一个section之前的所有commands或者options都将被忽略。

Actions和Sevices都有唯一的命名,如果有第二个Action名字和前面的相同,那么这两个Actions的所有commands都将合并在一起。如果有第二个Sevice和前面的相同,那么它将被忽略并且会记录下来一个出错log。

所有init语法都是用.rc文件来配置的,一个系统中会在不同的目录中存在很多个.rc文件。/init.rc是主rc文件并且被init执行文件第一个解析,平台相关的主入口是/init.${ro.hardware}.rc。它负责整个system的initial setup。

当执行mount_all命令时,init进程会加载所有/{system,vendor,odm}/etc/init/目录中的所有.rc文件。我们可以通过在mount_all命令中来修改或者扩展我们需要加载的.rc文件所在的目录。

不同etc/init目录一般包含不同内容:

(1)/system/etc/init/ 是包含core系统项目,比如surfaceflinger,mediaservice,logcatd相关的.rc配置

(2)/vendor/etc/init/是包含了SOC级别的.rc配置的

(3)/odm/etc/init/是包含了终端OEM厂商的项目配置

所有的services要根据自己bin文件所在的位置防止.rc配置文件到对应的etc/init/目录中。有一个编译宏命令可以用来帮助开发者做这件事情,那就是LOCAL_INIT_RC.

举个例子:

logcated.rc和Android.mk存在于/system/core/logcat目录中,在编译过程中,Android.mk中的LOCAL_INIT_RC命令会把logcated.rc移动到/system/etc/init目录中。

这种做法把不同服务需要的init命令给区分开了,放置于不同文件和目录中,这样更加方便维护和merge代码。

使用在mount_all命令中,有两个options “early”和“late”,如果设置了“–early”,init会跳过对“latemount”修饰的目录的挂载。如果设置了“–late”,init会只挂载被“latemount”修饰的目录,但除了import的.rc文件。默认情况下,没有设置以上两种option的话,mount_all会挂载fstab中所有的目录。

Actions


格式如下:

on <trigger> [&& <trigger>] *

    <command>

    <command>

    <command>

Services


服务是一种程序,它由init来启动的并且当它退出时init也会restart。

格式如下:

service <name> <pathname> [ <argument> ]*

    <option>

    <option>

    <option>

Options


选项是service的一些配置,他们应决定什么时间以什么方式来启动service。下面将介绍一些比较常见和关键的options。

class <name>

    为服务指定一个class名字,同一个class中的所有的services将被同时启动或者同时停止。如果service没有制定这个option,那么它会被默认属于“default” 类型。

user <username>

    执行service之前设置它的username,当前默认是root用户

group <groupname> [ <groupname> ]*

    在启动service之前改变它的groupname,当前默认是root组。

setenv <name> <value>

    在启动service的进程环境中设置环境变量

disabled

    加入此option的service将不会由class的调用而自动启动,它需要被指名来启动。

critical

    这个选项意味着这是一个设备相关的service,如果这种service在4分钟时间内反复退出了4次,那么设备将会重启并且进入recovery模式。

 oneshot

     当服务退出时不要重新restart它。

onrestart

    当服务restart重启时,执行一个command。

Triggers

触发器是指一种事件来触发actions的执行。一般可以分成两种类型:event trigger和property trigger

Event trigger可以由“trigger”命令来产生,也可以有init程序中的“QueueEventTrigger()”函数来产生。一般需要一个简单的字符串作为参数,比如“boot”后者“late-init”。

Property trigger是在property改变时产生的一类事件。格式如下:“propety:=”或者“propety:=*”。

一个action可以有多个property trigger但是它只能有一个event trigger。

举例说明:


'on boot && property:a=b'

代表这这个action只能在boot 事件发生并且此时a=b的情况下才会执行。

'on property:a=b && property:c=d'

这个代表这action可以在三种情况下执行,

1)在boot阶段,a=b并且c=d

2)任何时间当a=b时,c的值被设置为和d相等

3)任何时间当c=d时,a的值被设置为和b相等

Commands



class_start <serviceclass>

    启动一个class的services

class_stop <serviceclass>

    停止一个class的services

class_reset <serviceclass>

    停止一个class的services但是并不disable他们。

mount_all <fstab> [ <path> ]* [--<option>]

   调用 fs_mgr_mount_all 挂载fstab并且imports对应目录下的 .rc files

exec [ <seclabel> [ <user> [ <group> ]* ] ] -- <command> [ <argument> ]*

    执行命令

mount <type> <device> <dir> [ <flag> ]* [<options>]、

    mount一个分区到一个目录中

umount <path>

    unmount一个分区

trigger <event>

    触发一个event事件

start <service>

    开始一个service

stop <service>

    停止一个service

restart <service>

    重启一个service

setprop <name> <value>

    设置一个系统prop

wait <path> [ <timeout> ]

    等待一个path的生成,超时时间可以设定

write <path> <content>

    写入path文件一个string

bootchart_init

    如果配置了bootchart,那就开始bootcharting。这条命令是包含在default init.rc中的。

Imports

import并不是一个命令,它是导入.rc配置文件的关键字。当包含.rc的文件被解析完后init才会开始去解析被包含的.rc文件。


格式如下:

import <path>

    如果path是一个文件,那么就按照文件来解析,如果是一个目录,就会把该目录中的所有.rc都进行解析一下。只在两个时间点会执行import操作:

1)当boot阶段加载ini.rc时

2)当mount_all后加载.rc时

debug

默认情况下,被init执行的程序会把stdout和stderr重定向到/dev/null。为了帮助debug,可以通过Android程序logwrapper。


example:

servcie akmd /system/bin/logwrapper  /sbin/akmd

为了快速编译,可以使用如下命令:


 mm -j

 m ramdisk-nodeps

 m bootimage-nodeps

 adb reboot bootloader

 fastboot boot $ANDROID_PRODUCT_OUT/boot.img

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android设备上,要初始化蓝牙功能需要进行一些步骤。首先,需要在AndroidManifest.xml文件中添加蓝牙权限声明,以便应用程序可以使用蓝牙功能。然后,需要在应用程序代码中获取BluetoothAdapter对象,这是所有蓝牙操作的入口点。可以通过调用getSystemService方法并传入Context.BLUETOOTH_SERVICE参数来获取BluetoothManager,再调用getAdapter方法获取BluetoothAdapter对象。 接下来,需要检查设备是否支持蓝牙功能。通过调用BluetoothAdapter的isEnabled方法,可以判断蓝牙功能是否开启。如果蓝牙功能关闭,可以请求用户打开蓝牙,代码如下: ```java Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); ``` 当用户选择启用蓝牙后,可以在onActivityResult方法中获取结果,并进行相应处理。 如果蓝牙已开启,可以开始搜索其他蓝牙设备。通过调用BluetoothAdapter的startDiscovery方法,可以开始搜索周围的蓝牙设备并将它们显示在列表中。 最后,要记得在应用程序不需要使用蓝牙功能时,调用BluetoothAdapter的disable方法来关闭蓝牙功能,以节省设备的电量。 总之,初始化Android蓝牙功能需要在AndroidManifest.xml中声明权限,获取BluetoothAdapter对象,检查蓝牙是否开启,并进行搜索其他蓝牙设备的操作。同时,在应用程序不需要使用蓝牙时要记得关闭蓝牙功能,以提高设备的电量利用率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值