2010年11月1日 星期一

Android Service-概念(一)

一.說明
Service本身是個無介面,只單純提供功能讓其他元件(Activity)呼叫使用的元件,如果有需要長時間執行的獨立程序,可以寫成Service元件提供其他人呼叫使用。

Service本身並非一個獨立的Process,也不會脫離Main Thread獨立運作,如果需要做長時間的CPU運算,為了不影響到主程式運作,可以在Service內產生Thread,讓thread幫你作一些工作,Service的子類別IntentService即是一個有自己Thread 的Service,服務給並無直接與使用者互動的介面。
當Service元件被產生時,一定會執行其onCreate(),如果有需要產生Thread,則在這裡去產生新的thread

當Service有設定在Manifest上,就可以被自己與其他的App來做存取,其他App要使用service,需在他自己App的Manifest內的uses-permission作宣告

二.執行Service功能的兩種方式
1.startService
當有元件呼叫Context.startService(),系統會讀取被呼叫的Service(產生instance並執行其onCreate()),然後將client所傳進來的intent帶進Service的onStartCommand(Intent, int, int)內。這service會一直執行,直到有人呼叫Context.stopService()或內部呼叫stopSelf()而停止。

無論Context.startService()被呼叫了多少次,如果要停止Service,只要執行一次Context.stopService(),或在Service內執行stopSelf(),就會被停止。
如果是在Service內使用stopSelf(int),可以保證intent已經有被處理了,才會被停止。

對於已被啟動的Service,如果需要有不同的Service執行模式,可以在override onStartCommand()時,設定不同的回傳值。這回傳值常數已經被定義好在Service Class內
1.START_STICKY:
  當Service在執行時被砍掉後,若沒有新的intent進來,
  Service會停留在started state,但intent資料不會被保留
2.START_NOT_STICKY或START_REDELIVER_INTENT:
  當Service在執行時被砍掉後,若沒有新的intent進來,
  service會離開started  state,若沒有很明確的再啟動,
  將不會產生新的service物件

2.bindService
Client可以利用Context.bindService() 去建立與service持續性的連線,
如果建立連線時,還沒產生Service instance,會自動產生並呼叫執行onCreate。與startService不同的地方是,接下來並不會呼叫onStartCommand

要執行bindService,首先要先建立一個serviceConnection物件,把這conection物件當作參數放到bindService內讓Context與Service建立連線,Context.bindService(Intent service, ServiceConnection conn, int flags)
flags參數預設是Context.BIND_AUTO_CREATE,也就是bind的時候會自動產生service

當連線成功後,會自動呼叫執行這個connection內的onServiceConnected(ComponentName className, IBinder service) function,在這function會接收到由service內的onBinde()所丟出來的Ibinder物件
利用這IBinder物件取得Service物件,就可以直接操作Service內各個public 的method

三.Service Process重要性判斷
系統會盡量保持Service的Process運作,但若需要刪除Process,以下是重要性判斷準則
1.正在執行onCreate(), onStartCommand()或onDestroy()的
  Service會被當成前景執行程序,不會被刪除
2.假若這ervice已經被啟動(started),那這service所在的
  process的重要性,會是在visible process與hide process之間
3.如果service所在的Process上有元件是visible,那這Service
  的重要性就相當於是visible
4.一個已經started的service可以利用
  startForeground(int,Notification)放在比較重要的
  前景執行狀態,在記憶體少的時候比較不會被刪除

當記憶體不足Service被刪除後,它稍後還是會被重新啟動產生出來,但通常重新啟動後,原本的intent並不會被保留,如果需要在重新啟動後,再重發intent給Service,必須在override onStartCommand()時return START_REDELIVER_INTENT讓重新啟動的程序裡的onStartCommand(Intent intent, int flags, int startId)內的flags值=START_FLAG_REDELIVERY

1 則留言:

legochen 提到...

Good Job !! 邏輯寫得很讚 受益了 !!