Android應用進程防殺指南2-雙進程守護

    在上一篇博客中,咱們談到了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

這裏寫圖片描述

相關文章
相關標籤/搜索