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