一个Service有两种形态 被启动 (Started)
onStartCommand()
当调用stopService()或者stopSelf()时结束当前Service 被绑定(Bound) onBind()当所有组件都调用unbindService()时结束当前Service
Service运行在宿主进程的主线程中,不会自动生成自己的线程,所以在Service中有耗时操作时,需要创建自己的线程避免ANR错误。
Service需要实现的几个重要回调方法:
- onStartCommand() 调用
startService()时将先回调此方法,当此方法被执行时,意味着在后台启动了一个无限期的服务,开发者需要维护Service自身的生命周期,当任务完成时,可以在Service内部调用stopSelft()或者在Service外部调用 stopService()结束服务。如果你仅使用 bindService()方法启动Service时,可以不实现此方法。
-
bindService()时回调此方法,此方法会返回用于clients端和Service进行通信的IBinder对象。你必须实现此方法,如果你不想bind服务的话,只需要返回null就行了。onBind() 当Android组件调用
- onCreate()当Service初次被创建的时候回调此方法,方便用于实现初始化操作。
- onDestroy() 当Service即将被销毁时回调此方法,方便用于开发者释放资源。
在AndroidManifest.xml中配置Service的注意事项:
- 可以设置
android:exported为false,以避免外部应用访问
-
android:permission以添加权限,以避免外部应用访问可以单独设置Service的
- 如果你的Service作为public API使用时, android:name不能轻易修改 (http://android-developers.blogspot.hk/2011/06/things-that-cannot-change.html)
- 仅应用内单独使用的Service最好不要设置intent-filter,推荐使用explicit intent(显示意图)
两种Service的父类
- Service
- IntentService 当不需要Service内部同时处理多个请求时,推荐继承此类。这个类内部定义了 worker thread,所以不像Service类那样需要开发者再创建新的thread以避免ANR。继承此类只需要实现
onHandleIntent(),
需要注意的是当有多个start请求同时到来时,会按先后次序排列任务,当其中的某个任务耗时过长将会阻塞后边的任务。
onStartCommand()
返回值
- START_NOT_STICKY 被杀后不会自动重启,最安全的使用方式
- START_STICKY 被杀后会重启并带有 null Intent,适用于MediaPlayer
- START_REDELIVER_INTENT 被杀后会重启,并带有被杀前的最后一个Intent,适用于下载文件
内部停止服务的注意事项:当处理并发启动服务时,onStartCommand()会被同时调用多次,有可能在调用 stopSelf()时,正好有onStartCommand()的调用,可能会丢失处理任务,所以API中提供了另一种stopSelf(int startId)的方法,在onStartcommand()中有一个startId参数,当stopSelf中的startId与启动时的startId不符时,就不会停止服务。
阅读原文