保活Service我们需要做什么:

1.在应用被关闭后保活(最难)

2.在内用占用过大,系统自动释放内存时保活(优先杀死占用较高的Service)

3.重启手机后自动开启Service

4.手机息屏后不被释放内存

5.手动清理内存时保活

首先介绍一下Service的等级:

一、前台进程
二、可见进程
三、服务进程
四、后台进程
五、空进程  ---关闭应用后,没有清理缓存

所以为了提高优先级我们可以使用startForeground()方法将Service设置为前台进程。

一、在AndroidManifest中添加Service

<service android:name=".modle.StepService"android:process="istep.service"  //放入新进程><intent-filter android:priority="1000"><!-- 系统启动完成后会调用--><action android:name="android.intent.action.BOOT_COMPLETED"/><action android:name="android.intent.action.DATE_CHANGED"/><action android:name="android.intent.action.MEDIA_MOUNTED" /><action android:name="android.intent.action.USER_PRESENT" /><action android:name="android.intent.action.ACTION_TIME_TICK" /><action android:name="android.intent.action.ACTION_POWER_CONNECTED" /><action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" /></intent-filter>
</service><service android:name=".modle.GuardService"android:process=":GuardService"><intent-filter ><!-- 系统启动完成后会调用--><action android:name="android.intent.action.BOOT_COMPLETED"/><action android:name="android.intent.action.DATE_CHANGED"/><action android:name="android.intent.action.MEDIA_MOUNTED" /><action android:name="android.intent.action.USER_PRESENT" /><action android:name="android.intent.action.ACTION_TIME_TICK" /><action android:name="android.intent.action.ACTION_POWER_CONNECTED" /><action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" /></intent-filter></service>

二、双进程保护

1.创建aidl实现跨进程通信(新建一个aidl)

interface ProcessConnection {/*** Demonstrates some basic types that you can use as parameters* and return values in AIDL.*///删除不必要方法}

2.创建主服务


/*** 主进程 双进程通讯* Created by db on 2018/1/11.*/public class StepService extends Service{@Nullable@Overridepublic IBinder onBind(Intent intent) {return new ProcessConnection.Stub() {};}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {startForeground(1,new Notification());//绑定建立链接bindService(new Intent(this,GuardService.class),mServiceConnection, Context.BIND_IMPORTANT);return START_STICKY;}private ServiceConnection mServiceConnection = new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName componentName, IBinder iBinder) {//链接上Log.d("test","StepService:建立链接");}@Overridepublic void onServiceDisconnected(ComponentName componentName) {//断开链接startService(new Intent(StepService.this,GuardService.class));//重新绑定bindService(new Intent(StepService.this,GuardService.class),mServiceConnection, Context.BIND_IMPORTANT);}};}

3.创建守护服务

/*** 守护进程 双进程通讯* Created by db on 2018/1/11.*/public class GuardService extends Service{@Nullable@Overridepublic IBinder onBind(Intent intent) {return new ProcessConnection.Stub() {};}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {startForeground(1,new Notification());//绑定建立链接bindService(new Intent(this,StepService.class),mServiceConnection, Context.BIND_IMPORTANT);return START_STICKY;}private ServiceConnection mServiceConnection = new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName componentName, IBinder iBinder) {//链接上Log.d("test","GuardService:建立链接");}@Overridepublic void onServiceDisconnected(ComponentName componentName) {//断开链接startService(new Intent(GuardService.this,StepService.class));//重新绑定bindService(new Intent(GuardService.this,StepService.class),mServiceConnection, Context.BIND_IMPORTANT);}};}

返回参数含义:

START_STICKY:在Service被关闭后,重新开启Service
START_NOT_STICKY:服务被异常杀掉后,系统将会被设置为started状态,系统不会重启该服务,直到startService(Intent intent)方法再次被调用。
START_REDELIVER_INTENT:重传Intent,使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。
START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保证服务被kill后一定能重启。

三、使用JobService来实现应用退出后重启Service

1、在AndroidManifest中添加Service和权限

<!--JobService权限--><uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<receiver android:name=".modle.BootCompleteReceiver"><intent-filter><action android:name="android.intent.action.BOOT_COMPLETED"/></intent-filter>
</receiver>

2、JobService代码

/*** 用于判断Service是否被杀死* Created by db on 2018/1/11.*/
@TargetApi(Build.VERSION_CODES.LOLLIPOP)//5.0以后可用
public class JobWakeUpService extends JobService{private int JobWakeUpId = 1;@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {//开启轮寻JobInfo.Builder mJobBulider = new JobInfo.Builder(JobWakeUpId,new ComponentName(this,JobWakeUpService.class));//设置轮寻时间mJobBulider.setPeriodic(2000);JobScheduler mJobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);mJobScheduler.schedule(mJobBulider.build());return START_STICKY;}@Overridepublic boolean onStartJob(JobParameters jobParameters) {//开启定时任务 定时轮寻 判断应用Service是否被杀死//如果被杀死则重启Serviceboolean messageServiceAlive = serviceAlive(StepService.class.getName());if(!messageServiceAlive){startService(new Intent(this,StepService.class));}return false;}@Overridepublic boolean onStopJob(JobParameters jobParameters) {return false;}/*** 判断某个服务是否正在运行的方法* @param serviceName*            是包名+服务的类名(例如:net.loonggg.testbackstage.TestService)* @return true代表正在运行,false代表服务没有正在运行*/private boolean serviceAlive(String serviceName) {boolean isWork = false;ActivityManager myAM = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);List<ActivityManager.RunningServiceInfo> myList = myAM.getRunningServices(100);if (myList.size() <= 0) {return false;}for (int i = 0; i < myList.size(); i++) {String mName = myList.get(i).service.getClassName().toString();if (mName.equals(serviceName)) {isWork = true;break;}}return isWork;}
}

四、保证Service在开机后自动启动

1)注册广播

<receiver android:name=".modle.mReceiver"><intent-filter><action android:name="android.intent.action.BOOT_COMPLETED"/></intent-filter></receiver>

2)广播代码

/*** 开机完成广播*/public class mReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent){Intent mIntent = new Intent(context,StepService.class);context.startService(mIntent);}
}

五、保证息屏后不被释放资源杀死(WakeLock的使用)

(1)添加权限

<uses-permission android:name="android.permission.WAKE_LOCK" />

(2)在创建Service以后调用方法

/*** 同步方法   得到休眠锁* @param context* @return*/synchronized private void getLock(Context context){if(mWakeLock==null){PowerManager mgr=(PowerManager)context.getSystemService(Context.POWER_SERVICE);mWakeLock=mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,StepService.class.getName());mWakeLock.setReferenceCounted(true);Calendar c=Calendar.getInstance();c.setTimeInMillis((System.currentTimeMillis()));int hour =c.get(Calendar.HOUR_OF_DAY);if(hour>=23||hour<=6){mWakeLock.acquire(5000);}else{mWakeLock.acquire(300000);}}Log.v(TAG,"get lock");}

(3)在onDestroy()方法中调用释放锁的方法(避免占用内存)

synchronized private void releaseLock(){if(mWakeLock!=null){if(mWakeLock.isHeld()) {mWakeLock.release();Log.v(TAG,"release lock");}mWakeLock=null;}}

PARTIAL_WAKE_LOCK    保持CPU运转,屏幕和键盘灯有可能是关闭的。
SCREEN_DIM_WAKE_LOCK    保持CPU运转,允许保持屏幕显示但有可能是灰的,允许关闭键盘灯。
SCREEN_BRIGHT_WAKE_LOCK    保持CPU运转,保持屏幕高亮显示,允许关闭键盘灯。
FULL_WAKE_LOCK    保持CPU运转,保持屏幕高亮显示,键盘灯也保持亮度。
ACQUIRE_CAUSES_WAKEUP    不会唤醒设备,强制屏幕马上高亮显示,键盘灯开启。有一个例外,如果有notification弹出的话,会唤醒设备。
ON_AFTER_RELEASE    Wake Lock被释放后,维持屏幕亮度一小段时间,减少Wake Lock循环时的闪烁情况。

六、启动所有Service(在Activity中)

/*** 开启所有Service*/private void startAllServices(){startService(new Intent(this, StepService.class));startService(new Intent(this, GuardService.class));if(Build.VERSION.SDK_INT >=Build.VERSION_CODES.LOLLIPOP) {Log.d(TAG, "startAllServices: ");//版本必须大于5.0startService(new Intent(this, JobWakeUpService.class));}}

注意:该方法不能保证在所有机型上有效,而且除非在必要时,否则不建议写这样的流氓软件。特别是谷歌在android7.0以后对管理加强,想要保活Service其实已经变得不太可能了,谷歌这样做无疑是为了减少流氓软件的数量,这样做也是可取的。


Android Service保活的几种方法总结相关推荐

  1. Android启动服务的两种方法

    Android启动服务的两种方法 第一种方法 第二种方法 Android 5.0开始,只能使用显式Intent启动服务.其中,启动服务有2种方式,第一种是直接指定想要启动的服务:第二种是使用AIDL的 ...

  2. Android 更新UI的两种方法——handler和runOnUiThread()

    Android 更新UI的两种方法--handler和runOnUiThread() 在Android开发过程中,常需要更新界面的UI.而更新UI是要主线程来更新的,即UI线程更新.如果在主线线程之外 ...

  3. Android结束进程的几种方法

    Android 结束进程的几种方法 在开发过程中,遇到了测试的说关闭应用的时候出现了闪一下黑屏的情况,后面发现闪黑屏和杀掉进程有关系,这里就简单总结一下结束进程的几种方法,以及闪黑屏是如何解决的,防止 ...

  4. android 动画方式,Android Activity进出动画三种方法

    Android Activity进出动画三种方法 实现activity的进出场动画总共有3种方式,下面会一一列出,首先给出示例的动画xml文件. 动画的xml文件 android:fromYDelta ...

  5. android 实现毫秒定时器,Android实现定时器的五种方法实例详解

    一.Timer Timer是Android直接启动定时器的类,TimerTask是一个子线程,方便处理一些比较复杂耗时的功能逻辑,经常与handler结合使用. 跟handler自身实现的定时器相比, ...

  6. Android 设置音量的几种方法

    Android 设置音量的几种方法 Android 设置音量的几种方法 方法一.被动设置法 方法二.主动设置法 渐进设置 直接设置 按键设置 Android 设置音量的几种方法 在Android下,音 ...

  7. Android实现定时器的几种方法

    前言 这几天正在看Android官方的开发文档,里面有很多很值得思考的开发建议,有时间的朋友可以去看一下(官方是英文文档,如果看不懂可以通过浏览器插件翻译对比着看,还是很方便的). 其中一篇课程提到了 ...

  8. Android更新Ui的几种方法

    2019独角兽企业重金招聘Python工程师标准>>> 常用的几种方法简单概括有: - handler.sendMessage(); - handler.post(); - 在act ...

  9. 美团的android多渠道包的3种方法

    转: http://tech.meituan.com/mt-apk-packaging.html 美团Android自动化之旅-生成渠道包 zhihu2014-06-13 10:06 概述 每当发新版 ...

最新文章

  1. 简析服务端通过geotools导入SHP至PG的方法
  2. jquery 手型 鼠标穿过时_JS实现的鼠标跟随代码(卡通手型点击效果)
  3. springboot @JsonSerialize 的使用
  4. 计算机视觉与深度学习 | 相机抖动下的目标提取(Faster R-CNN+粒子群优化+图像配准)
  5. 数据结构与算法-- 二叉树后续遍历序列校验
  6. int与bigdecimal的相互转换
  7. vim学习笔记--代码折叠
  8. 实验1 201521410028
  9. JavaScript之爆肝汇总【万字长文❤值得收藏】
  10. 如何在 iPhone、iPad 和 Mac 上压缩照片?
  11. 梵语和藏语_《百字明》梵文和藏文发音区分
  12. python--数据类型
  13. 苹果服务器维护2017.12,2017年12月28日维护公告
  14. ctf镜子里面的世界_一个小编姐姐的CTF入坑之旅
  15. Proguard的Keep使用方法
  16. 服务器硬盘如何把硬盘装换到gpt格式化,装GPT硬盘系统的格式转换与diskpart命令使用方法...
  17. 为什么穷人不敢创业?
  18. Gamemaker小课堂#0 如何为 Windows 游戏编写 DLL 扩展
  19. excel表格拆分如何快速完成
  20. latex 中手写l的输入方法

热门文章

  1. php制作普通网站流程图,分享在线制作流程图的网页
  2. 南京计算机会计专业,理科全省位次5000名左右想学金融,师范,会计和计算机等专业应该怎么选?...
  3. 上海市高等学校信息技术水平考试——二三级人工智能技术及应用
  4. 基于机器学习组合模型的个人信用评估
  5. VR全景看考场,线上“踩点”不迷路
  6. Ants(POJ 1852)
  7. 学计算机设计制图需啥基础,学CAD制图需要什么软件
  8. Python面向对象程序设计期末考试复习题及答案(含编程题)
  9. YTUOJ-手机尾号评分
  10. java poi 加粗居中_poi生成excel整理(设置边框/字体/颜色/加粗/居中/)