Android4開發入門經典 之 第五部分:Service【私塾線上原創】

xinqing010發表於2012-03-01

Service基本概念

Service是什麼

是一種能在後臺執行,不需要使用者介面,用來執行需要長時間處理的元件。
 

Service的說明

1:它通常由其他元件啟動,並在後臺持久的執行,即使使用者已經切換到其他的應用,它仍然可以繼續在後臺執行。
2:其他元件能夠跟service繫結,甚至能進行跨程式的通訊(IPC:interprocess communication)
3:一個service通常用來執行:網路傳輸、音樂播放、檔案I/O、或者是與content provider進行互動等等。當然所有的操作過程都在background。

Service的兩種形式

1:Started
如果是其他應用元件通過呼叫startService()方法啟動的service,就被稱為“Started” Service。
一旦啟動了Service,它就會在後臺執行,即使啟動它的元件已經被銷燬了,Service仍然會繼續執行。一般這種啟動Service的操作是不需要返回值的,當Service完成工作後,它自己會停止執行。
2:Bound
如果是其他應用元件通過呼叫bindService()方法繫結的service,就被稱為“bound” Service。
繫結Service提供了Client和Server之間的互動,也就是允許元件和Service進行互動,傳送請求,獲得返回值等。甚至能夠實現跨程式的通訊(IPC)。
繫結Service和繫結它的元件的執行週期是一樣的,多個元件可以繫結到同一個Service,當所有繫結它的元件都銷燬了的時候,Service也就銷燬了。
nService和程式、執行緒
要注意一點:一個Service是執行在主執行緒和它的宿主程式中的,Service不會建立它自己的執行緒,也不會執行在單獨的程式中。
因此,如果Service要執行特別耗費CPU的工作,或者是其他導致阻塞的工作,最好在Service裡面建立新的執行緒來執行這些工作,這樣能避免典型的ANR(Application Not Response)錯誤。

 Service和執行緒的使用建議

1:Service適用於在後臺執行,不需要使用者在介面上操作的功能。
2:Thread適用於你希望在應用之外執行一些功能,而且使用者還需要操作介面,那麼建議使用Thread;還有一種情況就是Service裡面執行的工作特別耗費資源,容易引起主執行緒的阻塞,那麼也建議使用執行緒。
 

Service基本的API-1

建立Service非常簡單,寫一個類繼承Service,然後覆蓋實現相應的回撥方法即可,一些重要的回撥方法如下:

1:onStartCommand():當其他元件啟動Service的時候呼叫。當這個方法執行後,Service就啟動起來在後臺執行了。你可以呼叫stopSelf()或stopService()來停止Service。如果只是繫結服務,沒有必要實現這個方法。
2:onBind():當其他元件繫結Service的時候呼叫。你必須提供一個介面給客戶端,讓它通過這個介面來和服務端通訊,通常會返回一個IBinder,你應該始終實現該方法,如果不用繫結的話,返回null。
3:onCreate():當Service第一次建立的時候由系統呼叫該方法。如果服務已經啟動執行,將不會呼叫該方法。
4:onDestroy():當Service將要被銷燬的時候呼叫該方法。你應該實現該方法來釋放Service所使用的資源,比如:執行緒、註冊的監聽器、廣播訊息接受者等。

銷燬Service

1:如果是通過其他元件呼叫startService()來建立的Service,需要呼叫stopSelf()或stopService()來停止Service
2:如果是繫結的Service,它會一直執行到所有繫結它的元件銷燬後,由系統來銷燬Service。
3:如果系統急需要資源,它會強行停止一些長時間執行,且執行級別較低的service,比如沒有介面,在後臺執行的某些service。

在manifest檔案裡面宣告Service

要想使用Service,需要在manifest檔案裡面宣告Service,比如:

java程式碼:




建立Started Service

建立Started Service

通常有兩個類可以選擇:
1:service:這是所有Service的父類。當你直接繼承這個類的時候,要注意在Service裡面建立一個新的執行緒來執行工作,因為Service是執行在主執行緒裡面的,否則容易引起主執行緒阻塞。
2:IntentService:這是Service的一個子類,它使用一個Worker Thread來處理請求,通常繼承它是一個好的實現方式。你需要實現onHandleIntent()方法。

IntentService完成的工作

1:建立一個Worker Thread來處理請求,與Main Thread區別開來。
2:建立一個工作佇列,每次傳遞一個intent到onHandleIntent()方法,你無需擔心多執行緒的問題
3:當所有的請求都被處理後,自動停止Service。
4:提供onBind()方法的預設實現,返回null
5:提供onStartCommand()方法的預設實現,來把請求分發到onHandleIntent()方法
 

使用IntentService示例


java程式碼:
public class MyService1 extends IntentService{
private int num = 0;
//需要這個構造方法來向父類傳name值
public MyService1() {
super("MyService1");
}
protected void onHandleIntent(Intent in) {
//這裡實現service的工作
Log.i("MyService1","onHandleIntent=="+num++);
try {
Thread.sleep(2000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
 

繼承Service示例


java程式碼:
public class MyService extends Service{
public IBinder onBind(Intent arg0) {
return null;
}
public int onStartCommand(Intent intent, int flags, int startId) {
//這裡實現要處理的功能,這樣實現會阻塞主執行緒,還應該在這裡重新建立執行緒來執行功能
for(int i=0;i<10;i++){
Log.i("MyService","onStartCommand-----------&gt"+startId+",i="+i);
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return super.onStartCommand(intent, flags, startId);
}
}
建立Bound Service有三種方法:擴充套件Binder類、使用Messenger物件、使用AIDL(Android Interface Definition Language)

擴充套件Binder類來實現 Bound Service示例


java程式碼:
public class MyService2 extends Service {
//定義給客戶端使用的Binder
private final IBinder mBinder = new LocalBinder();
public class LocalBinder extends Binder {
MyService2 getService() {
//返回當前例項給客戶端,這樣,客戶端就可以操作服務的方法了
return MyService2.this;
}
}
public IBinder onBind(Intent intent) {
return mBinder;
}
//響應客戶端的服務方法
public int getData() {
Log.i("MyService2","now get Data==");
return new Random().nextInt(100);
}
}

使用Bound Service的Activity示例

1:要實現一個繫結連線的回撥實現

java程式碼:
private MyService2 ms = null;
private ServiceConnection mConnection = new ServiceConnection() {
      public void onServiceConnected(ComponentName className, IBinder service) {
//首先要強制造型
LocalBinder binder = (LocalBinder) service;
ms = binder.getService();
}
public void onServiceDisconnected(ComponentName arg0) { }
};
2:繫結Service

java程式碼:
Intent in = new Intent();
in.setClass(HelloWorldActivity.this, MyService2.class);
HelloWorldActivity.this.bindService(in, mConnection,
HelloWorldActivity.this.BIND_AUTO_CREATE);
3:然後就可以呼叫Service提供的方法了
4:如果不想繫結這個服務了,可以使用unbindService方法
 

在Foreground執行Service

Foreground

某些時候,我們需要Service到前臺來執行,這樣它就能向使用者提供很多使用者關心的服務執行資訊,而且不會被系統銷燬掉。
在Foreground的Service必須在status bar提供notification,除非服務被停止或者服務重新回到後臺執行。

startForeground 方法

要在Foreground執行service,只需要在Service中準備好相應的notification,方法和以前準備是一樣的,只是最後呼叫的方法不是以前的mNotificationManager.notify方法,而是使用startForeground 方法
stopForeground 方法
要取消在Foreground執行service,可以呼叫stopForeground 方法

視訊配套PPT,視訊地址【 Android4開發入門經典獨家視訊課程

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26715458/viewspace-717428/,如需轉載,請註明出處,否則將追究法律責任。

相關文章