Service 保活法之一

2022-03-19 08:11:35 字數 3616 閱讀 5780

我們都知道,在android中,service有兩種啟動方式:

以startservice()啟動服務,系統將通過傳入的intent在底層搜尋相關符合intent裡面資訊的service。

如果服務沒有啟動則先執行oncreate,然後執行onstartcommand (可在裡面處理啟動時傳過來的intent和其他引數),

直到明顯呼叫stopservice或者stopself才將停止service。無論執行startservice多少次,只要呼叫一次stopservice或者stopself,service都會停止。

以bindservice()方法啟用服務,呼叫者與服務繫結在了一起,呼叫者一旦退出,服務也就終止。

onbind()只有採用context.bindservice()方法啟動服務時才會**該方法。

該方法在呼叫者與服務繫結時被呼叫,當呼叫者與服務已經繫結,多次呼叫context.bindservice()方法並不會導致該方法被多次呼叫。

採用context.bindservice()方法啟動服務時只能呼叫onunbind()方法解除呼叫者與服務解除,服務結束時會呼叫ondestroy()方法。

但是,官方文件告訴我們,android系統會盡量保持擁有service的程序執行,只要在該service已經被啟動(start)或者客戶端連線(bindservice)到它。當記憶體不足時,需要保持,擁有service的程序具有較高的優先順序。

那麼,要如何保證service不被殺掉呢?

@override  

public

int onstartcommand(intent intent, int flags, int

startid)

startcommond幾個常量引數簡介:

1、start_sticky

在執行onstartcommand後service程序被kill後,那將保留在開始狀態,但是不保留那些傳入的intent。

不久後service就會再次嘗試重新建立,因為保留在開始狀態,在建立 service後將保證呼叫onstartcommand。如果沒有傳遞任何開始命令給service,那將獲取到null的intent。

2、start_not_sticky

在執行onstartcommand後service程序被kill後,並且沒有新的intent傳遞給它。service將移出開始狀態,並且直到新的明顯的方法(startservice)呼叫才重新建立。

因為如果沒有傳遞任何未決定的intent那麼service是不會啟動,也就是期間onstartcommand不會接收到任何null的intent。

3、start_redeliver_intent

在執行onstartcommand後service程序被kill後,系統將會再次啟動service,並傳入最後乙個intent給onstartcommand。直到呼叫stopself(int)才停止傳遞intent。

如果在被kill後還有未處理好的intent,那被kill後服務還是會自動啟動。因此onstartcommand不會接收到任何null的intent。

【結論】手動返回start_sticky,親測當service因記憶體不足被kill,當記憶體又有的時候,service又被重新建立,比較不錯,但是不能保證任何情況下都被重建,比如程序被乾掉了....

3.次要服務程序(secondary_server )

5.內容**節點(content_provider)

當service執行在低記憶體的環境時,將會kill掉一些存在的程序。因此程序的優先順序將會很重要,可以使用startforeground 將service放到前台狀態。這樣在低記憶體時被kill的機率會低一些。

在onstartcommand方法內新增如下**:

notification notification = new

notification(r.drawable.ic_launcher,

pendingintent pendingintent = pendingintent.getactivity(this, 0,

notification.setlatesteventinfo(

this, "uploadservice", "請保持程式在後台執行",

pendingintent);

startforeground(0x111, notification);

【結論】如果在極度極度低記憶體的壓力下,該service還是會被kill掉,並且不一定會restart

<

receiver

android:name

="com.dbjtech.acbxt.waiqin.bootreceiver"

>

<

intent-filter

>

<

action

android:name

="android.intent.action.boot_completed"

/>

<

action

android:name

="android.intent.action.user_present"

/>

<

action

android:name

="com.dbjtech.waiqin.destroy"

/>

//這個就是自定義的action

intent-filter

>

receiver

>

在ondestroy時:

@override  

public

void

ondestroy()

在bootreceiver裡:

public

class bootreceiver extends

broadcastreceiver

} }

也可以直接在ondestroy()裡startservice

@override  

public

void

ondestroy()

看android的文件知道,當程序長期不活動,或系統需要資源時,會自動清理門戶,殺死一些service,和不可見的activity等所在的程序。但是如果某個程序不想被殺死(如資料快取程序,或狀態監控程序,或遠端服務程序),可以這麼做:

<

android:name

android:allowbackup

="true"

android:icon

="@drawable/ic_launcher"

android:label

android:persistent

="true"

android:theme

>

>

【結論】據說這個屬性不能亂設定,不過設定後,的確發現優先順序提高不少,或許是相當於系統級的程序,但是還是無法保證存活

**

換一種活法

我的心是曠野的鳥,它本可以飛往任何地方,卻是有一種力量,在不斷的給翅膀增加阻力,最後你連飛的心情也沒有了,牢牢的被釘死在原地,任何多餘的妄想都像是給自己增加煩惱,追求自由和愛情,追求詩和遠方都成了負擔。而原本這些是人生裡最美的風景。只能無能為力又不甘平凡。歲月蹉跎過去,而那些你曾經多麼多麼想的事情,...

Service學習之一 服務生命週期

1 要使用服務,第一件事是自己建立乙個類繼承seivice package com.example.studyservice import android.content.intent import android.os.ibinder import android.util.log public ...

Service詳解 學習(一)

因為最近想用到service,所以今天系統的學習了一下service的用法。service給我的感覺就和activity很相似,都是代表可執行的程式,只不過service是在後台執行的,沒有什麼實在的介面。service一旦啟動,和activity一樣,具有生命週期。使用activity或者serv...