標籤:
4.2 千變萬化的服務-Service開發
Service是Android系統中運行在後台、不和使用者互動應用組件。它和Activity的層級差不多,只能在後台運行。每個Service必須在manifest檔案中 通過<service>來聲明。
4.2.1 Service的生命週期
Service的生命週期並不像Activity那麼複雜,它只繼承了onCreate(),onStart(),onDestroy()三個方法,當我們第一次啟動Service的時候,先後調用onCreate()、onStart()這兩個方法,當停止Service的時候,則執行onDestroy()方法,這裡需要注意的是,如果Service已經啟動了,當我們再次啟動Service時,不會再執行onCreate()方法,而是直接執行onStart()方法。Service的啟動有StartService和BindService兩種方法,這兩種方法對Service生命週期的影響是不一樣的。
下面,我們分別來看看這兩種方法是如何影響Service生命週期的:
1) StartService啟動Service
用這種方法啟動Service,Service會經曆 onCreate 然後是onStart,接著一直處於運行狀態,直到stopService的時候調用onDestroy方法。如果是調用者自己直接退出而沒有調用stopService的話,Service會一直在後台運行。
2) BindService啟動Service
通過這種方法啟動Service,Service會運行onCreate,然後是調用onBind, 這個時候調用者和Service綁定在一起。調用者退出了,Srevice就會調用onUnbind->onDestroyed方法。所謂綁定在一起就共存亡了。調用者也可以通過調用unbindService方法來停止服務,這時候Srevice就會調用onUnbindonUnbind->onDestroyed方法。
4.2.2 Service的啟動和停止
我們已經對Service的生命週期有了一定的瞭解,Service的啟動方式不同,它的生命週期也不相同。下面,就讓我們來看看Service到底是如何啟動和停止的。
服務不能自己運行,需要通過調用Context.startService()或Context.bindService()方法啟動服務。這兩個方法都可以啟動Service,但是它們的使用場合有所不同。
1)使用startService()方法啟用服務,調用者與服務之間沒有關連,即使調用者退出了,服務仍然運行。
如果打算採用Context.startService()方法啟動服務,在服務未被建立時,系統會先調用服務的onCreate()方法,接著調用onStart()方法。
如果調用startService()方法前服務已經被建立,多次調用startService()方法並不會導致多次建立服務,但會導致多次調用onStart()方法。
採用startService()方法啟動的服務,只能調用Context.stopService()方法結束服務,服務結束時會調用onDestroy()方法。
2)使用bindService()方法啟用服務,調用者與服務綁定在了一起,調用者一旦退出,服務也就終止,大有“不求同生,必須同死”的特點。
onBind()只有採用Context.bindService()方法啟動服務時才會回調該方法。該方法在調用者與服務綁定時被調用,當調用者與服務已經綁定,多次調用Context.bindService()方法並不會導致該方法被多次調用。
採用Context.bindService()方法啟動服務時只能調用onUnbind()方法解除調用者與服務解除,服務結束時會調用onDestroy()方法。
4.2.3 我的服務我來用—本地服務(Localservice)開發
本地服務用於應用程式內部。它可以啟動並運行,直到有人停止了它或它自己停止。在這種方式下,它以調用Context.startService()來啟動,調用Context.stopService()來停止。它也可以調用Service.stopSelf() 或Service.stopSelfResult()來自己停止。不論調用了多少次startService()方法,你只需要調用一次stopService()就可以停止服務。
它用於實現應用程式自己的一些耗時任務,比如查詢升級資訊,它並不佔用應用程式Activity所屬線程,而只是單開線程後台執行,這樣使用者體驗比較好。
有些服務是不需要和Activity互動就能直接啟動並執行,而有些則是需要與Activity進行互動。下面,我們通過一些例子來加以說明。
--------------------------------------------試著放個廣告 現在沒工作 要生存 沒辦法平安陸金所 隸屬於平安集團的p2p平台年投資報酬率7%-9% 是替代銀行理財的首選個人經驗教訓 推薦投資安鑫或者有擔保的彩虹項目不要投資安e 那個幾乎無法轉讓 想提前提現非常困難註冊連結 http://affiliate.lufax.com/action/36XBU用此連結註冊 你我都會有幾十元的額外現金獎勵--------------------------------------------
1)不和Activity互動的本地服務
首先,我們建立一個LocalService類繼承自Service,代碼如下:
// import略 public class LocalService extends Service{ @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); } @Override public void onDestroy() { super.onDestroy(); } @Override public void onStart(Intent intent, int startId) { super.onStart(intent, startId); } } |
然後,建立一個類ServiceActivity繼承自Actvity,代碼如下:
// import略 public class ServiceActivity extends Activity{ private Button startBtn,stopBtn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.localservice); startBtn = (Button)findViewById(R.id.start_button); stopBtn = (Button)findViewById(R.id.stop_button); startBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startService(new Intent("com.char4.LOCAL_SERVICE")); } }); stopBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { stopService(new Intent("com.char4.LOCAL_SERVICE")); } }); } } |
布局檔案localservice.xml代碼如下,它定義了兩個按鈕,一個用來啟動Service,一個用來停止Service:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/start_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="啟動"/> <Button android:id="@+id/stop_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="停止"/> </LinearLayout> |
別忘了,在AndroidMainfest.xml中註冊Service:
<service android:name=".LocalService"> <intent-filter> <action android:name="com.char4.LOCAL_SERVICE " /> <category android:name="android.intent.category.default" /> </intent-filter> </service> |
下面,我們來看看效果,4-7所示:
圖4-7 startService啟動順序
通過日誌列印我們可以發現,第一次點擊“啟動”按鈕時,會調用onCreate和onStart方法,在沒有點擊“停止”按鈕前,無論點擊多少次“啟動”按鈕,都只會調用onStart。而點擊“停止”按鈕時則調用onDestroy。再次點擊 “停止”按鈕,會發現不會進入service的生命週期的,即不會再調用onCreate,onStart和onDestroy,而onBind在點擊“啟動”和“停止”按鈕時都沒有調用。
第四章 Android開發三大基石—Activity、Service和Handler(4)