Android進程保活之綁定系統服務

有些業務需要service在後臺持續的運行,所以就要有後臺保活機制,包括lowMemory防殺和自啓。

  防殺機制

  基本就是提高進程優先級,保證在低內存時進程不被有限殺死,常用的方法就是利用系統bug提高進程優先級,灰色保活手段。

  後臺自啓

  大概包括

  Receiver拉起

  AlarmManager拉起

  雙進程互相守護

  利用推送SDK拉起進程

  以上說的這幾種是常用的方法,對於原生和沒有深度定製的ROM有一定作用,但是對於像小米、魅族等這類深度定製的系統來說效果不是很好。

  綁定系統服務

  系統提供一些系統級的Service,比如AccessibilityService輔助服務、NotificationListenerService用於監聽通知消息。這篇文章主要講下怎樣利用NotificationListenerService用於監聽通知消息實現進程保活。

  首先,如果想使用系統service,必須要用戶手動點開權限。我們可以添加一個設置的入口直接跳到系統設置通知權限的界面,顯示提示用戶需要開啓權限。

  public static void goNLPermission(Context context) {

  try {

  Intent intent = new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");

  context.startActivity(intent);

  } catch (Exception e) {

  e.printStackTrace();

  }

  }

  界面就不截圖了,然後我們app中要有一個權限的狀態檢查用於提示用戶是否開啓了通知顯示權。

  /**

  * 檢查通知使用權

  */

  public static boolean checkNotificationPermission(Context context) {

  String pkg = context.getPackageName();

  String flat = Settings.Secure.getString(context.getContentResolver(), "enabled_notification_listeners");

  boolean enabled = flat != null && flat.contains(pkg);

  return enabled;

  }

  註冊,聲明運行在com.package.pedometer進程中

  <service< p="">

  android:name=".service.MyListenerService"

  android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"

  android:process=":pedometer">

  然後需要繼承NotificationListenerService實現兩個方法

  /**

  * 監聽系統通知,需要用戶手動開啓權限,那麼該進程可以不死

  */

  @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)

  public class MyListenerService extends NotificationListenerService {

  @Override

  public void onNotificationPosted(StatusBarNotification sbn) {

  }

  @Override

  public void onNotificationRemoved(StatusBarNotification sbn) {

  }

  }

  方法中什麼都不用實現,MyListenerService所在的進程就擁有了跟NotificationListenerService一樣的權限。可以試下手動強制停止進程會發現怎麼都結束不掉,強制停止的按鈕一直可以點擊。可以使用

  adb shell ps | grep ***

  命令查看進程是否存活。

  cat /proc/12869/oom_adj

  0

  查看進程的oom_adj的值爲0,那麼我們知道在灰色保活手段上基本就是提高oom_adj的值,越小越不容易被殺死,這種方法一步到位。

  那麼怎麼應用到我們自己的service中呢?很簡單,將service跟MyListenerService運行在同一個進程就可以了。

  <service< p="">

  android:name=".service.StepCounterService"

  android:exported="true"

  android:process=":pedometer">

  這樣基本就可以保證service所在的進程不被殺死了。當然,如果ROM廠商在系統級別攔截掉了,這種方法也會無效了。


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