一种较方便在Android中添加开机自启动的守护进程的方法

来源:互联网 发布:linux命令大全app 编辑:程序博客网 时间:2024/04/29 21:38

运用本方法的前提是你已经把android源码的sdk编译出来了。在你的Android源码目录下存在这两个目录:

./out/target/product/generic/ramdisk.img


./out/host/linux-x86/sdk/android-sdk_eng.root_linux-x86/platforms/android-2.3.4/images/ramdisk.img

下面通过在Android系统启动时启动一个守护进程,其功能是向指定文件中写。

共4步:1、解压ramdisk.img 2、用c语言完成要实现的功能 3、修改init.rc,启动c语言可执行程序  4、制作ramdisk.img


1、解压ramdisk.img:

  解压、修改Android的ramdisk.img的手动方法:

  将ramdisk.img复制一份到任何其他目录下,将其名称改为ramdisk.img.gz,并使用命令

gunzip ramdisk.img.gz

  然后新建一个文件夹,叫ramdisk吧,进入,输入命令
cpio -i -F ../ramdisk.img
  就能把ramdisk.img解压出来了并可以操作ramdisk里面的内容了。

2、完成一个C语言程序hello.c,来实现功能。

a。首先,代码如下:


[cpp] view plaincopyprint?
  1. <span style="font-size: 18px;"
  2.  
  3.  
  4. /************************程序开始**************************/ 
  5.  
  6. #include <stdio.h> 
  7.  
  8. #include <stdlib.h> 
  9.  
  10. #include <unistd.h> 
  11. #include <sys/time.h> 
  12. #include <sys/resource.h> 
  13. #include <sys/types.h> 
  14. #include <sys/stat.h> 
  15. #include <fcntl.h> 
  16.  
  17. int main(void
  18.  
  19.     int i=0; 
  20.  
  21.     int fd; 
  22.  
  23.     pid_t pid; 
  24.  
  25.     struct rlimit rl; 
  26.  
  27.     char str[]="hello world...\n"
  28.  
  29.  
  30.     umask(0); 
  31.     if(getrlimit(RLIMIT_NOFILE,&rl)<0) 
  32.         printf("getrlimit函数调用出现错误!\n"); 
  33.     if((pid=fork())<0) 
  34.     { 
  35.         printf("fork出现错误!\n"); 
  36.         exit(1); 
  37.     } 
  38.     else if(pid>0)//父进程退出 
  39.     { 
  40.         printf("父进程退出,它的ID为%d,它的子进程ID为%d\n",getpid(),pid); 
  41.         exit(0); 
  42.     } 
  43.     //子进程 
  44.     sleep(2); 
  45.     printf("子进程ID为%d\n",getpid()); 
  46.  
  47.     setsid(); 
  48.     if((pid=fork())<0) 
  49.     { 
  50.         printf("fork出现错误!\n"); 
  51.         return -1; 
  52.     } 
  53.     else if(pid>0)//第一个子进程退出 
  54.     { 
  55.         printf("第一个子进程退出,它的ID为%d,它的子进程ID为%d\n",getpid(),pid);/*这个printf的内容可以被输出,貌似是因为它所在的进程虽然失去了终端,但它是一个会话组的首进程,因此看到有printf后,自己又申请了一个终端?*/ 
  56.         exit(0); 
  57.     } 
  58.  
  59.     //第二个子进程 
  60.     printf("不会输出这一行。\n");/*这个printf的内容将不会在屏幕上输出,原因可能是因为它所在的进程此时已经不是一个会话组的首进程,无法重新申请获得终端?*/ 
  61.     chdir("/"); 
  62.     if(rl.rlim_max==RLIM_INFINITY) 
  63.         rl.rlim_max=1024; 
  64.     printf("%d",(int)rl.rlim_max); 
  65.     for(i=0;i<rl.rlim_max;i++) 
  66.         close(i); 
  67.     open("/dev/null",O_RDWR); 
  68.     dup(0); 
  69.     dup(0); 
  70.     
  71.     //每隔5s向文件内写入一次数据 
  72.     while(1) 
  73.     { 
  74.         fd=open("/data/hello.txt",O_WRONLY|O_CREAT|O_APPEND,0766);/*这里的/data指的是android系统上的/data目录*/ 
  75.         write(fd,str,sizeof(str)); 
  76.         sleep(5); 
  77.     } 
  78.     close(fd); 
  79.     exit(0); 
  80.  
  81.  
  82. /************************程序结束**************************/ 
  83.  
  84. </span> 

b。然后编译此程序成为android下可执行程序:

在当前目录下建立Android.mk文件,输入以下内容:

[cpp] view plaincopyprint?
  1. <span style="font-size: 18px;"
  2.  
  3. LOCAL_PATH:=$(call my-dir) 
  4. include $(CLEAR_VARS) 
  5. LOCAL_MODULE_TAGS := optional 
  6. LOCAL_MODULE:=helloworld 
  7. LOCAL_SRC_FILES:=hello.c 
  8. include $(BUILD_EXECUTABLE) 
  9.                                     </span> 
保存退出,之后cd到android源码目录下,运行make  helloworld 命令。如果成功编译,生成的helloworld会在目录out/target/product/generic/system/bin/下,把生成的helloworld执行文件push到模拟器的/data目录中去:


#adb push helloworld /data


3、修改ramdisk目录下init.rc文件,让其启动helloworld程序,增加以下代码

[cpp] view plaincopyprint?
  1. <span style="font-size: 18px;"
  2.  
  3.  
  4. #add by me on 2010-10-18     
  5. service chpermission   /data/ chpermission  
  6. oneshot</span> 


4、制作ramdisk.img:

init.rc修改之后,可以使用下列命令重新打包成镜像
cpio -i -t -F ../ramdisk.img > list
  cpio -o -H newc -O lk.img < list

  当前目录下生成的lk.img就是我们的新镜像了。

 将ramdisk.img拷贝到sdk指向的目录。重启模拟器。
原创粉丝点击