Service是Android系統中的一種元件,它跟Activity的級別差不多,但是它不能自己執行,只能後臺執行,並且可以和其他元件進行互動。Service是沒有介面的長生命週期的程式碼。Service是一種程式,它可以執行很長時間,但是它卻沒有使用者介面。這麼說有點枯燥,來看個例子,開啟一個音樂播放器的程式,這個時候若想上網了,那麼,我們開啟Android瀏覽器,這個時候雖然我們已經進入了瀏覽器程式,但是,歌曲播放並沒有停止,而是在後臺繼續一首接著一首地播放。其實這個播放就是由播放音樂的Service進行控制的。
當然這個播放音樂的Service也可以停止,例如,當播放列表裡邊的歌曲都結束,或者使用者按下了停止音樂播放的快捷鍵等。Service可以在很多場合的應用中使用,比如播放多媒體的時候使用者啟動了其他Activity,這個時候程式要在後臺繼續播放,比如檢測SD卡上檔案的變化,再或者在後臺記錄使用者地理資訊位置的改變等等。總之服務嘛,總是藏在後頭的。
一、註冊Service
service的註冊跟activity的註冊類似,同樣是要在AndroidManifest.xml的檔案裡註冊。
<service android:name=".MyService"> <intent-filter> <action android:name="android.guo.service.playmusic.MyService"/> </intent-filter> </service>
二、Service的兩種模式
service有兩種模式,本地服務和遠端服務。我們一般開發應用都是用的本地服務,而遠端服務經常在做系統開發時被用到。所以今天我會主要講本地的服務,遠端服務放著以後再講吧(其實UP主也沒用過遠端服務就是了==)
類別 | 區別 | 優點 | 缺點 | 應用 |
本地服務(Local) | 該服務依附在主程式上, | 服務依附在主程式上而不是獨立的程式,這樣在一定程度上節約了資源,另外Local服務因為是在同一程式因此不需要IPC,也不需要AIDL。相應bindService會方便很多。 | 主程式被Kill後,服務便會終止。 | 非常常見的應用如:HTC的音樂播放服務,天天動聽音樂播放服務。 |
遠端服務(Remote) | 該服務是獨立的程式, | 服務為獨立的程式,對應程式名格式為所在包名加上你指定的android:process字串。由於是獨立的程式,因此在Activity所在程式被Kill的時候,該服務依然在執行,不受其他程式影響,有利於為多個程式提供服務具有較高的靈活性。 | 該服務是獨立的程式,會佔用一定資源,並且使用AIDL進行IPC稍微麻煩一點。 | 一些提供系統服務的Service,這種Service是常駐的。 |
三、Service的生命週期及兩種啟動方式
service的生命週期比activity簡單多了,原因是service是在後臺執行的,它是一直執行的,所以不需要那麼多的狀態判斷。它只繼承了onCreate()、onStart()或者說是onStartCommand()、 // 2.0 API level之後,實現onStart等同於重寫onStartCommand並返回 關於onStartCommon()的詳解:http://blog.csdn.net/lizzy115/article/details/7001731
onDestroy()三個方法。 服務不能自己執行,需要通過呼叫Context.startService()或Context.bindService()方法啟動服務。這兩個方法都可以啟動Service,但是它們的使用場合有所不同。
- 使用startService()方法啟用服務,呼叫者與服務之間沒有關連,即使呼叫者退出了,服務仍然執行。 如果打算採用Context.startService()方法啟動服務,在服務未被建立時,系統會先呼叫服務的onCreate()方法,接著呼叫onStart()方法。如果呼叫startService()方法前服務已經被建立,多次呼叫startService()方法並不會導致多次建立服務,但會導致多次呼叫onStart()方法。 採用startService()方法啟動的服務,只能呼叫Context.stopService()方法結束服務,服務結束時會呼叫onDestroy()方法。
- 使用bindService()方法啟用服務,呼叫者與服務繫結在了一起,呼叫者一旦退出,服務也就終止,大有“不求同時生,必須同時死”的特點。onBind()只有採用Context.bindService()方法啟動服務時才會回撥該方法。該方法在呼叫者與服務繫結時被呼叫,當呼叫者與服務已經繫結,多次呼叫Context.bindService()方法並不會導致該方法被多次呼叫。採用Context.bindService()方法啟動服務時只能呼叫onUnbind()方法解除呼叫者與服務解除,服務結束時會呼叫onDestroy()方法。
四、Service例項
ServiceActivity.java:
package com.example.helloandroid; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class ServiceActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_service); Button btnStartService = (Button)this.findViewById(R.id.btnStartService); Button btnStopService = (Button)this.findViewById(R.id.btnStopService); btnStartService.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { startService(new Intent(ServiceActivity.this, MyService.class)); } }); btnStopService.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { stopService(new Intent(ServiceActivity.this, MyService.class)); } }); } @Override protected void onStart() { super.onStart(); } @Override protected void onResume() { super.onResume(); } @Override protected void onPause() { super.onPause(); } @Override protected void onStop() { super.onStop(); } @Override protected void onDestroy() { super.onDestroy(); } }
activicy_service.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="服務" /> <Button android:id="@+id/btnStartService" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="啟動服務" /> <Button android:id="@+id/btnStopService" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="停止服務" /> </LinearLayout>
MyService.java:
package com.example.helloandroid; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.util.Log; import android.widget.Toast; public class MyService extends Service{ private final String STR_TAG ="TAG"; @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return null; } @Override public void onCreate(){ Log.v(STR_TAG, "My Service Create"); } @Override public void onStart(Intent intent, int startId) { Log.v(STR_TAG, "My Service Started"); } @Override public void onDestroy(){ Log.v(STR_TAG, "My Service Destroy"); } }
啟動Service過程如下:
context.startService() ->onCreate()- >onStart()->Service running
其中onCreate()可以進行一些服務的初始化工作.
停止Service過程如下:
context.stopService() | ->onDestroy() ->Service stop