作为一个android初学者,经常对service的使用感到困惑。今天结合Google API 对Service这四大组件之一,进行简单使用说明。
希望对和我一样的初学者有帮助,如有不对的地方,也希望及时指出。
Service :就是长时间运行在后台,没有用户界面的一个应用组件。即便,用户切换到其他的应用,Service依然可以在后台运行。
除此之外,一个组件可以将自己和Service进行绑定,甚至是进程间通信。例如,Service可以处理网络请求,播放音乐,
处理I/O操作,和Content provider进行交互。
上述是API 对Service的介绍,简单来说,Service就是可以长时间运行在后台,不需要界面的一个组件。
Service的存在形式,也就是启动方式有两种。需要通过Intent启动。
1,Stared(启动) 组件通过调用startService()启动Service,即便组件被销毁,Service依然可以在后台运行。调用stopService(),stopSelf()销毁Service。
startService( serviceIntent); stopService( serviceIntent);
2,Bound(绑定) 组件通过调用bindService ()和Service进行绑定启动。Service执行onBind()。通过unbindService()将Service和组件进行解绑。
解绑时,Service执行onUnbind(),若此时没有任何组件和Service存在绑定关系,会接着执行onDestroy();
绑定启动的Service提供了client-server(IBinder通信机制),使得组件和service之间可以进行交互。
多个组件可以和一个service进行绑定,当所有组件都解绑的时候,service执行onDetroy()被销毁。
public abstract boolean bindService (Intent service, ServiceConnection conn,
int flags);
public abstract void unbindService(ServiceConnection conn);
通过Bound方式进行启动的时候,需要创建ServiceConnetction,并重写onServiceDisconnected,onServiceConnected方法,这就是Service
提供的client-server(IBinder通信)。
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName arg0) {
Log. e(TAG, "onServiceDisconnected");
}
@Override
public void onServiceConnected(ComponentName arg0, IBinder service) {
Log. e(TAG, "onServiceConnected");
MyService mService = ((MyService.MyBinder)service).getService();
}
};
在Service中的onBind()方法中,要返回一个Binder。Binder可以自定义。例如:
public IBinder myBinder = new MyBinder();
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
Log. e(TAG, "onBind");
return myBinder ;
}
public class MyBinder extends Binder{
public TestService getService(){
return TestService. this;
}
}
在onBind()中返回的这个Binder,可以在onServiceConnected()中拿到,这样就可以拿到Service对象,并对其操作。
MyService mService = ((MyService.MyBinder)service).getService();
**关于IBinder的通信机制,可以深入研究下。
##Service可以被启动多次,也可以被绑定多次,也可以既绑定,也启动。
## Service默认情况下,是存在于主进程的主线程(UI线程)中,Service不会自己创建新的自己的线程,也不会运行在不同的进程。除非对service进行特别声明。
这就意味着,如果在service中进行一些耗时或者复杂密集的操作时,应该放到线程中去做。
## Service如果被started方式启动,又被Bound方式启动,此时调用stopService()是不能够销毁掉Service,只有当Unbind()掉所有的绑定,才能执行Service的onDestroy();
## Service和Activity组件一样,使用的时候需要在manifest中进行声明设定。可以将Service设定成私有的,或者增加intent filter等设定参数。
OK,Service启动后,再来关注下它的生命周期。
第一种方式:startService()
onCreate() 创建Service,此回调方法只会执行一次。Service多次启动并不会多次创建。
onStartCommand() 每次startService()都会执行。如下图,创建Service后执行此方法。启动Service的时候可以通过Intent传递数据。在此方法中进行处理。
onDestroy() 调用stopService() stopSelf() 或者Unbind()后,执行此方法,Service进行销毁。
第二种方式 bindService()
onCreate() 创建Service,此回调方法只会执行一次。Service多次启动并不会多次创建。
onBind() 绑定Service,并回调Ibinder.
onUnbind() 解除绑定
onDestroy() 销毁
**关于onStartCommand()返回值的说明:
START_NOT_STICKY
- 系统将Service杀死之后,不重新创建Service。除非有pending intents 传过来要重新启动Service.
START_STICKY
- 系统将Service杀死之后,重新创建Service并执行onstartCommand(),但是不传递最后的Intent,而是系统会在重新执行onStartCommand()时们传入一个空的intent.
START_REDELIVER_INTENT
- 系统将Service杀死之后,重新创建Service并执行onstartCommand().传入最后接收的intent.
IntendService
android 中还有一个class,IntentService.
public abstract class IntentService extends Service {
private volatile Looper mServiceLooper;
private volatile ServiceHandler mServiceHandler;
从源码中可以看到,IntentService继承自Service,而且有自己的looper和handler。
Google Api 中说:
The IntentService
does the following:
- Creates a default worker thread that executes all intents delivered to
onStartCommand()
separate from your application‘s main thread. - Creates a work queue that passes one intent at a time to your
onHandleIntent()
implementation, so you never have to worry about multi-threading. - Stops the service after all start requests have been handled, so you never have to call
stopSelf()
. - Provides default implementation of
onBind()
that returns null. - Provides a default implementation of
onStartCommand()
that sends the intent to the work queue and then to youronHandleIntent()
implementation.
IntentService 主要作用:
自己管理一个工作消息序列,同一时刻只有一个任务会被执行,也就是说它不支持多任务并发处理。
不需要调用stopSelf来停止Service,当没有任务执行的时候,会自己停止。使用的时候,只需要实现onHandleIntent()。
@Override
protected void onHandleIntent(Intent intend) {
// TODO Auto-generated method stub
}
**经常看到有人问,怎么保证Service不被杀死。个人认为,不被杀死,从两点考虑。
1.提高优先级
2.杀死后再重启
提高Service优先级,可以使用setForeground(true),将Service变为前台运行。
在onStartCommand()中使用回调返回值,使得Service杀死后再重启。
还看到有大神说创建守护进程,在service被杀死后重启。这个我不是很了解。
关于Service的介绍就是这些,深入的东西,我也不是很懂。写的有点乱。欢迎大家批评指正,互相学习,求大神教育。
我的qq:1921991896