Service
什么是Service
Service是一个可以在后台执行长时间操作而不使用用户界面的应用组件。
如何使用Service
我们首先需要实现一个Service的子类。主要实现Service的onCreat(),onStartCommand(),onBind(),onDesroy(),其中onBind()只有在需要与activity有交互的时候才会调用。由于很多时候我们需要在service中进行许多比较耗时的操作,所以我们常常需要在其中开启子线程,因为每次都需要在线程任务执行之后去调用stopSelf()。
Service与Activity通信
从上面的生命周期,可以看出,当用startService()来启动一个Service的时候,这个服务的执行就不再受到控制,为了与某个服务通信,我们可以使用bindService()来启动一个Service。Google的例子如下:
public class MyService extends Service {
private static final String TAG = "MyService";
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
//当其他组件调用bindService()方法时,此方法将会被调用
//然后返回一个Binder对象
//如果不想让这个service被绑定,在此返回null即可
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "onBind");
LocalBinder binder = new LocalBinder();
return binder;
}
@Override
public void onDestroy() {
Log.d(TAG, "onDestroy");
//service调用的最后一个方法
//在此进行资源的回收
super.onDestroy();
}
/** method for clients */
public int getRandomNumber() {
return mGenerator.nextInt(100);
}
/**
* 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 {
MyService getService() {
// Return this instance of LocalService so clients can call public methods
return MyService.this;
}
}
}
使用bindService()和startService()的最大区别就是对于Service中的onBind()实现,当执行到这一步的时候会返回一个Binder对象,这个就是开始与Service通信的节点。
public class MyActivity extends Activity {
LocalService mService;
boolean mBound = false;
/** 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;
}
};
@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();
}
}
}
通过上面的代码我们可以看出,执行bindService()需要是三个参数,一个是intent,一个是ServiceConnection,第三个是一个flag,一般使用BIND_AUTO_CREATE。而Activity与Service的通信主要就是通过这个对象来实现的,我们可以很容易的看出其中两个函数的作用,在Activity与Service执行bind的时候,会将Service中onBind()返回的Binder对象,我们可以通过onServiceConnected()持有它的一个引用,这样我们就可以通过它与Service内部进行通信了。