一、引言
本文,我们通过修改Android操作系统源码,在原生的Android项目中增加一个我们自定义的线程来执行相关任务,并修改init.rc,来增加启动过程中的任务。
本文中涉及到了很多android中的知识,在我之前的博文中都有讲解,本文只介绍整个流程,不会详细介绍某一块,有问题的同学可以回去看下我之前的博客。
二、Android系统程序的整理框架
下面我准备了一张图来反映大体框架
我们需要做以下几步来将我们自己的程序添加入系统的开机流程
1、编写需要执行的程序
#include<stdio.h>
int main(){
int i=0;
for(i;i<100;i++)
{
sleep(180);
printf("I am a process\n");
}
return 0;
}
2、将编写好的程序放入源码中的某一目录:(需事先查找上次的mk文件,确定该目录下的子目录会都被编译到),一般放入vendor中的相关目录
3、Android.mk: 在对应目录下编写Android.mk,将我们编写的程序根据需要封装成一个可执行文件
4、在“android/device/xxx/xxx/Productxxx.mk”中添加如下语句,将生成的模块编入系统
PRODUCT_PACKAGES += xxx(模块名)
5、init.rc: 去device下找到我们产品相关的目录,找到init.rc(部分公司会直接include成自己的启动文件,我们直接去其文件中即可),在其中遵循格式Android源码之init.rc文件详解来增加自己的启动项
如下:
service qya /system/bin/loop
class main
console
oneshot
console表示服务需要并运行在控制台,oneshot表示服务只运行一次,在退出时将服务设置为禁用
也许有人会发现,class main这是个什么东西,好像没讲,然而我并不是忘了,我在这里再详细讲讲。我之前讲过start命令是在on中启动serice,但是通览整个init.rc文件,我们会发现,直接使用start命令启动service的情况非常少,我之前也用这种方式试过几次,但都未能成功。所以我在仔细阅读和查询资料后发现,大多数inti进程fork出来的开机启动进程都是用另外一种方式来启动。我们来看看下面一个on行为的定义:
on property:vold.decrypt=trigger_restart_min_framework
class_start main
我在这里再简单说一下on,on分为两种:
第一种:一共有7个,它们是一定会随inti进程的启动而执行的,比如我们上面介绍init.rc的时候展示的early-init正是这7个on中的第一个。
第二种:则是在满足某些特定条件时才会启动的,比如我们这里的这个on就是第二种。
我们看到它下面有一条class_start main命令,而我们的service下面第一个属性正是class main。所以可以理解了,这个class_start main命令是启动main下面所有service。通览init.rc文件,我们会发现属于main的service非常多,所以我们的service也就搭一趟便车,挤上main的队伍。
6、了解SEAndroid机制(该机制有些复杂,本人也还没去看),在
external/sepolicy目录下模仿其他可执行模块的.te文件,写一个.te文件来给定其权限
7、重新编译,烧写程序即可
开机后,如果你编写的自定义程序会执行很长一段时间,则可使用"ps -Z"来找到与模块名相同名称的进程名