Android service后台保活原理相关和测试结果

本文探讨了Android系统中后台Service保活的各种方法及其效果。通过实际测试不同品牌和版本的设备,总结出了有效策略,包括调整onStartCommand返回值、在onDestroy中重启Service、提高服务优先级及使用守护进程等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

引子:

目前在做的一个Android项目,涉及到了后台Service保活的问题,网上找了很多资料,基本的保活方法都测试了。结果是:不同的手机,不同的Android版本保活效果各有差异~。最难绕过的是个厂商对“后台程序保活”管理。


下面把相应的测试结果和保活方法罗列下。测试的机子有限,非常希望有不完整的地方能提出补充。

正文:

一、为什么我们的后台Service会被结束掉?

我想到的是有三个方面:1.Android系统内存回收机制,2.各厂商对后台程序的一个管理制度(就是允许程序后台运行那个),3.第三方软件的清理(360什么的)。求补充1

其中有的后台程序保护把程序结束的同时会把程序弄成停止状态,导致无法接收广播!
二、测试环境
手机:三星9100-4.1.2,三星9300-4.3,华为G730-4.1.2,华为TL00H-EMUI3.1(android 5.1.1),魅族MX4-Flyme4.2.8.2c(android 4.4.2)

手头能用的测试机就这些了。测试的service是一个最基本的service,在相应的生命周期的触发函数上做了输出。测试时都没有添加到后台保护中,注:三星的机子没找到有后台保护设置的地方。


三、我们的保活方案有哪些?

1.控制onStartCommand函数的返回值。
我对这个函数的理解是:当服务被异常终止时,是否重启服务?
有些文章里面在用这个做保活时,修改的是flag,在我实际测试中是无效。有效的做法是直接返回参数。另外默认的flags值为0,是START_STICKY_COMPATIBILITY。如下:
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		// TODO Auto-generated method stub
		return START_STICKY;
		//return super.onStartCommand(intent, flags, startId);
	}
测试结果:
魅族的机子:无效,不管默认还是修改参数,在DDMS里面直接结束进程后都不会重启服务。
其它三台机子(9100没测):默认参数的情况下就会重启服务,return START_STICKY 会重启,return START_NOT_STICKY 不会重启。
其它: 1.用360一键清理,或者360超级ROOT的手机优化,会杀死进程,过会儿还是会重启,只是会慢很多,大概是在排队重启服务。
2.一次测试完后确保服务重启后,执行了onStartCommand函数。

2.在service 的onDestory里面重启服务
这个在所有能触发onDestory的情况下都是有效的。4台测试机都测试过。直接startService 或者发送广播重启都可以 。
但能触发onDestory的情况,我不知道内存回收会不会触发。另外两种情况(2,3)是不触发的。我的测试方法是在“设置”-》应用管理-》正在运行-》停止服务。(这个是正常停止服务,会触发onDestory,所以上面的onStartCommand效果不会触发。)


3.提高服务的优先级
这个主要是针对第一种kill服务的情况,内存回收机制。由于这个测试比较难搭建。360清理什么把后台的进程都杀的,体现不出优先级这样的概念。我的建议是能提高就提高。下面例几种。
通知--前台service
创建一个通知使自己成为前台service
测试结果
360一键清理和手机优化,不会把该service结束掉。
对于后台保护:华为G730不结束service,魅族和华为TL00H都会结束service。
通知栏的保活效果还是可以的,一般的应用要求基本能满足了。

若有root权限:
  android:persistent="true",并放入system/app中
  测试结果:效果一般,三星9100上用360等清理工具杀不掉进程,在华为G730上没什么效果.(这个测试跟onStartCommand有点干扰

4.守护进程
双服务
360会同时杀掉两个服务,分两个apk也一样
native守护进程
360不会杀掉native的守护进程,但在魅族和华为TL00H中待机一段时间后还是会被杀掉。

结论和待续
1.一般的应用添加到后台保护进程后, 改个onStartCommand返回值,再加个通知。基本上大部分都能保活了。
2.双服务我觉得没有native守护进程来的好,虽然360,微信什么的都有几个进程服务,但如果不添加到后台保活的话,效果一样不能保活,也会进入停止状态。
3.但是.360手机助手会创建双natice守护进程做相互的看守。存活的效果会高一点点。“没添加到后台保活”一般只会杀一次,(魅族是屏幕关闭后5分钟,华为TL00H是屏幕关闭时)

附个native守护进程:利用socket来判断服务是否存在,需要在被保活的服务里创建一个监听socket。调试信息会在SD卡目录下创建一个daemon.log
使用方法:NDKFork port 包名/.服务名


Android 中,要实现 Service后台保活,可以尝试以下几种方法: 1. 使用前台服务(Foreground Service):将 Service 设置为前台服务,给它分配一个与用户正在进行的活动相关联的通知。这样可以提高 Service 的优先级,使其更不容易被系统杀死。示例代码如下: ```java // 在 Service 的 onStartCommand 方法中调用 Notification notification = new Notification.Builder(this, CHANNEL_ID) .setContentTitle("My Service") .setContentText("Running in background") .setSmallIcon(R.drawable.ic_notification) .build(); startForeground(notificationId, notification); ``` 2. 使用 JobScheduler:使用 JobScheduler 调度一个定期执行的任务,确保 Service 定期被唤醒以执行需要的操作。示例代码如下: ```java // 在合适的地方调用 JobScheduler jobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE); JobInfo jobInfo = new JobInfo.Builder(jobId, new ComponentName(this, MyJobService.class)) .setPeriodic(15 * 60 * 1000) // 每 15 分钟执行一次 .setPersisted(true) // 设备重启后保持任务有效 .build(); jobScheduler.schedule(jobInfo); ``` 3. 使用 AlarmManager:使用 AlarmManager 设置一个定时闹钟,在指定时间间隔内唤醒 Service 执行任务。示例代码如下: ```java // 在合适的地方调用 AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent(this, MyService.class); PendingIntent pendingIntent = PendingIntent.getService(this, 0, intent, 0); long intervalMillis = 15 * 60 * 1000; // 每 15 分钟执行一次 alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), intervalMillis, pendingIntent); ``` 请注意,这些方法都不是绝对保证 Service 不会被系统杀死。Android 系统对应用程序的资源使用有一定的限制,以确保设备的性能电池寿命。使用这些方法可以提高 Service 的存活率,但并不能完全消除被杀死的可能性。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值