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";@Overridepublic void onCreate() {super.onCreate();Log.d(TAG, "onCreate");}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {Log.d(TAG, "onStartCommand");return super.onStartCommand(intent, flags, startId);}//当其他组件调用bindService()方法时,此方法将会被调用//然后返回一个Binder对象//如果不想让这个service被绑定,在此返回null即可@Nullable@Overridepublic IBinder onBind(Intent intent) {Log.d(TAG, "onBind");LocalBinder binder = new LocalBinder();return binder;}@Overridepublic 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 methodsreturn 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() {@Overridepublic void onServiceConnected(ComponentName className,IBinder service) {// We've bound to LocalService, cast the IBinder and get LocalService instanceLocalBinder binder = (LocalBinder) service;mService = binder.getService();mBound = true;}@Overridepublic void onServiceDisconnected(ComponentName arg0) {mBound = false;}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);}@Overrideprotected void onStart() {super.onStart();// Bind to LocalServiceIntent intent = new Intent(this, LocalService.class);bindService(intent, mConnection, Context.BIND_AUTO_CREATE);}@Overrideprotected void onStop() {super.onStop();// Unbind from the serviceif (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内部进行通信了。