Android守护进程

这几天,一位做Android的朋友和我探讨了一个问题:因为业务需求的原因,在自己的App长时间不使用被kill掉之后,如何让它再重新运行起来。

虽然,我本身很排斥这种做法,有点类似“流氓软件”的行为,但是还是查询了资料,大概想了一个实现的方式,和大家一起分享。

其实,这个问题可以简单的看作:如何编写一个守护进程

使用C/C++编写一个守护进程的.so程序,Android端通过JNI调用。该进程监听当前的目标程序进程,如果目标程序被kill掉了,再重新start一下,大概的思路就是这样。伪代码如下:

int pid = fork();
if(pid <0)
{    
    printf("Error\n");
    exit(0);
}
else if(pid > 0)
{
    printf("this is father\n");
    exit(0);
}
else if(pid == 0) // child1
{
    setsid();
    int pid = fork();
    if(pid  == 0) // child2
    {
        while(1)
        {
            if(App is killed)
                start App again;
        }
    }
}

这其中,缺少了:

①unmask(),因为从父进程继承下来了一些东西,所以需要设置一定的权限进行操作。

②chdir("/")。

③关闭从父进程继承而来的不需要的文件描述符,否则就可能造成资源的浪费。

为什么要进行两次fork()?

在这段伪代码中,进行了两次fork()操作,其实很多文章在描述守护进程时都只是仅仅的进行了一次fork操作就结束了,这里我想仔细讲一讲原因。

首先,setsid()函数的作用。一般而言,父进程和子进程都处在一个session当中,父进程是session的领头进程。如果当父进程(领头进程)被杀死之后,那么同一个session中的所有进程都会被杀死,或者成为孤儿进程而被init托管。所以,我们需要让子进程调用setsid(),创建一个新的session并将自己设置为该session的领头进程(若领头进程调用setsid()则没有任何效果)。这样,如果父进程被kill掉,因为他们并不在一个session中,所以子进程仍然可以继续执行。由于session对控制终端的独占性,进程同时与控制终端脱离。

session中包含了很多东西,如:控制终端、进程组等等。如果我们只fork()一次,将第一个由父进程创建出的子进程分离出来作为守护进程,一般情况下也是没有什么问题的。但是,如果此时通过什么方式通过此进程创建出了一个与自己的session相关联的控制终端,那么则会产生一定的影响。所以,则有了第二次fork()的意义。第二次fork使用子进程创建出了一个“孙子进程”,并且我们还是使用第一个父进程创建出的子进程进行setsid()但它并不是守护进程,该孙子进程进行守护进程相关的操作。这就有效的避免了上文提到的问题的产生,因为子进程创建出了一个新的session,并且作为该session的领头进程,同时这个session包含了该孙子进程且它并不是领头进程。那么该孙子进程就永远无法创建出一个控制终端,也就没有任何影响。

存在的问题

代码中使用轮询的方式来查询,App进程是否被kill了,这样效率十分低下,会导致手机的电量损耗很快。是否可以通过进程间通信的方式,如:socket等等,进行相关操作。

转载于:https://www.cnblogs.com/saintlas/p/5876849.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值