在上一篇博客中,咱们谈到了Android进程防杀的经常使用套路,各位童鞋能够点击查看个人博客Android应用进程防杀指南1-经常使用套路,随着愈来愈多的用户手机安装某卫士,某管家,经常使用的进程防杀套路并不可以很好的保证咱们的APP进程常驻,所以本篇博客我给你们带来抗某卫士,某管家的双进程守护解决方案。双进程守护,其实原理很是简单,网上也有不少博文讲述,今天我给你们用一个完整的案例来说述。java
假设咱们的APP中开启了两个Service,分别是A和B,那么:
若是A守护B,则B挂掉的同时,A就应该把B启动起来,反之亦然,也就是说A和B应该是互相守护,不管谁被杀掉,对方就把它拉起来。android
既然提到了两个Service,那么这两个Service就不能让它们同处在一个进程中,不然就会被一次性双杀。这里咱们很容易想到IPC技术,在Android中一般咱们可使用AIDL来实现IPC操做。废话很少说,直接撸码。
先来看下项目总体结构:markdown
这里,咱们定义两个Service,分别是LocalCastielService和RemoteCastielService,其中的RemoteCastielService咱们经过属性配置android:process=”:com.castiel.remote” ,让它成为远端进程。
LocalCastielService.javaide
/** * @ClassName: LocalCastielService * @Description: 本地服务 * @author 猴子搬来的救兵 http://blog.csdn.net/mynameishuangshuai * @version */ public class LocalCastielService extends Service { MyBinder myBinder; private PendingIntent pintent; MyServiceConnection myServiceConnection; @Override public void onCreate() { super.onCreate(); if (myBinder == null) { myBinder = new MyBinder(); } myServiceConnection = new MyServiceConnection(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { this.bindService(new Intent(this, RemoteCastielService.class), myServiceConnection, Context.BIND_IMPORTANT); Notification notification = new Notification(R.drawable.ic_launcher, "猴子服务启动中", System.currentTimeMillis()); pintent = PendingIntent.getService(this, 0, intent, 0); notification.setLatestEventInfo(this, "猴子服务", "防止被杀掉!", pintent); // 设置service为前台进程,避免手机休眠时系统自动杀掉该服务 startForeground(startId, notification); return START_STICKY; } class MyServiceConnection implements ServiceConnection { @Override public void onServiceConnected(ComponentName arg0, IBinder arg1) { Log.i("castiel", "远程服务链接成功"); } @Override public void onServiceDisconnected(ComponentName arg0) { // 链接出现了异常断开了,RemoteService被杀掉了 Toast.makeText(LocalCastielService.this, "远程服务Remote被干掉", Toast.LENGTH_LONG).show(); // 启动RemoteCastielService LocalCastielService.this.startService(new Intent(LocalCastielService.this, RemoteCastielService.class)); LocalCastielService.this.bindService(new Intent(LocalCastielService.this, RemoteCastielService.class), myServiceConnection, Context.BIND_IMPORTANT); } } class MyBinder extends CastielProgressConnection.Stub { @Override public String getProName() throws RemoteException { return "Local猴子搬来的救兵 http://blog.csdn.net/mynameishuangshuai"; } } @Override public IBinder onBind(Intent arg0) { return myBinder; } }
RemoteCastielService.javathis
/** * * @ClassName: RemoteCastielService * @Description: 远程服务 * @author 猴子搬来的救兵 http://blog.csdn.net/mynameishuangshuai */ public class RemoteCastielService extends Service { MyBinder myBinder; private PendingIntent pintent; MyServiceConnection myServiceConnection; @Override public void onCreate() { super.onCreate(); if (myBinder == null) { myBinder = new MyBinder(); } myServiceConnection = new MyServiceConnection(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { this.bindService(new Intent(this,LocalCastielService.class), myServiceConnection, Context.BIND_IMPORTANT); Notification notification = new Notification(R.drawable.ic_launcher, "猴子服务启动中", System.currentTimeMillis()); pintent=PendingIntent.getService(this, 0, intent, 0); notification.setLatestEventInfo(this, "猴子服务", "防止被杀掉!", pintent); //设置service为前台进程,避免手机休眠时系统自动杀掉该服务 startForeground(startId, notification); return START_STICKY; } class MyServiceConnection implements ServiceConnection { @Override public void onServiceConnected(ComponentName arg0, IBinder arg1) { Log.i("castiel", "本地服务链接成功"); } @Override public void onServiceDisconnected(ComponentName arg0) { // 链接出现了异常断开了,LocalCastielService被杀死了 Toast.makeText(RemoteCastielService.this, "本地服务Local被干掉", Toast.LENGTH_LONG).show(); // 启动LocalCastielService RemoteCastielService.this.startService(new Intent(RemoteCastielService.this,LocalCastielService.class)); RemoteCastielService.this.bindService(new Intent(RemoteCastielService.this,LocalCastielService.class), myServiceConnection, Context.BIND_IMPORTANT); } } class MyBinder extends CastielProgressConnection.Stub { @Override public String getProName() throws RemoteException { return "Remote猴子搬来的救兵 http://blog.csdn.net/mynameishuangshuai"; } } @Override public IBinder onBind(Intent arg0) { return myBinder; } }
aidl文件spa
package com.castiel.aidl; interface CastielProgressConnection{ String getProName(); }
启动服务.net
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 启动本地服务和远程服务 startService(new Intent(this, LocalCastielService.class)); startService(new Intent(this, RemoteCastielService.class)); }
经过以上代码能够看出,双进程守护实现代码很是简单,两个服务相互链接,Local服务链接着Remote服务,Remote服务又链接着Local服务,你中有我我中有你,一旦两个服务发现对方被杀掉,另外一服务马上会启动并链接它,下面我给你们演示一下。日志
查看一下系统打印日志:code