1. 程式人生 > >Android Service保活(執行緒保活)

Android Service保活(執行緒保活)

    Android 系統對於記憶體管理,為了使系統有序穩定的執行,系統內部會自動分配,控制程式的記憶體使用。當系統覺得記憶體的資源非常有限的時候,為了保證一些優先順序高的程式能執行,就會殺掉一些他認為不重要的程式或者服務來釋放記憶體, 比如專案需求需要Service在後臺實時監聽網路連線狀態,或者其他用Service執行的後臺操作,為了保證Service一直執行不被系統釋放掉,就需要用到Service保活技術。

    好多部落格上寫的單一的保活手段可能在實際程式碼的檢測上發現並不好用,下面我記錄的Service保活,使用了3重的保險,Service保活的3重實現。 在我所經歷的實際的專案中,MessageService這個服務在後臺監聽網路,wifi,螢幕亮度等等的狀態,為了保證這個Service不被殺死能一直監聽,用到了Service的保活,保證Service即使被殺死也能立刻再重新呼叫起來
        
        第一重:

      startForeground前臺服務的方式啟動Service,並在onStartCommand回撥中設定START_STICKY,這樣當服務被kill那麼START_STICKY會重新啟動該Service ,這是一重處理,為了保證它不被殺掉,只做一重是不夠的,所以還要寫其他幾重的保活        
        
        第二重:

     在MessageService裡開一個Service當做MessageService的守護服務。當這兩個服務任意一個銷燬的時候,都會發送相同的廣播,由專案中的ServiceReceiver這個廣播接收器來監聽,如果收到了任意一個Service銷燬時候發出的廣播,就開啟這兩個Service ,啟動的id保持一致,這樣當使用的ID一致時,僅僅只會更新當前service的Notification。這個處理跟兩個Service的互拉有一些區別,   
    
        第三重:

     將守護的service在adminfest中新增android:process=":guard"

 

public class MessageService extends Service {

    public final static ConnectReceiver conncetReceiver = new ConnectReceiver();

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        Log.d(TAG, "onCreate");
        super.onCreate();
        startGuardService();
        DeviceEngine.getInst().init( this.getApplicationContext() );


        IntentFilter filter = new IntentFilter();
        filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
        filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
        filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
        filter.addAction(Intent.ACTION_SCREEN_ON);
        filter.addAction(Intent.ACTION_SCREEN_OFF);
        filter.addAction(Intent.ACTION_USER_PRESENT);
        filter.addAction("android.intent.action.USER_PRESENT");
        registerReceiver( conncetReceiver , filter);

        Notification notification = new Notification();
        notification.flags = Notification.FLAG_ONGOING_EVENT;
        notification.flags |= Notification.FLAG_NO_CLEAR;
        notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
        this.startForeground(1, notification);

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "ServiceDemo onStartCommand");
        flags = START_STICKY;
        return super.onStartCommand(intent, flags, startId);

    }

    @Override
    public void onDestroy() {
        Log.d(TAG, "onDestroy");
        super.onDestroy();
        Intent intent = new Intent( ACTION );
        sendBroadcast(intent);
        unregisterReceiver( conncetReceiver );
        Log.d(TAG, "sendBroadcast[" + ACTION + "]");
    }


    public void startGuardService()
    {
        Intent intent = new Intent();
        intent.setClass(this, GuardService.class);
        startService(intent);
    }



    private final static String TAG = "MessageService";
    public final static String ACTION = "com.luobeitech.automgr.guard.CONNECT_SERVICE";
}
public class GuardService extends Service {

    public GuardService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        Log.d(TAG, "onCreate");
        super.onCreate();

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "onStartCommand");
        flags = START_STICKY;
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        Log.d(TAG, "onDestroy");
        super.onDestroy();
        Intent intent = new Intent( ACTION );
        sendBroadcast(intent);
        Log.d(TAG, "sendBroadcast[" + ACTION + "]");
    }

    public final static String ACTION = "com.luobeitech.automgr.guard.CONNECT_SERVICE";
    private final static String TAG = "GuardService";

}

 receiver 的註冊以及原始碼:

      <receiver
            android:name=".service.ServiceReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.luobeitech.automgr.guard.CONNECT_SERVICE"/>
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.USER_PRESENT"/>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.PACKAGE_ADDED"/>
                <action android:name="android.intent.action.PACKAGE_REMOVED"/>

                <data android:scheme="package"/>
            </intent-filter>
        </receiver>
public class ServiceReceiver extends BroadcastReceiver {

    private final static String TAG = "ServiceReceiver";

    public ServiceReceiver() {
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d(TAG, "onReceive");
        Intent mIntent = new Intent();
        mIntent.setClass( context , MessageService.class );
        context.startService( mIntent );
        Log.d(TAG, "start MessageService");

        Intent intent1 = new Intent();
        intent1.setClass( context , GuardService.class);
        context.startService( intent1 );
        Log.d(TAG, "start GuardService");
    }
}
  <!-- Message Service -->
        <service android:name=".service.MessageService"/>
        <service
            android:name=".service.GuardService"
            android:enabled="true"
            android:exported="true"
            android:process=":guard"/>

然後再開啟Service的活動呼叫MessageService即可

                    Intent mIntent = new Intent();
                    mIntent.setClass(context, MessageService.class);
                    context.startService(mIntent);