双进程守护(暴力拉活)

结合之前讲到的拉活方式,其实没有一个能确保每次都能拉活成功,所以我们只能从提高拉活的概率出发,接下来讲到的双进程守护其实就是结合service提权和jobscheduler来进行的一种拉活
实现原理:


image.png

在主进程中创建一个前台服务,在子进程中也创建一个前台服务,然后对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中进行注册


你可能感兴趣的:(双进程守护(暴力拉活))