一般为了保证后台进程不被系统干掉,人为的或者是系统因为内存不足的原因,我们希望自己应用的进程一直存在或者不被轻易的杀死,一般的套路会包含以下几点:

(1)提升service进程优先级

在AndroidManifest.xml文件中对于intent-filter可以通过android:priority = “1000”这个属性设置最高优先级,1000是最高值,如果数字越小则优先级越低,同时实用于广播

<service  
    android:name="com.dbjtech.acbxt.waiqin.UploadService"  
    android:enabled="true" >  
    <intent-filter android:priority="1000" >  
        <action android:name="com.test.service" />  
    </intent-filter>  
</service>

这个办法对普通应用而言,只是降低了应用被杀死的概率,但是如果真的被系统回收了,还是无法让应用自动重新启动!

(2)提升service优先级

Android中的进程是托管的,当系统进程空间紧张的时候,会依照优先级自动进行进程的回收。Android将进程分为6个等级,它们按优先级顺序由高到低依次是:

1.前台进程( FOREGROUND_APP)

A. 拥有用户正在交互的 Activity( onResume()状态)

B. 正在与bound绑定服务交互的 Activity

C. 正在“前台”运行的 Service(startForeground()被调用)

D. 生命周期函数正在被执行的 Service(onCreate()、onStart() 或 onDestroy())

E. 正执行 onReceive() 方法的 BroadcastReceiver    

(该进程优先级别最高,杀死前台进程需要用户的响应。)

2.可视进程(VISIBLE_APP )

该进程并不是在最前端,并没有得到焦点,但是我们却能看到它们。
A. 拥有不在前台、但仍对用户可见的 Activity(例如弹出一个对话框的Activity)
B. 绑定到可见进程(或前台进程)中的Activity 的 Service

3.服务进程(Service process)

正在运行的通过 startService() 启动的,且不属于上述两个更高进程状态的Service

4.后台进程(Background process)

不可见状态的Activity进程

5.空进程(Empty process)

没有运行任何应用组件的进程,保留这个进程主要是为了缓存的需要,待下次相关组件运行时直接从内存中获取数据,缩短对数据获取的时间

当service运行在低内存的环境时,将会kill掉一些存在的进程。因此进程的优先级将会很重要,可以使用startForeground API将service放到前台状态。这样在低内存时被kill的几率更低,但是如果在极度极度低内存的压力下,该service还是会被kill掉。
在onStartCommand方法内

public class MyService extends Service {

    public static final String TAG = "MyService";

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

    @Override
    public void onCreate() {
        super.onCreate();
        Log.w(TAG, "in onCreate");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.w(TAG, "in onStartCommand");
        Log.w(TAG, "MyService:" + this);
        String name = intent.getStringExtra("name");
        Log.w(TAG, "name:" + name);


        Notification notification = new Notification(R.drawable.ic_launcher, "test", System.currentTimeMillis());
        Intent notificationIntent = new Intent(this, DActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntesnt, 0);
        notification.setLatestEventInfo(this, "title", "content", pendingIntent);
        startForeground(1, notification);
        return START_REDELIVER_INTENT;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        stopForeground(true);
        Log.w(TAG, "in onDestroy");
    }
}

(3)在Service中的onDestroy方法里发送广播重启service

<receiver android:name="com.test.BootReceiver" >  
    <intent-filter>  
        <action android:name="android.intent.action.BOOT_COMPLETED" />  
        <action android:name="android.intent.action.USER_PRESENT" />  
        <action android:name="com.define.destory>  
</receiver>

(4)设置 android:persistent属性为true

<application 
    android:name="com.test.Application" 
    android:allowBackup="true" 
    android:icon="@drawable/ic_launcher" 
    android:label="@string/app_name" 
  android:persistent="true"
    android:theme="@style/AppTheme" > 
</application>

属性设置后,优先级提高不少,或许是相当于系统级的进程,但是还是无法保证存活

(5)本地service与远端service绑定,双进程监听

假设我们的APP中开启了两个Service,分别是LocalService和RemoteService,那么:
如果LocalService守护RemoteService,则RemoteService挂掉的同时,,反之亦然,也就是说无论谁被杀掉,对方就把它拉起来。

public class LocalService 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("Local", "远程服务连接成功");
        }

        @Override
        public void onServiceDisconnected(ComponentName arg0) {
            // 连接出现了异常断开了,RemoteService被杀掉了
            Toast.makeText(LocalCastielService.this, "远程服务Remote被干掉", Toast.LENGTH_LONG).show();
            // 启动RemoteService
            LocalServiceA.this.startService(new Intent(LocalServiceA.this, RemotelService.class));
            LocalServiceA.this.bindService(new Intent(LocalServiceA.this, RemoteService.class),
                    myServiceConnection, Context.BIND_IMPORTANT);
        }

    }

    class MyBinder extends AIDLInterface.Stub {

        @Override
        public String message() throws RemoteException {
            return "message"
        }

    }

    @Override
    public IBinder onBind(Intent arg0) {
        return myBinder;
    }

}

AIDL自定义文件

package com.test.aidl;
interface AIDLInterface.{
    String message();
}

RemoteService

public class RemoteService 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,LocalService.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("RemoteService", "链接本地服务成功");
        }

        @Override
        public void onServiceDisconnected(ComponentName arg0) {
            // 连接出现了异常断开了,LocalService被杀死了
            Toast.makeText(RemoteService.this, "本地服务被干掉", Toast.LENGTH_LONG).show();
            RemoteService.this.startService(new Intent(RemoteService.this,LocalService.class));
            RemoteService.this.bindService(new Intent(RemoteService.this,LocalService.class), myServiceConnection, Context.BIND_IMPORTANT);
        }

    }

    class MyBinder extends AIDLInterface.Stub {

        @Override
        public String message() throws RemoteException {
            return "双进程守护";
        }

    }

    @Override
    public IBinder onBind(Intent arg0) {
        return myBinder;
    }

}

应用程序启动的时候开启服务

public class MainActivity extends Activity {

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

配置文件

<service
         android:name=".services.LocalService"
         android:process=":local" />
<service
        android:name=".services.RemoteService"
        android:process=":remote" />