Service的啓動有兩種方式:1)Started,也就是服務的啓動,服務啓動後,服務移動運行下去,及時啓動他的服務已經被銷燬。操作完成後,此服務自動銷燬。服務可以做一些阻塞線程的工作,如網絡下載、上傳文件等。
BoundService是指應用程序組件通過BindService()綁定到服務上。服務聲明後,任何服務器組件都能綁定該服務。
<service android:name=".ExampleService" />
例如啓動一個數據保存的服務,首先啓動一個守護服務,通過startservice()啓動服務,並且通過一個intent進行數據傳遞。該服務在onStartCommond()中接受intent,再進行數據庫的事務處理。另外,需要注意的是啓動服務的時候,需要重新的啓動一個進程。因爲服務都是一些耗時的操作。
綁定服務是一種應用程序和服務綁定的一種方式,它允許應用程序和服務進行綁定交互。客戶端綁定服務的時候必須通過Intent和ServiceConnnection進行服務的綁定。服務綁定之後通過ServiceConnection進行服務的監控和互動。ServiceConnection鏈接後會調用OnServiceConnection回調函數,傳入Ibind對象與服務器端進行交互。
綁定之前需要再服務器端首先準備一個支持Bind的服務,服務中必須實現Onbind方法,並且該方法必須要返回一個對象,客戶端可以通過該對象調用服務的方法。該對象需要實現Ibind()接口,接口中定義服務實現的方法。
以上綁定服務用於同一進程中的操作,多線程的綁定需要通過Message和HandleMessage進行操作。Servcie中定義Handler,同時定義HandleMessage方法,該方法中處理相應的操作,onBind中返回相應的Message接口。客戶端中,依然綁定服務,仍然需要傳遞ServiceConnection,並且通過他獲取服務端的Message。另外,客戶端,根據獲取的Mesage,發送消息與服務器端進行操作。
例如:
public class MessengerService extends Service {
/** 發送給服務的用於顯示信息的指令*/
static final int MSG_SAY_HELLO = 1;
/**
* 從客戶端接收消息的Handler
*/
class IncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_SAY_HELLO:
Toast.makeText(getApplicationContext(), "hello!", Toast.LENGTH_SHORT).show();
break;
default:
super.handleMessage(msg);
}
}
}
/**
* 向客戶端公佈的用於向IncomingHandler發送信息的Messager
*/
final Messenger mMessenger = new Messenger(new IncomingHandler());
/**
* 當綁定到服務時,我們向Messager返回接口,
* 用於向服務發送消息
*/
@Override
public IBinder onBind(Intent intent) {
Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show();
return mMessenger.getBinder();
}
}
public class ActivityMessenger extends Activity {
/** 用於和服務通信的Messenger*/
Messenger mService = null;
/** 標識我們是否已綁定服務的標誌 */
boolean mBound;
/**
* 與服務的主接口進行交互的類
*/
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
// 與服務建立聯接後將會調用本方法,
// 給出用於和服務交互的對象。
// 我們將用一個Messenger來與服務進行通信,
// 因此這裏我們獲取到一個原始IBinder對象的客戶端實例。
mService = new Messenger(service);
mBound = true;
}
public void onServiceDisconnected(ComponentName className) {
// 當與服務的聯接被意外中斷時——也就是說服務的進程崩潰了,
// 將會調用本方法。
mService = null;
mBound = false;
}
};
public void sayHello(View v) {
if (!mBound) return;
// 創建並向服務發送一個消息,用到了已約定的'what'值
Message msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0);
try {
mService.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
protected void onStart() {
super.onStart();
// Bind to the service
bindService(new Intent(this, MessengerService.class), mConnection,
Context.BIND_AUTO_CREATE);
}
@Override
protected void onStop() {
super.onStop();
// Unbind from the service
if (mBound) {
unbindService(mConnection);
mBound = false;
}
}
}
另,onBinde(Intent,ServiceConnection,服務標識),Intent即服務的意圖,也就是要啓動的服務。ServiceConnection標識進行交互的對象,第三個標識指的是服務的啓動方式。
另外服務是可以跨進行進行通信的,通信的方式通過AIDL和RPC協議進行通信。AIDL定義了通信的接口,RPC將通信的方式進行封裝,使得程序顯示的更加簡潔和方便。