双进程守护

公司的产品要求在程序被杀死后,程序的服务依然存活(像今日头条,腾讯新闻被杀死后后台服务依然存在,无法杀死),听到这个需求这也是好多的羊驼再奔腾,最开始想法很简单,就是服务死后怎么被唤醒,
最先使用了 监听系统广播的方法,来唤醒挂掉的服务,发现静态监听不到。因为好多系统广播已经不支持静态注册。
后来在上网上查找相关资料,发现了一个至今还有效的方法那就是双进程守护。
双进程守护的实现:来利用cpu 执行处理杀死进程的时间间隔,也就是两个进程相互监听,一个进程挂了,另一个进程接收到后重新启动挂掉的进程,反之一样。那么

如何进行双进程守护

  • 在app中开启两个进程:在清单文件中开启一个新的进程,
  • 两个进程之间建立联系 :aidl ,bindService
  • 监听两个进程的异常断开(如被杀死,别一键清理软件清理,手动停止):ServiceConnection

那么下面,贴一下 代码

AndroidManifest.xml

1
2
3
4
5
6
7
8
<service
android:name=".service.Service1"
android:enabled="true"
android:process=":service1"></service>
<service
android:name=".service.Service2"
android:enabled="true"
android:process=":service2"></service>

aidl 用于两个进程之间的交互

1
2
3
4
5
6
7
8
9
interface IProgressService {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
// void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
// double aDouble, String aString);
String getServiceName();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
> service1
public class Service1 extends Service {
@Override
public void onCreate() {
myBinder=new MyBinder();
if(myConn==null){
myConn=new MyConn();
public class Service1 extends Service {
@Override
public void onCreate() {
myBinder=new MyBinder();
if(myConn==null){
myConn=new MyConn();
}
Toast.makeText(Service1.this, "Service1 正在启动...", Toast.LENGTH_SHORT)
.show();
}
@Override
public IBinder onBind(Intent intent) {
return myBinder;
}
@Override
public void onDestroy() {
super.onDestroy();
}
private MyBinder myBinder;
class MyBinder extends IProgressService.Stub{
@Override
public String getServiceName() throws RemoteException {
return "Service1";
}
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Service1.this.bindService(new Intent(Service1.this,Service2.class),myConn, Context.BIND_IMPORTANT );
}
private MyConn myConn;
class MyConn implements ServiceConnection{
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i("Service1","程序 1 链接 程序2成功");
}
@Override
public void onServiceDisconnected(ComponentName name) {
Toast.makeText(Service1.this, "Service2 链接断开...", Toast.LENGTH_SHORT).show();
Service1.this.startService(new Intent(Service1.this,Service2.class));
Service1.this.bindService(new Intent(Service1.this,Service2.class),myConn, Context.BIND_IMPORTANT );
}
}
}
}
Toast.makeText(Service1.this, "Service1 正在启动...", Toast.LENGTH_SHORT)
.show();
}
@Override
public IBinder onBind(Intent intent) {
return myBinder;
}
@Override
public void onDestroy() {
super.onDestroy();
}
private MyBinder myBinder;
class MyBinder extends IProgressService.Stub{
@Override
public String getServiceName() throws RemoteException {
return "Service1";
}
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Service1.this.bindService(new Intent(Service1.this,Service2.class),myConn, Context.BIND_IMPORTANT );
}
private MyConn myConn;
class MyConn implements ServiceConnection{
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i("Service1","程序 1 链接 程序2成功");
}
@Override
public void onServiceDisconnected(ComponentName name) {
Toast.makeText(Service1.this, "Service2 链接断开...", Toast.LENGTH_SHORT).show();
Service1.this.startService(new Intent(Service1.this,Service2.class));
Service1.this.bindService(new Intent(Service1.this,Service2.class),myConn, Context.BIND_IMPORTANT );
}
}
}

service2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
public class Service2 extends Service {
@SuppressLint("NewApi")
public void onCreate() {
myBinder=new MyBinder();
if(myConn==null){
myConn=new MyConn();
}
Toast.makeText(Service2.this, "Service2 启动中...", Toast.LENGTH_SHORT)
.show();
}
@Override
public IBinder onBind(Intent intent) {
// return (IBinder) startS1;
return myBinder;
}
@Override
public void onDestroy() {
super.onDestroy();
Log.e("s","onDestroy2");
}
private MyBinder myBinder;
class MyBinder extends IProgressService.Stub{
@Override
public String getServiceName() throws RemoteException {
return "Service2";
}
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Service2.this.bindService(new Intent(Service2.this,Service1.class),myConn, Context.BIND_IMPORTANT );
}
private MyConn myConn;
class MyConn implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i("Service2","程序 2 链接 程序1成功");
}
@Override
public void onServiceDisconnected(ComponentName name) {
Toast.makeText(Service2.this, "Service1 链接断开...", Toast.LENGTH_SHORT).show();
Service2.this.startService(new Intent(Service2.this,Service1.class));
Service2.this.bindService(new Intent(Service2.this,Service1.class),myConn, Context.BIND_IMPORTANT );
}
}
}

这样只要不是同一时间杀死两个进程,那么进程就会复活,但有的手机可以杀死进程组(如华为手机)那么可以用jobService.
这里有一篇jobService介绍用法

Android5.0之后用JobService可以进行保护

JobScheduleService

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
@SuppressLint("NewApi")
public class JobScheduleService extends JobService {
private int kJobId = 0;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("job", "jobService启动");
scheduleJob(getJobInfo());
return START_NOT_STICKY;
}
@Override
public boolean onStartJob(JobParameters params) {
Log.i("job", "onStartJob");
boolean isLocalServiceWork = Utils.isServiceWork(this, "com.ctoyo.protect.service.Service1");
boolean isRemoteServiceWork = Utils.isServiceWork(this, "com.ctoyo.protect.serviceService2");
if(!isLocalServiceWork||
!isRemoteServiceWork){
this.startService(new Intent(this,Service1.class));
this.startService(new Intent(this,Service2.class));
Toast.makeText(this, "进程复活", Toast.LENGTH_SHORT).show();
}
return true;
}
@Override
public boolean onStopJob(JobParameters params) {
Log.i("job", "onStopJob");
scheduleJob(getJobInfo());
return true;
}
public void scheduleJob(JobInfo t) {
Log.i("job ", "scheduleJob");
JobScheduler tm =
(JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
tm.schedule(t);
}
public JobInfo getJobInfo(){
JobInfo.Builder builder = new JobInfo.Builder(kJobId++, new ComponentName(this, JobScheduleService.class));
builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
builder.setPersisted(true);
builder.setRequiresCharging(false);
builder.setRequiresDeviceIdle(false);
builder.setPeriodic(1000);
return builder.build();
}
}

点击demo下载