Android 2个Service实现相互保活,通过bindservice来实现,不通过广播实现

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 代码如下:


        <service
            android:name="com.foxconn.androidlib.service.StepService"
            android:exported="true"
            android:process=":istep.service">
            <intent-filter>
                <action android:name="com.foxconn.androidlib.service.StepService"/>
            </intent-filter>
        </service>

        <service
            android:name="com.foxconn.androidlib.service.GuardService"
            android:exported="true"
            android:process=":GuardService">
            <intent-filter>
                <action android:name="com.foxconn.androidlib.service.GuardService"/>
            </intent-filter>
        </service>

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);

猜你喜欢

转载自blog.csdn.net/fhl13017599952/article/details/84982707