25 November 2012
這篇要說明
  • startService
  • bindService
這兩者的差別!

其實在我之前的筆記有關Service的文章,都是使用startService!
並沒有使用bindService!
一方面是因為startService簡單很多!
再來也是最近才發現有bindService!
應該是說我原本以為startService的行為與bindService差不多!
但實際找答案以後才知道不是這樣的!


這裡就不多作說明如何使用startService或者bindService!
主要會說明這兩者差異性!
如果要看如何使用可以看之前的筆記:

  1. Android C2DM (四):實作之Android篇
  2. android detect screen on and screen off
  3. android 偵測 sdcard


先去看Google的定義,對於startService,Google定義如下
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.
簡言之用startService啟動,這個service是不會跟隨著啓動他的component消滅!且原則上是不能與UI互動的!(原則上)


而對於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.
用bindService起來的話,則此service可以跟該component進行溝通!甚至可以做到 IPC!

小結:
bindService和startService最主要的差異在於其本身的lifecycle!
以及bindService可以用來做IPC!簡單的說就是可以讓你的service和UI溝通!

這裡就用一個project來說明吧!

先建立一個new project!
在這project中建立一個Activity,並指定它為launcher!
然後在建立一個Service!內如如下:
public class Services extends Service {

@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
Log.d("TestService","onBind");
return null;
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("TestService","onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
@Override
public ComponentName startService(Intent service) {
Log.d("TestService","startService");
return super.startService(service);
}

@Override
public void onCreate() {
super.onCreate();
Log.d("TestService","onCreate");
}

@Override
public void onDestroy() {
super.onDestroy();
Log.d("TestService","onDestroy");
}

@Override
public boolean onUnbind(Intent intent) {
Log.d("TestService","onUnbind");
return super.onUnbind(intent);
}

}

可以看到上面的Service中並沒有做任何處理!
只有簡單的Log!
目的只是要讓我們瞭解startService和bindService的lifecycle差異性!

首先先來講startService,
我們先在onCreate中start!如下:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

startService(new Intent(this,Services.class));
}

然後按下run,在開啟DDMS來觀看log!
會發現印出了”onCreate"->"onStartCommand"!

這時候按下back鍵來destroy這個activity,你會發現什麼都沒有印出來!
也就是說這個service仍在background執行!(你得手動stop)

這時候我們換成bindService來看看,如下:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

bindService(new Intent(this,Services.class),null,Context.BIND_AUTO_CREATE);
}

一樣按下run!再看一下LOG!
會發現印出“onCreate"->"onBind"!

再按下back鍵,會發現...印出了!
“onUnbind"->"onDestroy"



總結上面兩項的差異,
會發現使用bindService時,
這個service的lifecycle是跟隨著bind它的object!
所以當該object被destroy,自然而然這個service也被destroy!

而使用startService,
就不是這樣了!這個service就是獨立的!不屬於任何一個object!
得靠stopService來停止!(任何一個Activity中都可以stop)


註:bindService的使用方式比較特別!
多帶了幾個參數!
在這個例子我們第二個參數設為null!
其實這參數是要傳入一個ServiceConnection的物件!
而ServiceConnection是一個Interface,這個Interface中
會有兩個callback function!
主要是用來monitor 這個service的state!
















blog comments powered by Disqus