2023-04-14 16:22阅读: 265评论: 0推荐: 0

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. }
`![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)

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. }` ![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)

返回参数含义:

  • 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. }
`![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)

四、保证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.     }`![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)

(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_RELEASEWake 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 中国大陆许可协议进行许可。

posted @   cps666  阅读(265)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起
  1. 1 404 not found REOL
404 not found - REOL
00:00 / 00:00
An audio error has occurred.