Android守护进程
这几天,一位做Android的朋友和我探讨了一个问题:因为业务需求的原因,在自己的App长时间不使用被kill掉之后,如何让它再重新运行起来。
虽然,我本身很排斥这种做法,有点类似“流氓软件”的行为,但是还是查询了资料,大概想了一个实现的方式,和大家一起分享。
其实,这个问题可以简单的看作:如何编写一个守护进程。
使用C/C++编写一个守护进程的.so程序,Android端通过JNI调用。该进程监听当前的目标程序进程,如果目标程序被kill掉了,再重新start一下,大概的思路就是这样。伪代码如下:
int pid = fork();
if(pid <)
{
printf("Error\n");
exit();
}
else if(pid > )
{
printf("this is father\n");
exit();
}
else if(pid == ) // child1
{
setsid();
int pid = fork();
if(pid == ) // child2
{
while()
{
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等等,进行相关操作。
Android守护进程的更多相关文章
- 创建Android守护进程(底层服务)【转】
本文转载自:https://blog.csdn.net/myfriend0/article/details/80016739 创建Android守护进程(底层服务) 前言 Android底层服务,即运 ...
- Android 通过JNI实现守护进程,使得Service服务不被杀死
来自: http://finalshares.com/read-7306 转载请注明出处: http://blog.csdn.net/yyh352091626/article/details/5054 ...
- android 通过AlarmManager实现守护进程
场景:在app崩溃或手动退出或静默安装后能够自动重启应用activity 前提:得到系统签名 platform.pk8.platform.x509.pem及signapk.jar 三个文件缺一不可(系 ...
- android双进程守护,让程序崩溃后一定可以重启
由于我们做的是机器人上的软件,而机器人是24小时不间断服务的,这就要求我们的软件不能退出到系统桌面.当然最好是能够做到程序能够不卡顿,不崩溃,自己不退出.由于我们引用了很多第三方的开发包,也不能保证他 ...
- Android init进程概述
init进程,其程序位于根文件系统中,在kernle自行启动后,其中的 start_kernel 函数把根文件系统挂载到/目录后,在 rest_init 函数中通过 kernel_thread(ker ...
- APP中一种在Java层实现的简单守护进程方式
转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52779986 守护进程是一个黑色 ...
- ANDROID init进程
init简要 init是Android上启动的第一个用户态进程. 执行序列是: start_kernel() -> rest_init() -> kernel_init() -> i ...
- 一篇文章了解相见恨晚的 Android Binder 进程间通讯机制【转】
本文转载自:https://blog.csdn.net/freekiteyu/article/details/70082302 Android-Binder进程间通讯机制 概述 最近在学习Binder ...
- dhcpcd守护进程分析【转】
本文转载自;http://blog.csdn.net/lishanmin11/article/details/37930073 最近在调android ethernet功能,android本身不带 e ...
随机推荐
- Yii入门☞应用
Yii 应用的静态结构 应用: require可以有返回值,Yii中经常返回数组用以配置.以前只知道引用文件成功返回1. controllerMap属性允许你指定一个控制器ID到任意控制器类,修改配置 ...
- js检测手机摇一摇
1.检测设备是否支持重力感应事件deviceorientation deviceorientation 提供设备的物理方向信息,表示为一系列本地坐标系的旋角 function motionHandle ...
- ios上position:fixed失效问题
手机端上的猫腻真是多啊~~~ 此起彼伏! 最近又遇到了 固定定位的底部导航在ios上被弹出去 此时内心1w+个草泥马奔过~~~~~~~~ 直接上解决方案: <div class="ma ...
- iOS 面试题(五):weak 的内部实现原理 --转自唐巧
问题 weak 变量在引用计数为0时,会被自动设置成 nil,这个特性是如何实现的? 答案 在 Friday QA 上,有一期专门介绍 weak 的实现原理.https://mikeash.com/p ...
- 如何理解C#委托
一:从下面的例子开始,理解委托变量本质 如上图,Condition是我定义的委托变量.这个委托变量的本质就是地址变量(即C语言当中的指针变量),它保存的是方法的入口地址. 当函数的调用者传递实参给这个 ...
- 详解一个自己原创的正则匹配IP的表达式
这里给大家详细讲解一下一个匹配IP地址的正则表达式, 有关正则方面的知识,会在详细的讲解中提到. 在讲解之前,我先给大家介绍一下,ip地址的生成规则. IP地址,是由32位数字二进制转为四个十进制的字 ...
- python正则
1.. 匹配任意除换行符"\n"外的字符:2.*表示匹配前一个字符0次或无限次:3.+或*后跟?表示非贪婪匹配,即尽可能少的匹配,如*?重复任意次,但尽可能少重复:4. .*? 表 ...
- 搭建git for windows服务器(100%可以成功)
既然Git在Linux下面非常好用,为什么还要搭建git windows的服务器,因为不是所有的用户都需要在linux下面做开发,对吧,还有很多用户选择使用windows做开发. 看到很多网友尝试部分 ...
- javascript的缓动效果
这部分对原先的缓动函数进行抽象化,并结合缓动公式进行强化.成品的效果非常惊人逆天.走过路过不要错过. 好了,打诨到此为止.普通的加速减速是难以让人满意的,为了实现弹簧等让人眼花缭乱的效果必须动用缓动公 ...
- delphi中exit,abort,break,continue 的区别
from:http://www.cnblogs.com/taofengli288/archive/2011/09/05/2167553.html delphi中表示跳出的有break,continue ...