如何保活后台服务
在Android Services (后台服务) 里面,我们了解了Android四大组件之一的Service,知道如何使用后台服务进行来完成一些特定的任务。但是后台服务在系统内存不足的时候,可能会被系统杀死。那么如何让后台服务尽量不被杀死呢?基本的解决思路主要有以下几种:
1. 提高Service的优先级:为防止Service被系统回收,可以尝试通过提高服务的优先级解决,android:priority=“1000” ,1000是最高优先级,数字越小,优先级越低。
2.把service写成系统服务,将不会被回收:在Manifest.xml文件中设置persistent属性为true,则可使该服务免受out-of-memory killer的影响。但是这种做法一定要谨慎,系统服务太多将严重影响系统的整体运行效率。
3.将服务改成前台服务 Foreground service:重写onStartCommand方法,使用StartForeground(int,Notification)方法来启动service。 对于通过startForeground启动的service,onDestory方法中需要通过stopForeground(true)来取消前台运行状态。
4.利用Android的系统广播:利用Android的系统广播检查Service的运行状态,如果被杀掉,就再起来,系统广播是Intent.ACTION_TIME_TICK,这个广播每分钟发送一次,我们可以每分钟检查一次Service的运行状态,如果已经被结束了,就重新启动Service
本次主要使用提高adj方式保活:
Android系统在运行时,如果遭遇到内存过低,为保证系统稳定与流畅,会回收一部分不常用的进程(当然很多三方rom如miui会在电量过低也会回收)。这个回收过程当然不是随意回收,系统需要有一个判断进程优先级的指标,帮助系统判断哪些资源是优先级高需要保留,哪些资源优先级比较低需要释放该资源。
ADJ就是系统杀死进程的重要指标
本文从linux\Android进程优先级:adj分数,浅析一下如何查看adj以及各个adj分数背后所代表的含义。
ADJ 如何查看
利用adb shell
1.ps | grep 包名 //查看当前app的进程号
2.cat /proc/进程号/oom_adj //查看当前进程的adj值(早期android和linux使用,现已废弃,但仍然有效
3.cat /proc/进程号/oom_score_adj //这个是新版本的查看adj的命令,adj有效值为-1000~1000
NATIVE_ADJ -1000 native进程
SYSTEM_ADJ -900 仅指system_server进程
PERSISTENT_PROC_ADJ -800 系统persistent进程
PERSISTENT_SERVICE_ADJ -700 关联着系统或persistent进程
FOREGROUND_APP_ADJ 0 前台进程
VISIBLE_APP_ADJ 100 可见进程
PERCEPTIBLE_APP_ADJ 200 可感知进程,比如后台音乐播放
BACKUP_APP_ADJ 300 备份进程
HEAVY_WEIGHT_APP_ADJ 400 重量级进程
SERVICE_ADJ 500 服务进程(A list中的service)
HOME_APP_ADJ 600 Home进程
PREVIOUS_APP_ADJ 700 上一个进程
SERVICE_B_ADJ 800 B List中的Service
CACHED_APP_MIN_ADJ 900 不可见进程的adj最小值
CACHED_APP_MAX_ADJ 906 不可见进程的adj最大值
一般情况adj到200,即我们常用的前台服务
在service 的onStartCommand中添加:
内联代码片
。
// An highlighted block
// 为了提高进程优先级(前台服务)
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
NotificationChannel channel = new NotificationChannel("channelId", "channelName",
NotificationManager.IMPORTANCE_HIGH);
nm.createNotificationChannel(channel);
Notification notification = new Notification.Builder(getApplicationContext(), "channelId")
.setContentText("This is a foreground service")
.setSmallIcon(R.drawable.ic_notification_white)
.setWhen(System.currentTimeMillis())
.build();
startForeground(110, notification);
在onDestroy中添加
// An highlighted block
@Override
public void onDestroy() {
super.onDestroy();
stopForeground(true);
}