现在的位置: 首页 > 综合 > 正文

如何让你的进程更加“强硬”

2016年12月26日 ⁄ 综合 ⁄ 共 1733字 ⁄ 字号 评论关闭

用任何一款具备任务管理器功能的应用,尝试去关闭360安全卫士时,会发现360进程是无法被关闭的。

     首先,明确一个前提——360没有roo权限的。那它是如何做到的呢?
     先说一下Android上的进程的优先级。在Android上,系统为了管理内存释放有限的空间,会根据优先级杀掉一些进程,进程优先级越低的优先被清除。
      从高到低依次是:
            foreground process
            visible process
            service process
            background process
            empty process。
      Service它还是在主线程跑,要做耗时的工作还得在Service里面另起一个线程,倒不如直接就这样做而不用 Service? 原来用了Service来处理是为了保证这个工作有较高的优先级,从上面可看到它排在第3,如果不通过Service直接启动线程则当 Activity退出或暂停的时候,该线程很容易被杀掉,用Service可以有效地保护起来。
这就解释一个现象:在Activity里起一个Thread,并处于wait状态时,会很容易被kill掉的原因。

     再到说题目,为什么360的进程无法被删除? 实验证明,只要进程被修改foreground级别,就不会被任务管理器关闭,但在使用之前,有一点小窍门。
     在1.5固件之前,Service提供了一个setForeground(boolean enable),可以把当前进程的优化级提升到foreground的级别。1.5固件之后,google把setForeground(boolean enable)废弃了,改为startForeground(int id, Notification
notification),意味着需要开发者强制弹提示以告之用户。 因此,如果要同时兼容两个版本,就需要用反射机制来实现的,这不再详说。 这里会产生一个矛盾:如果需要一个foreground的进程,但又不希望出现notification提示,怎么办? 这个矛盾在1.5之前是不存在的,1.5之后就需要用点“怪招”了。 

   经验证,一个notification的icon,只要不设置任何值(其它值可以任意设置),那通过NotificationManager.notify是不会显示出来的。这样的话,通过如下方式启动Service,就可以得到foreground而不需求显示notification了,代码如下:

public final class MyService extends Service {
      @Override
      public IBinder onBind(Intent arg0) {
            return null;
      }

      @Override
      public void onCreate() {
            super.onCreate();
            
            
      }
      @Override
      public void onStart(Intent intent, int startId) {
            super.onStart(intent, startId);
            startForeground();
      }
      
      private void startForeground(){
            Notification notification = new Notification();
            notification.tickerText = "哈哈";
            notification.setLatestEventInfo(this, "HI", "HI", PendingIntent.getActivity(this, 0, new Intent(), 0));
            startForeground(665248, notification);
      }
      
}

抱歉!评论已关闭.