如何讓你的進程更加“強硬”

用任何一款具備任務管理器功能的應用,嘗試去關閉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);
      }
      
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章