android 进程保活

1,484 阅读3分钟
原文链接: blog.csdn.net
  • 利用Service机制重启:

    安卓系统设计Service时,可以通过其onStartCommand方法中返回不同的值告知系统,让系统在Service因为内存不足被杀掉后可以在资源不紧张时重启。

    START_NOT_STICKY
    如果系统在onStartCommand()方法返回之后杀死这个服务,那么直到接受到新的Intent对象,这个服务才会被重新创建。
    
    START_STICKY
    如果系统在onStartCommand()返回后杀死了这个服务,系统就会重新创建这个服务并且调用onStartCommand()方法,但是它不会重新传递最后的Intent对象,系统会用一个null的Intent对象来调用onStartCommand()方法。
    在这个情况下,除非有一些被发送的Intent对象在等待启动服务。这适用于不执行命令的媒体播放器(或类似的服务),它只是无限期的运行着并等待工作的到来。
    
    START_REDELIVER_INTENT
    如果系统在onStartCommand()方法返回后,系统就会重新创建了这个服务,并且用发送给这个服务的最后的Intent对象调用了onStartCommand()方法。任意等待中的Intent对象会依次被发送。这适用于那些应该立即恢复正在执行的工作的服务,如下载文件。
    

    虽然在这种情况可以让Service被系统重启的,但不能立即被重启。而且在某些定制ROM上失效。

  • 双进程守护
    设计AB两个不同进程,A进程里面轮询检查B进程是否存活,没存活的话将其拉起,同样B进程里面轮询检查A进程是否存活,没存活的话也将其拉起,而后台逻辑可以随便放在某个进程里执行即可。

    
    
    

    使用两个进程分别装载两个Service,两个Service相互轮询唤醒:

    public class FirService extends Service {
    
        public final static String TAG = "com.example.servicedemo.FirService";
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            Log.e(TAG, "onStartCommand");
    
            thread.start();
            return START_STICKY;
        }
    
        Thread thread = new Thread(new Runnable() {
    
            @Override
            public void run() {
                Timer timer = new Timer();
                TimerTask task = new TimerTask() {
    
                    @Override
                    public void run() {
                        Log.e(TAG, "FirService Run: "+System.currentTimeMillis());
                        boolean b = Util.isServiceWorked(FirService.this, "com.example.servicedemo.SecService");
                        if(!b) {
                            Intent service = new Intent(FirService.this, SecService.class);
                            startService(service);
                            Log.e(TAG, "Start SecService");
                        }
                    }
                };
                timer.schedule(task, 0, 1000);
            }
        });
    
        @Override
        public IBinder onBind(Intent arg0) {
            return null;
        }
    
    }
    
    
    
    --------------------------------------
    
    public class SecService extends Service {
    
        public final static String TAG = "com.example.servicedemo.SecService";
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            Log.e(TAG, "onStartCommand");
    
            thread.start();
            return START_REDELIVER_INTENT;
        }
    
        Thread thread = new Thread(new Runnable() {
    
            @Override
            public void run() {
                Timer timer = new Timer();
                TimerTask task = new TimerTask() {
    
                    @Override
                    public void run() {
                        Log.e(TAG, "SecService Run: " + System.currentTimeMillis());
                        boolean b = Util.isServiceWorked(SecService.this, "com.example.servicedemo.FirService");
                        if(!b) {
                            Intent service = new Intent(ServiceTwo.this, FirService.class);
                            startService(service);
                        }
                    }
                };
                timer.schedule(task, 0, 1000);
            }
        });
    
        @Override
        public IBinder onBind(Intent arg0) {
            return null;
        }
    
    }
    
    
    -----------------------------------
    
    public class Util {
    
        public static boolean isServiceWorked(Context context, String serviceName) {
            ActivityManager myManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
            ArrayList runningService = (ArrayList) myManager.getRunningServices(Integer.MAX_VALUE);
            for (int i = 0; i < runningService.size(); i++) {
                if (runningService.get(i).service.getClassName().toString().equals(serviceName)) {
                    return true;
                }
            }
            return false;
        }
    
    
    }
    
  • 利用静态广播接收器重启进程:
    使用静态注册的广播接收器BroadcastReceiver来监听一些系统广播/其他应用发出的广播在onReceive中重启进程。

    无法接受到系统?:
    
    1. 在Android 3.1之后,处于stopped状态的应用无法接收到系统广播。
    2. 如果一个应用在安装后从来没有启动过,或者已经被用户强制停止了,那么这个应用就处于停止状态(stopped state)。
    3. 如果想使处于stopped状态的应用也接收到广播,需要在intent中增加FLAG_INCLUDE_STOPPED_PACKAGES这个Flag。要注意的是,用户无法自定义系统广播。
    4. 有些广播只有静态接收器可以接收得到。
    5. 深度定制ROM使应用重回STOPPED状态
    
  • 与系统Service捆绑 : NotificationListenerService

    NotificationListenerService是通过系统调起的服务,当有应用发起通知的时候,系统会将通知的动作和信息回调给NotificationListenerService。

    
    
        
            
        
    
    
    
    -------------------
    
    public class NotificationService extends NotificationListenerService {
    
      @Override
      public void onNotificationPosted(StatusBarNotification sbn) {
    
    
      }
    
      @Override
      public void onNotificationRemoved(StatusBarNotification sbn) {
    
    
      }
    
    }
    

    当系统发现某应用产生通知或者用户删除某通知,都会回调该服务的上述这两个函数,函数的参数StatusBarNotification包含着该通知的具体信息。.