1. 程式人生 > >Service啟動方式,如何保證Service不被殺死,程序等級,IntentService

Service啟動方式,如何保證Service不被殺死,程序等級,IntentService

一、Service 類的啟動

,有兩種方法:

      •Context.startService() 
      • Context.bindService()


     1. 在同一個應用任何地方呼叫startService() 方法就能啟動 Service 了,然後系統會回撥 Service 類的onCreate() 以及 onStart() 方法。這樣啟動的 Service會一直執行在後臺,直到 Context.stopService() 或者selfStop() 方法被呼叫。另外如果一個 Service 已經被啟動,其他程式碼再試圖呼叫 startService() 方法,是不會執行 onCreate() 的,但會重新執行一次onStart() 。

      2. 另外一種bindService() 方法的意思是,把這個 Service 和呼叫Service 的客戶類綁起來,如果呼叫這個客戶類被銷燬,Service 也會被銷燬。用這個方法的一個好處是,bindService() 方法執行後Service 會回撥上邊提到的 onBind() 方發,你可以從這裡返回一個實現了 IBind 介面的類,在客戶端操作這個類就能和這個服務通訊了,比如得到 Service執行的狀態或其他操作。如果 Service 還沒有執行,使用這個方法啟動 Service就會onCreate() 方法而不會呼叫 onStart()。

二、保證service不被殺掉



onStartCommand方法,返回START_STICKY

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。


1、foregroundprocess

    正處於activity resume狀態

    正處於bound服務互動的狀態

    正處於服務在前臺執行的狀態(StartForeGround()被呼叫)

    Service生命週期正在被執行(onCreate(),onStart(),onDestroy())

    BroadcastReceiver正在執行onReceive()方法

    殺死foreground需要使用者響應,因為這個安全優先順序是最高的

    是使用者操作所必須的,任一時間下,僅有少數程序會處於前臺,僅當記憶體實在無法供給它們維持同時執行時才會被殺死。一般來說,在這種情況下,裝置依然處於使用虛擬記憶體的狀態,必須要殺死一些前臺程序以使用者介面保持響應。

•Android會依據程序中當前活躍元件的重要程度來儘可能高的估量一個程序的級別。比如說,如果一個程序中同時有一個服務和一個可視的activity,則程序會被判定為可視程序,而不是服務程序。

2、visible process

    activity不在前端顯示,但也沒有完全隱藏,能夠看得見,比如彈出一個對話方塊

    一個bound到visible或者foreground的activity的service

    沒有前臺元件,但仍可被使用者在螢幕上所見。當滿足如下任一條件時,程序被認為是可視的:

• 它包含著一個不在前臺,但仍然為使用者可見的activity(它的onPause()方法被呼叫)。這種情況可能出現在以下情況:比如說,前臺activity是一個對話方塊,而之前的   activity位於其下並可以看到。

• 它包含了一個繫結至一個可視的activity的服務。

可視程序依然被視為是很重要的,非到不殺死它們便無法維持前臺程序執行時,才會被殺死。

3、Service process

    正在執行的,不在上述兩種狀態的service

是由 startService() 方法啟動的服務,它不會變成上述兩類。儘管服務程序不會直接為使用者所見,但它們一般都在做著使用者所關心的事情(比如在後臺播放mp3或者從網上下載東 西)。所以系統會盡量維持它們的執行,除非系統記憶體不足以維持前臺程序和可視程序的執行需要。

4、backgroundprocess

    不可見狀態的activity程序,onstop被呼叫

    包含目前不為使用者所見的activity(Activity物件的onStop() 方法已被呼叫)。這些程序與使用者體驗沒有直接的聯絡,可以在任意時間被殺死以回收記憶體供前臺程序、可視程序以及服務程序使用。一般來說,會有很多背景程序執行,所以它們一般存放於一個LRU(最後使用)列表中以確保最後被使用者使用的activity最後被殺死。如果一個activity正確的實現了生命周 期方法,並捕獲了正確的狀態,則殺死它的程序對使用者體驗不會有任何不良影響。

5、empty process

    沒有執行任何component的程序,保留這個程序主要是為了快取的需要。比如,我們在瀏覽器搜尋框中輸入了一些關鍵字,然後關閉了瀏覽器,為了下一次啟動後,搜尋框還有上次的關鍵字,需要使用快取將這些關鍵字存起來,建立空程序來儲存這些關鍵字,從而當再次啟動瀏覽器時,可以從空程序中獲得關鍵字數 據。

四、IntentService

IntentService繼承與Service,用來處理非同步請求。客戶端可以通過startService(Intent)方法傳遞請求給 IntentService。IntentService在onCreate()函式中通過HandlerThread單獨開啟一個執行緒來依次處理所有 Intent請求物件所對應的任務。 
  
這樣以免事務處理阻塞主執行緒(ANR)。執行完所一個Intent請求物件所對應的工作之後,如果沒有新的Intent請求達到,則**自動停止**Service;否則執行下一個Intent請求所對應的任務。 
  
IntentService在處理事務時,還是採用的Handler方式,建立一個名叫ServiceHandler的內部Handler,並把它直接綁 定到HandlerThread所對應的子執行緒。 ServiceHandler把處理一個intent所對應的事務都封裝到叫做onHandleIntent的虛擬函式;因此我們直接實現虛擬函式onHandleIntent,再在裡面根據Intent的不同進行不同的事務處理就可以了。
另外,IntentService預設實現了Onbind()方法,返回值為null。

使用IntentService需要實現的兩個方法:

1.建構函式 

IntentService的建構函式一定是引數為空的建構函式,然後再在其中呼叫super(“name”)這種形式的建構函式。因為Service的例項化是系統來完成的,而且系統是用引數為空的建構函式來例項化Service的

2.實現虛擬函式onHandleIntent

在裡面根據Intent的不同進行不同的事務處理。