Service 是一個可以長久運行在後臺不能提供用戶界面的一個組件。程序的其他組件可以啓動service,service可以在後臺運行即便用戶切換了應用程序。一個組件可以綁定一個service並且可以和它交互甚至在進程間交互。例如:請求網絡,播放音樂、I/O、或者和contentprovider交互,所有這一切都是在後臺進行的。
service大致可以有兩種方式存在。
- started:startService
一旦啓它,理論上它就可以在後臺無限期運行了,即便是啓動它的組件退出了它仍然存在。通常,啓動一個service都是一個單獨的操作過程,不會返回調用者結果。當操作完成,service應當自己退出:stopSelf()。
- bound:bindsService
無論使用哪種方式的service,started,bound或兩個一起,其他應用組件都可以使用它,甚至是另一個應用的組件也可以使用它。你也可以聲明你的service爲私有的。
注意:一個service運行在它所附屬的進程的主線程中,service不會創建線程也不會運行在一個獨立的進程中(除非你特別制定)。這意味着如果你的service要做一些影響cpu的操作,你應該創建一個新的線程去工作。
一個 boundService 是一個client-server的接口。一個boundService只有在它鄉另一個應用組件提供服務的時候才活着,它並不是永久運行在後臺的。
- 基本架構:
多個client可以同時綁定service,但是系統並不會再次調用service的onBind()方法了,只有第一個調用的時候纔會回調。系統會傳遞同一個IBinder到後來的client。當最後一個client解綁service後系統會銷燬這個service,除非service已經被started了。
start 方式比較簡單,所以這裏重點介紹Bound Service 。Bound Service 第一部分:本地Binder方式。
- 擴展Binder
如果你的service僅僅服務於本地應用不需要跨進程服務,你可以選擇這種方式。
實現步驟:
1.創建一個Binder對象
2. Binder提供一個公用方法獲取當前service
3.當前service提供公用方法供client使用
public class LocalService extends Service {
// Binder given to clients
private final IBinder mBinder = new LocalBinder();
// Random number generator
private final Random mGenerator = new Random();
/**
* Class used for the client Binder. Because we know this service always
* runs in the same process as its clients, we don't need to deal with IPC.
*/
public class LocalBinder extends Binder {
LocalService getService() {
// Return this instance of LocalService so clients can call public methods
return LocalService.this;
}
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
/** method for clients */
public int getRandomNumber() {
return mGenerator.nextInt(100);
}
}
然後你的Activity綁定這個服務:
public class BindingActivity extends Activity {
LocalService mService;
boolean mBound = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
protected void onStart() {
super.onStart();
// Bind to LocalService
Intent intent = new Intent(this, LocalService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
@Override
protected void onStop() {
super.onStop();
// Unbind from the service
if (mBound) {
unbindService(mConnection);
mBound = false;
}
}
/** Called when a button is clicked (the button in the layout file attaches to
* this method with the android:onClick attribute) */
public void onButtonClick(View v) {
if (mBound) {
// Call a method from the LocalService.
// However, if this call were something that might hang, then this request should
// occur in a separate thread to avoid slowing down the activity performance.
int num = mService.getRandomNumber();
Toast.makeText(this, "number: " + num, Toast.LENGTH_SHORT).show();
}
}
/** Defines callbacks for service binding, passed to bindService() */
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className,
IBinder service) {
// We've bound to LocalService, cast the IBinder and get LocalService instance
LocalBinder binder = (LocalBinder) service;
mService = binder.getService();
mBound = true;
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
mBound = false;
}
};
}
Bound Service 之本地Binder簡單介紹道這裏了,下篇文章介紹Bound Service的第二種方式:《Bound Service 之 Messenger》
文章參考:http://developer.android.com/guide/components/bound-services.html