Service保活 双进程
原文地址 blog.csdn.net
写在前头
保活Service我们需要做什么:
1.在应用被关闭后保活(最难)
2.在内用占用过大,系统自动释放内存时保活(优先杀死占用较高的Service)
3.重启手机后自动开启Service
4.手机息屏后不被释放内存
5.手动清理内存时保活
首先介绍一下Service的等级:
一、前台进程
二、可见进程
三、服务进程
四、后台进程
五、空进程 ---关闭应用后,没有清理缓存
所以为了提高优先级我们可以使用startForeground()方法将Service设置为前台进程。
一、在AndroidManifest中添加Service
1. <service android: 2. android:process="istep.service" //放入新进程 3. > 4. <intent-filter android:priority="1000"> 5. <!-- 系统启动完成后会调用--> 6. <action android:/> 7. <action android:/> 8. <action android: /> 9. <action android: /> 10. <action android: /> 11. <action android: /> 12. <action android: /> 13. </intent-filter> 14. </service> 17. <service android: 18. android:process=":GuardService"> 19. <intent-filter > 20. <!-- 系统启动完成后会调用--> 21. <action android:/> 22. <action android:/> 23. <action android: /> 24. <action android: /> 25. <action android: /> 26. <action android: /> 27. <action android: /> 28. </intent-filter> 29. </service>
二、双进程保护
1.创建aidl实现跨进程通信(新建一个aidl)
1. interface ProcessConnection { 2. /** 3. * Demonstrates some basic types that you can use as parameters 4. * and return values in AIDL. 5. */ 6. //删除不必要方法 7. }
2.创建主服务
` 1. /** 2. * 主进程 双进程通讯 3. * Created by db on 2018/1/11. 4. */ 6. public class StepService extends Service{ 7. @Nullable 8. @Override 9. public IBinder onBind(Intent intent) { 10. return new ProcessConnection.Stub() {}; 11. } 13. @Override 14. public int onStartCommand(Intent intent, int flags, int startId) { 15. startForeground(1,new Notification()); 16. //绑定建立链接 17. bindService(new Intent(this,GuardService.class), 18. mServiceConnection, Context.BIND_IMPORTANT); 19. return START_STICKY; 20. } 22. private ServiceConnection mServiceConnection = new ServiceConnection() { 23. @Override 24. public void onServiceConnected(ComponentName componentName, IBinder iBinder) { 25. //链接上 26. Log.d("test","StepService:建立链接"); 27. } 29. @Override 30. public void onServiceDisconnected(ComponentName componentName) { 31. //断开链接 32. startService(new Intent(StepService.this,GuardService.class)); 33. //重新绑定 34. bindService(new Intent(StepService.this,GuardService.class), 35. mServiceConnection, Context.BIND_IMPORTANT); 36. } 37. }; 39. } `
3.创建守护服务
`1. /** 2. * 守护进程 双进程通讯 3. * Created by db on 2018/1/11. 4. */ 6. public class GuardService extends Service{ 7. @Nullable 8. @Override 9. public IBinder onBind(Intent intent) { 10. return new ProcessConnection.Stub() {}; 11. } 13. @Override 14. public int onStartCommand(Intent intent, int flags, int startId) { 15. startForeground(1,new Notification()); 16. //绑定建立链接 17. bindService(new Intent(this,StepService.class), 18. mServiceConnection, Context.BIND_IMPORTANT); 19. return START_STICKY; 20. } 22. private ServiceConnection mServiceConnection = new ServiceConnection() { 23. @Override 24. public void onServiceConnected(ComponentName componentName, IBinder iBinder) { 25. //链接上 26. Log.d("test","GuardService:建立链接"); 27. } 29. @Override 30. public void onServiceDisconnected(ComponentName componentName) { 31. //断开链接 32. startService(new Intent(GuardService.this,StepService.class)); 33. //重新绑定 34. bindService(new Intent(GuardService.this,StepService.class), 35. mServiceConnection, Context.BIND_IMPORTANT); 36. } 37. }; 39. }` 
返回参数含义:
- 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和权限
1. <service android: 2. android:permission="android.permission.BIND_JOB_SERVICE" > 3. </service>
2、JobService代码
` 1. /** 2. * 用于判断Service是否被杀死 3. * Created by db on 2018/1/11. 4. */ 5. @TargetApi(Build.VERSION_CODES.LOLLIPOP)//5.0以后可用 6. public class JobWakeUpService extends JobService{ 7. private int JobWakeUpId = 1; 8. @Override 9. public int onStartCommand(Intent intent, int flags, int startId) { 10. //开启轮寻 11. JobInfo.Builder mJobBulider = new JobInfo.Builder( 12. JobWakeUpId,new ComponentName(this,JobWakeUpService.class)); 13. //设置轮寻时间 14. mJobBulider.setPeriodic(2000); 15. JobScheduler mJobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE); 16. mJobScheduler.schedule(mJobBulider.build()); 17. return START_STICKY; 18. } 20. @Override 21. public boolean onStartJob(JobParameters jobParameters) { 22. //开启定时任务 定时轮寻 判断应用Service是否被杀死 23. //如果被杀死则重启Service 24. boolean messageServiceAlive = serviceAlive(StepService.class.getName()); 25. if(!messageServiceAlive){ 26. startService(new Intent(this,StepService.class)); 27. } 29. return false; 30. } 32. @Override 33. public boolean onStopJob(JobParameters jobParameters) { 35. return false; 36. } 38. /** 39. * 判断某个服务是否正在运行的方法 40. * @param serviceName 41. * 是包名+服务的类名(例如:net.loonggg.testbackstage.TestService) 42. * @return true代表正在运行,false代表服务没有正在运行 43. */ 44. private boolean serviceAlive(String serviceName) { 45. boolean isWork = false; 46. ActivityManager myAM = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE); 47. List<ActivityManager.RunningServiceInfo> myList = myAM.getRunningServices(100); 48. if (myList.size() <= 0) { 49. return false; 50. } 51. for (int i = 0; i < myList.size(); i++) { 52. String mName = myList.get(i).service.getClassName().toString(); 53. if (mName.equals(serviceName)) { 54. isWork = true; 55. break; 56. } 57. } 58. return isWork; 59. } 60. } `
四、保证Service在开机后自动启动
(1)注册广播
1. <receiver android:> 2. <intent-filter> 3. <action android:/> 4. </intent-filter> 5. </receiver>
(2)广播代码
1. /** 2. * 开机完成广播 3. */ 5. public class mReceiver extends BroadcastReceiver { 6. @Override 7. public void onReceive(Context context, Intent intent){ 8. Intent mIntent = new Intent(context,StepService.class); 9. context.startService(mIntent); 10. } 11. }
五、保证息屏后不被释放资源杀死(WakeLock的使用)
(1)添加权限
<uses-permission android: />
(2)在创建Service以后调用方法
`1. /** 2. * 同步方法 得到休眠锁 3. * @param context 4. * @return 5. */ 6. synchronized private void getLock(Context context){ 7. if(mWakeLock==null){ 8. PowerManager mgr=(PowerManager)context.getSystemService(Context.POWER_SERVICE); 9. mWakeLock=mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,StepService.class.getName()); 10. mWakeLock.setReferenceCounted(true); 11. Calendar c=Calendar.getInstance(); 12. c.setTimeInMillis((System.currentTimeMillis())); 13. int hour =c.get(Calendar.HOUR_OF_DAY); 14. if(hour>=23||hour<=6){ 15. mWakeLock.acquire(5000); 16. }else{ 17. mWakeLock.acquire(300000); 18. } 19. } 20. Log.v(TAG,"get lock"); 21. }`
(3)在onDestroy()方法中调用释放锁的方法(避免占用内存)
1. synchronized private void releaseLock() 2. { 3. if(mWakeLock!=null){ 4. if(mWakeLock.isHeld()) { 5. mWakeLock.release(); 6. Log.v(TAG,"release lock"); 7. } 9. mWakeLock=null; 10. } 11. }
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中)
1. /** 2. * 开启所有Service 3. */ 4. private void startAllServices() 5. { 6. startService(new Intent(this, StepService.class)); 7. startService(new Intent(this, GuardService.class)); 8. if(Build.VERSION.SDK_INT >=Build.VERSION_CODES.LOLLIPOP) { 9. Log.d(TAG, "startAllServices: "); 10. //版本必须大于5.0 11. startService(new Intent(this, JobWakeUpService.class)); 12. } 13. }
注意:该方法不能保证在所有机型上有效,而且除非在必要时,否则不建议写这样的流氓软件。特别是谷歌在android7.0以后对管理加强,想要保活Service其实已经变得不太可能了,谷歌这样做无疑是为了减少流氓软件的数量,这样做也是可取的。
本文作者:cps666
本文链接:https://www.cnblogs.com/cps666/p/17318696.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
分类:
标签:
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步