1,实现原理:启动2个Service,相互绑定监听,当A Service监听到连接断开的时候,说明B服务可能被 Kill掉了,这时需要重新开启A服务,同样B服务的监听断掉了,重新启动A服务。A,B两个服务都是单独的进程,需要使用AIDL来通讯。
2,A服务源码:
public class StepService extends Service {
String TAG="StepService";
private int NOTICE_ID=1000;
@Override
public void onCreate() {
super.onCreate();
LogUtil.d(TAG,"StepService 被创建:"+new Date().toLocaleString());
startGuardService();
}
void startGuardService(){
new Thread(new Runnable() {
@Override
public void run() {
Intent service=new Intent("com.foxconn.androidlib.service.GuardService");
String packageName = "com.foxconn.androidlib";//需要开启服务的app包名
String serviceClassName = packageName + "com.foxconn.androidlib.service.GuardService";//服务的类名全限定名
service.setComponent(new ComponentName(packageName, "com.foxconn.androidlib.service.GuardService"));
startService(service);
bindService(service,mServiceConnection, Context.BIND_AUTO_CREATE);
}
}).start();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return new ProcessConnection.Stub() {
};
}
private Notification getNotification(){
String channelId = "notification_simple";
Notification notification;
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O) {
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
NotificationChannel channel = new NotificationChannel(channelId, "simple", NotificationManager.IMPORTANCE_DEFAULT);
manager.createNotificationChannel(channel);
notification = new NotificationCompat.Builder(this, channelId)
.setContentTitle("保持前台运行")
// .setContentText("This is content text")
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
.build();
// manager.notify(1, notification);
}else{
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notification = new NotificationCompat.Builder(this, channelId)
.setContentTitle("保持前台运行")
// .setContentText("This is content text")
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
.build();
// manager.notify(1, notification);
}
return notification;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// startForeground(1, new Notification());
//绑定建立链接
return super.onStartCommand(intent,flags,startId);
}
private ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
//链接上
Log.d(TAG, "StepService:建立链接");
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
LogUtil.d(TAG,"StepService 断开连接:"+new Date().toLocaleString());
//断开链接
// startService(new Intent(StepService.this, GuardService.class));
startGuardService();
}
};
@Override
public void onDestroy() {
// releaseLock();
LogUtil.d(TAG,"StepService 销毁:"+new Date().toLocaleString());
unbindService(mServiceConnection);
super.onDestroy();
}
private PowerManager.WakeLock mWakeLock;
/**
* 同步方法 得到休眠锁
*
* @param context
* @return
*/
synchronized private void getLock(Context context) {
if (mWakeLock == null) {
PowerManager mgr = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
mWakeLock = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, StepService.class.getName());
mWakeLock.setReferenceCounted(true);
Calendar c = Calendar.getInstance();
c.setTimeInMillis((System.currentTimeMillis()));
int hour = c.get(Calendar.HOUR_OF_DAY);
if (hour >= 23 || hour <= 6) {
mWakeLock.acquire(5000);
} else {
mWakeLock.acquire(300000);
}
}
Log.v(TAG, "get lock");
}
synchronized private void releaseLock()
{
if(mWakeLock!=null){
if(mWakeLock.isHeld()) {
mWakeLock.release();
Log.v(TAG,"release lock");
}
mWakeLock=null;
}
}
}
3,B服务的源源码如下:
public class GuardService extends Service {
String TAG="GuardService";
@Nullable
@Override
public IBinder onBind(Intent intent) {
return new ProcessConnection.Stub() {
};
}
@Override
public void onCreate() {
super.onCreate();
LogUtil.d(TAG,"GuardService 创建:"+new Date().toLocaleString());
startStepService();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// startForeground(1, new Notification());
//绑定建立链接
return super.onStartCommand(intent,flags,startId);
}
void startStepService(){
new Thread(new Runnable() {
@Override
public void run() {
Intent service=new Intent("com.foxconn.androidlib.service.StepService");
String packageName = "com.foxconn.androidlib";//需要开启服务的app包名
String serviceClassName = packageName + ".StepService";//服务的类名全限定名
service.setComponent(new ComponentName(packageName, "com.foxconn.androidlib.service.StepService"));
startService(service);
bindService(service,mServiceConnection, Context.BIND_AUTO_CREATE);
}
}).start();
}
private ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
//链接上
Log.d("test", "GuardService:建立链接");
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
LogUtil.d(TAG,"GuardService 断开链接:"+new Date().toLocaleString());
//断开链接
startStepService();
}
};
@Override
public void onDestroy() {
super.onDestroy();
LogUtil.d(TAG,"GuardService 销毁:"+new Date().toLocaleString());
unbindService(mServiceConnection);
}
}
4,AIDL文件如下:
interface ProcessConnection {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
}
5,AndroidManifest.xml 代码如下:
6,启动Service:
Intent service = new Intent("com.foxconn.androidlib.service.StepService");
String packageName = "com.foxconn.androidlib";//需要开启服务的app包名
String serviceClassName = packageName + ".StepService";//服务的类名全限定名
service.setComponent(new ComponentName(packageName, "com.foxconn.androidlib.service.StepService"));
startService(service);
Intent service2 = new Intent("com.foxconn.androidlib.service.GuardService");
service2.setComponent(new ComponentName(packageName, "com.foxconn.androidlib.service.GuardService"));
startService(service2);