發現了比較好的學習service資料,原文出處:Android中Service(服務)詳解html
Service是Android中四大組件之一,在Android開發中起到很是重要的做用,先來看一下官方對Service的定義:java
A Service is an application component that can perform long-running operations in the background and does not provide a user interface. Another application component can start a service and it will continue to run in the background even if the user switches to another application. Additionally, a component can bind to a service to interact with it and even perform interprocess communication (IPC). For example, a service might handle network transactions, play music, perform file I/O, or interact with a content provider, all from the background.android
翻譯過來就是:Service(服務)是一個沒有用戶界面的在後臺運行執行耗時操做的應用組件。其餘應用組件可以啓動Service,而且當用戶切換到另外的應用場景,Service將持續在後臺運行。另外,一個組件可以綁定到一個service與之交互(IPC機制),例如,一個service可能會處理網絡操做,播放音樂,操做文件I/O或者與內容提供者(content provider)交互,全部這些活動都是在後臺進行。markdown
Service有兩種狀態,「啓動的」和「綁定」網絡
Started
A service is 「started」 when an application component (such as an activity) starts it by calling startService(). Once started, a service can run in the background indefinitely, even if the component that started it is destroyed. Usually, a started service performs a single operation and does not return a result to the caller. For example, it might download or upload a file over the network. When the operation is done, the service should stop itself.app
Bound
A service is 「bound」 when an application component binds to it by calling bindService(). A bound service offers a client-server interface that allows components to interact with the service, send requests, get results, and even do so across processes with interprocess communication (IPC). A bound service runs only as long as another application component is bound to it. Multiple components can bind to the service at once, but when all of them unbind, the service is destroyed.less
經過startService()啓動的服務處於「啓動的」狀態,一旦啓動,service就在後臺運行,即便啓動它的應用組件已經被銷燬了。一般started狀態的service執行單任務而且不返回任何結果給啓動者。好比當下載或上傳一個文件,當這項操做完成時,service應該中止它自己。異步
還有一種「綁定」狀態的service,經過調用bindService()來啓動,一個綁定的service提供一個容許組件與service交互的接口,能夠發送請求、獲取返回結果,還能夠經過誇進程通訊來交互(IPC)。綁定的service只有當應用組件綁定後才能運行,多個組件能夠綁定一個service,當調用unbind()方法時,這個service就會被銷燬了。ide
另外,在官方的說明文檔中還有一個警告:
Caution: A service runs in the main thread of its hosting process—the service does not create its own thread and does not run in a separate process (unless you specify otherwise). This means that, if your service is going to do any CPU intensive work or blocking operations (such as MP3 playback or networking), you should create a new thread within the service to do that work. By using a separate thread, you will reduce the risk of Application Not Responding (ANR) errors and the application’s main thread can remain dedicated to user interaction with your activities.學習
意思是service與activity同樣都存在與當前進程的主線程中,因此,一些阻塞UI的操做,好比耗時操做不能放在service裏進行,好比另外開啓一個線程來處理諸如網絡請求的耗時操做。若是在service裏進行一些耗CPU和耗時操做,可能會引起ANR警告,這時應用會彈出是強制關閉仍是等待的對話框。因此,對service的理解就是和activity平級的,只不過是看不見的,在後臺運行的一個組件,這也是爲何和activity同被說爲Android的基本組件。
Service生命週期中的一些方法:
經過這個圖能夠看到,兩種啓動service的方式以及他們的生命週期,bind service的不一樣之處在於當綁定的組件銷燬後,對應的service也就被kill了。service的聲明週期相比與activity的簡單了許多,只要好好理解兩種啓動service方式的異同就行。
service生命週期也涉及一些回調方法,這些方法都不用調用父類方法,具體以下:
public class ExampleService extends Service {
int mStartMode; // indicates how to behave if the service is killed
IBinder mBinder; // interface for clients that bind
boolean mAllowRebind; // indicates whether onRebind should be used
@Override
public void onCreate() {
// The service is being created
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// The service is starting, due to a call to startService()
return mStartMode;
}
@Override
public IBinder onBind(Intent intent) {
// A client is binding to the service with bindService()
return mBinder;
}
@Override
public boolean onUnbind(Intent intent) {
// All clients have unbound with unbindService()
return mAllowRebind;
}
@Override
public void onRebind(Intent intent) {
// A client is binding to the service with bindService(),
// after onUnbind() has already been called
}
@Override
public void onDestroy() {
// The service is no longer used and is being destroyed
}
}
關於Service生命週期還有一張比較易懂的圖(來源於網絡)
另外,這裏要說明Service的一個子類,IntentService,首先看下官方文檔的說明:
This is a subclass of Service that uses a worker thread to handle all start requests, one at a time. This is the best option if you don’t require that your service handle multiple requests simultaneously. All you need to do is implement onHandleIntent(), which receives the intent for each start request so you can do the background work.
IntentService使用隊列的方式將請求的Intent加入隊列,而後開啓一個worker thread(線程)來處理隊列中的Intent,對於異步的startService請求,IntentService會處理完成一個以後再處理第二個,每個請求都會在一個單獨的worker thread中處理,不會阻塞應用程序的主線程,這裏就給咱們提供了一個思路,若是有耗時的操做與其在Service裏面開啓新線程還不如使用IntentService來處理耗時操做。而在通常的繼承Service裏面若是要進行耗時操做就必須另開線程,可是使用IntentService就能夠直接在裏面進行耗時操做,由於默認實現了一個worker thread。對於異步的startService請求,IntentService會處理完成一個以後再處理第二個。
看下IntentService的具體實現:
public class HelloIntentService extends IntentService {
/** * A constructor is required, and must call the super IntentService(String) * constructor with a name for the worker thread. */
public HelloIntentService() {
super("HelloIntentService");
}
/** * The IntentService calls this method from the default worker thread with * the intent that started the service. When this method returns, IntentService * stops the service, as appropriate. */
@Override
protected void onHandleIntent(Intent intent) {
// Normally we would do some work here, like download a file.
// For our sample, we just sleep for 5 seconds.
long endTime = System.currentTimeMillis() + 5*1000;
while (System.currentTimeMillis() < endTime) {
synchronized (this) {
try {
wait(endTime - System.currentTimeMillis());
} catch (Exception e) {
}
}
}
}
}
關於中止Service,若是service是非綁定的,最終當任務完成時,爲了節省系統資源,必定要中止service,能夠經過stopSelf()來中止,也能夠在其餘組件中經過stopService()來中止,綁定的service能夠經過onUnBind()來中止service。
關於Service還有不少知識,這裏就再也不一一列舉,能夠參考 http://developer.android.com/guide/components/services.html