VMDaemonService.java 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. package com.vmloft.develop.daemon.services;
  2. import android.app.AlarmManager;
  3. import android.app.Notification;
  4. import android.app.PendingIntent;
  5. import android.app.Service;
  6. import android.content.Context;
  7. import android.content.Intent;
  8. import android.os.Build;
  9. import android.os.IBinder;
  10. import android.util.Log;
  11. import com.vmloft.develop.daemon.receiver.VMWakeReceiver;
  12. /**
  13. * 以实现内部 Service 类的方式实现守护进程,这里是利用 android 漏洞提高当前进程优先级
  14. *
  15. * Created by lzan13 on 2017/3/7.
  16. */
  17. public class VMDaemonService extends Service {
  18. private final static String TAG = VMDaemonService.class.getSimpleName();
  19. // 定时唤醒的时间间隔,这里为了自己测试方边设置了一分钟
  20. private final static int ALARM_INTERVAL = 1 * 60 * 1000;
  21. // 发送唤醒广播请求码
  22. private final static int WAKE_REQUEST_CODE = 5121;
  23. // 守护进程 Service ID
  24. private final static int DAEMON_SERVICE_ID = -5121;
  25. @Override public void onCreate() {
  26. Log.i(TAG, "VMDaemonService->onCreate");
  27. super.onCreate();
  28. }
  29. @Override public int onStartCommand(Intent intent, int flags, int startId) {
  30. Log.i(TAG, "VMDaemonService->onStartCommand");
  31. // 利用 Android 漏洞提高进程优先级,
  32. startForeground(DAEMON_SERVICE_ID, new Notification());
  33. // 当 SDk 版本大于18时,需要通过内部 Service 类启动同样 id 的 Service
  34. if (Build.VERSION.SDK_INT >= 18) {
  35. Intent innerIntent = new Intent(this, DaemonInnerService.class);
  36. startService(innerIntent);
  37. }
  38. // 发送唤醒广播来促使挂掉的UI进程重新启动起来
  39. AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
  40. Intent alarmIntent = new Intent();
  41. alarmIntent.setAction(VMWakeReceiver.DAEMON_WAKE_ACTION);
  42. PendingIntent operation = PendingIntent.getBroadcast(this, WAKE_REQUEST_CODE, alarmIntent,
  43. PendingIntent.FLAG_UPDATE_CURRENT);
  44. alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(),
  45. ALARM_INTERVAL, operation);
  46. /**
  47. * 这里返回值是使用系统 Service 的机制自动重新启动,不过这种方式以下两种方式不适用:
  48. * 1.Service 第一次被异常杀死后会在5秒内重启,第二次被杀死会在10秒内重启,第三次会在20秒内重启,一旦在短时间内 Service 被杀死达到5次,则系统不再拉起。
  49. * 2.进程被取得 Root 权限的管理工具或系统工具通过 forestop 停止掉,无法重启。
  50. */
  51. return START_STICKY;
  52. }
  53. @Override public IBinder onBind(Intent intent) {
  54. // TODO: Return the communication channel to the service.
  55. throw new UnsupportedOperationException("onBind 未实现");
  56. }
  57. @Override public void onDestroy() {
  58. Log.i(TAG, "VMDaemonService->onDestroy");
  59. super.onDestroy();
  60. }
  61. /**
  62. * 实现一个内部的 Service,实现让后台服务的优先级提高到前台服务,这里利用了 android 系统的漏洞,
  63. * 不保证所有系统可用,测试在7.1.1 之前大部分系统都是可以的,不排除个别厂商优化限制
  64. */
  65. public static class DaemonInnerService extends Service {
  66. @Override public void onCreate() {
  67. Log.i(TAG, "DaemonInnerService -> onCreate");
  68. super.onCreate();
  69. }
  70. @Override public int onStartCommand(Intent intent, int flags, int startId) {
  71. Log.i(TAG, "DaemonInnerService -> onStartCommand");
  72. startForeground(DAEMON_SERVICE_ID, new Notification());
  73. stopSelf();
  74. return super.onStartCommand(intent, flags, startId);
  75. }
  76. @Override public IBinder onBind(Intent intent) {
  77. // TODO: Return the communication channel to the service.
  78. throw new UnsupportedOperationException("onBind 未实现");
  79. }
  80. @Override public void onDestroy() {
  81. Log.i(TAG, "DaemonInnerService -> onDestroy");
  82. super.onDestroy();
  83. }
  84. }
  85. }