结合之前讲到的拉活方式,其实没有一个能确保每次都能拉活成功,所以我们只能从提高拉活的概率出发,接下来讲到的双进程守护其实就是结合service提权和jobscheduler来进行的一种拉活
实现原理:
在主进程中创建一个前台服务,在子进程中也创建一个前台服务,然后对LocalService和RemoteService进行相互绑定,通过ServiceConnection的回调得到service之间的连接状态,
如果RemoteService中监听到LocalService断开,则立马再次启动LocalService,并再次绑定。同理,如果在LocalService中监听到RemoteService断开,则立马再次启动RemoteService,并再次绑定。
代码实现
interface IMyAidlInterface {
/**
* 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);
}
public class RemoteService extends Service {
private static final String TAG = "Service";
class MyBinder extends IMyAidlInterface.Stub {
@Override
public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double
aDouble, String aString) throws RemoteException {
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return myBinder;
}
MyBinder myBinder;
ServiceConnection serviceConnection;
@Override
public void onCreate() {
super.onCreate();
myBinder = new MyBinder();
serviceConnection = new ServiceConnection();
//使Service变成前台服务
startForeground(20, new Notification());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
startService(new Intent(this, LocalService.InnnerService.class));
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
bindService(new Intent(this, LocalService.class), serviceConnection,
BIND_AUTO_CREATE);
return super.onStartCommand(intent, flags, startId);
}
class ServiceConnection implements android.content.ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//服务连接后回调
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.e(TAG,"主进程可能被干掉了,拉活");
//连接中断后回调
startService(new Intent(RemoteService.this, LocalService.class));
bindService(new Intent(RemoteService.this, LocalService.class), serviceConnection,
BIND_AUTO_CREATE);
}
}
public static class InnnerService extends Service {
@Override
public void onCreate() {
super.onCreate();
startForeground(20, new Notification());
stopSelf();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
}
public class LocalService extends Service {
private static final String TAG = "Service";
private MyBinder myBinder;
class MyBinder extends IMyAidlInterface.Stub {
@Override
public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double
aDouble, String aString) throws RemoteException {
}
}
ServiceConnection serviceConnection;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return myBinder;
}
@Override
public void onCreate() {
super.onCreate();
myBinder = new MyBinder();
serviceConnection = new ServiceConnection();
//使Service变成前台服务
startForeground(20, new Notification());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
startService(new Intent(this, InnnerService.class));
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
bindService(new Intent(this, RemoteService.class), serviceConnection,
BIND_AUTO_CREATE);
return super.onStartCommand(intent, flags, startId);
}
class ServiceConnection implements android.content.ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//服务连接后回调
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.e(TAG,"子进程可能被干掉了,拉活");
//连接中断后回调
startService(new Intent(LocalService.this, RemoteService.class));
bindService(new Intent(LocalService.this, RemoteService.class),serviceConnection,
BIND_AUTO_CREATE);
}
}
public static class InnnerService extends Service {
@Override
public void onCreate() {
super.onCreate();
startForeground(20, new Notification());
stopSelf();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
}
在AndroidManifest中进行服务注册
在MainActivity中启动这两个服务即可
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startService(new Intent(this, LocalService.class));
startService(new Intent(this, RemoteService.class));
}
}
通过上述方法我们即实现了双进程守护,提高了拉活率,我们上一篇文章讲到了jobScheduler,它是通过系统进行调度,
如果我们这个时候再通过jobScheduler来实时监听LocalService和RemoteService的状态,发现被杀掉了再立即重新启动,是不就能够更加的提高拉活的概率吗。
上代码:
首先,我们要有一个方法能够得到Service当前的状态,根据ClassName知道指定Service是否被杀死
public class Utils {
public static boolean isRunningService(Context context, String name) {
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List runningServices = am.getRunningServices(100);
for (ActivityManager.RunningServiceInfo info : runningServices
) {
if (TextUtils.equals(info.service.getClassName(), name)) {
return true;
}
}
return false;
}
}
其次,我们就是实现JobService的监听啦
public class MyJobService extends JobService {
public static void StartJob(Context context) {
JobScheduler jobScheduler = (JobScheduler) context.getSystemService(Context
.JOB_SCHEDULER_SERVICE);
// setPersisted 在设备重启依然执行
JobInfo.Builder builder = new JobInfo.Builder(10, new ComponentName(context
.getPackageName(), MyJobService.class
.getName())).setPersisted(true);
//小于7.0
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
// 每隔1s 执行一次 job
builder.setPeriodic(1_000);
} else {
//延迟执行任务
//大于7.0的机型发现定时无效果,所需需要进行延时轮询
builder.setMinimumLatency(1_000);
}
jobScheduler.schedule(builder.build());
}
private static final String TAG = "MyJobService";
@Override
public boolean onStartJob(JobParameters params) {
Log.e(TAG, "开启job");
//如果7.0以上 轮训
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
StartJob(this);
}
boolean isLocalRun = Utils.isRunningService(this, LocalService.class.getName());
boolean isRemoteRun = Utils.isRunningService(this, RemoteService.class.getName());
//只有其中任何一个服务被干掉了,则进行start
if (!isLocalRun || !isRemoteRun) {
startService(new Intent(this, LocalService.class));
startService(new Intent(this, RemoteService.class));
}
return false;
}
@Override
public boolean onStopJob(JobParameters params) {
return false;
}
}
在MainActivity中进行调用
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startService(new Intent(this, LocalService.class));
startService(new Intent(this, RemoteService.class));
MyJobService.StartJob(this);
}
}
在AndroidManifest中进行注册