天天看點

保證service存活

從android官方文檔中,我們知道onstartcommand有4種int傳回值,首先簡單地講講int傳回值的作用。

一、onstartcommand有4種傳回值:

start_sticky:如果service程序被kill掉,保留service的狀态為開始狀态,但不保留遞送的intent對象。随後系統會嘗試重新建立service,由于服務狀态為開始狀态,是以建立服務後一定會調用onstartcommand(intent,int,int)方法。如果在此期間沒有任何啟動指令被傳遞到service,那麼參數intent将為null。

start_not_sticky:“非粘性的”。使用這個傳回值時,如果在執行完onstartcommand後,服務被異常kill掉,系統不會自動重新開機該服務。

start_redeliver_intent:重傳intent。使用這個傳回值時,如果在執行完onstartcommand後,服務被異常kill掉,系統會自動重新開機該服務,并将intent的值傳入。

start_sticky_compatibility:start_sticky的相容版本,但不保證服務被kill後一定能重新開機。

二、建立不被殺死的service

1.在service中重寫下面的方法,這個方法有三個傳回值, start_sticky(或start_sticky_compatibility)是service被kill掉後自動重寫建立

@override

public int onstartcommand(intent intent, int flags, int startid)

{

return start_sticky_compatibility;

//return super.onstartcommand(intent, flags, startid);

}

flags = start_sticky;

return super.onstartcommand(intent, flags, startid);

// return start_redeliver_intent;

public void onstart(intent intent, int startid)

// 再次動态注冊廣播

intentfilter localintentfilter = new intentfilter("android.intent.action.user_present");

localintentfilter.setpriority(integer.max_value);// 整形最大值

myreceiver searchreceiver = new myreceiver();

registerreceiver(searchreceiver, localintentfilter);

super.onstart(intent, startid);

2.在service的ondestroy()中重新開機service.

public void ondestroy()

intent localintent = new intent();

localintent.setclass(this, myservice.class); // 銷毀時重新啟動service

this.startservice(localintent);

3.建立一個廣播

public class myreceiver extends broadcastreceiver

public void onreceive(context context, intent intent)

context.startservice(new intent(context, google.class));

4.androidmanifest.xml中注冊廣播myreceiver及myservice服務

<receiver android:name=".myreceiver" >

           <intent-filter android:priority="2147483647" ><!--優先級加最高-->

               <!-- 系統啟動完成後會調用 -->

               <action android:name="android.intent.action.boot_completed" />              

               <!-- 解鎖完成後會調用 -->

               <action android:name="android.intent.action.user_present" />

               <!-- 監聽情景切換 -->

               <action android:name="android.media.ringer_mode_changed" />              

           </intent-filter>

</receiver>

<service android:name=".myservice" >

注:解鎖,啟動,切換場景激活廣播需權重限,如啟動完成,及手機機狀态等。

<uses-permission android:name="android.permission.receive_boot_completed" />

<uses-permission android:name="android.permission.read_phone_state" />

親測zte u795手機android 4.0.4版本adb push到systemapp下android:persistent="true"

變成核心程式,在360殺掉程序的時候,myreceiver照樣有效,保證service重生。呃

kill問題:

1. settings 中stop service

ondestroy方法中,調用startservice進行service的重新開機。

2.settings中force stop 應用

捕捉系統進行廣播(action為android.intent.action.package_restarted)

3. 借助第三方應用kill掉running task

提升service的優先級,程式簽名,或adb push到systemapp下等

相較于/data/app下的應用,放在/system/app下的應用享受更多的特權,比如若在其manifest.xml檔案中設定persistent屬性為true,則可使其免受out-of-memory killer的影響。如應用程式'phone'的androidmanifest.xml檔案:

   <application android:name="phoneapp"

                android:persistent="true"

                android:label="@string/dialericonlabel"

                android:icon="@drawable/ic_launcher_phone">

        ...

   </application>

設定後app提升為系統核心級别

繼續閱讀