Service
几个问题
1. Service的start和bind状态有什么区别?
- 同一个Service,先startService,然后再bindService,如何把它停止掉?
- 你有注意到Service的onStartCommand方法的返回值吗?不同返回值有什么区别?
- Service的生命周期方法onCreate、onStart、onBind等运行在哪个线程?
学习的过程中还会遇到其它问题会一块解决
概述
Service是一个一种可以在后台执行长时间运行操作而没有用户界面的应用组件。Service可由其他应用组件启动(如Activity,也可以是另外一个Service),Service一旦被启动将在后台一直运行,即使启动服务的组件(Activity)已销毁也不受影响。 此外,组件可以绑定到服务,以与之进行交互,甚至是执行进程间通信 (IPC)(什么是进程间通信)。 例如,Service可以处理网络事务、播放音乐,执行文件 I/O 或与内容提供程序交互,而所有这一切均可在后台进行
声明
任何 service都是通过继承 Service 基类自定义而来,需要在AndroidManifest.xml中声明
<service android:enabled=["true" | "false"]
android:exported=["true" | "false"]
android:icon="drawable resource"
android:isolatedProcess=["true" | "false"]
android:label="string resource"
android:name="string"
android:permission="string"
android:process="string" >
. . .
</service>
定义
定义过程主要实现下面几个方法
onBind()
当另一个组件想通过调用 bindService() 与服务绑定(例如执行 RPC)时,系统将调用此方法。在此方法的实现中,必须返回 一个IBinder 接口的实现类,供客户端用来与服务进行通信。无论是启动状态还是绑定状态,此方法必须重写,但在启动状态的情况下直接返回 null。
onCreate()
首次创建服务时,系统将调用此方法来执行一次性设置程序(在调用 onStartCommand() 或onBind() 之前)。如果服务已在运行,则不会调用此方法,该方法只调用一次
onStartCommand()
当另一个组件(如 Activity)通过调用 startService() 请求启动服务时,系统将调用此方法。一旦执行此方法,服务即会启动并可在后台无限期运行。 如果自己实现此方法,则需要在服务工作完成后,通过调用 stopSelf() 或 stopService() 来停止服务。(在绑定状态下,无需实现此方法。)
onDestroy()
当服务不再使用且将被销毁时,系统将调用此方法。服务应该实现此方法来清理所有资源,如线程、注册的侦听器、接收器等,这是服务接收的最后一个调用。
启动
当组件通过调用 startService() 启动服务时,服务即处于“启动”状态。一旦启动,服务即可在后台无限期运行(如何停止服务),即使启动服务的组件已被销毁也不受影响,除非手动调用才能停止服务, 已启动的服务通常是执行单一操作,而且不会将结果返回给调用方。
绑定
bindService
Service处于绑定状态时,其代表着客户端-服务器接口中的服务器。当其他组件绑定到服务时可以从组件中去调用Service中的方法
答案
- Service的start和bind状态有什么区别?
startService() :
场景:一般主要用于长期后台运行播放音乐
生命周期: onCreate(第一次会触发)–onStartCommand(每次都会触发)–onDestry
停止方式 外部调用 Context.stopService(service)(可以执行多次)或者自身 StopSelf()
bindService(service,conn.flags):
生命周期 onCreate–onBind(只能触发一次)–onUnbind– onDestroy
bind启动之后服务与组件相关联,如果组件销毁服务也会销毁
停止方式 Context.unbindService(conn)(只能解绑一次,多次会抛出异常)或启动它的 activity 销毁
- 同一个Service,先startService,然后再bindService,如何把它停止掉?
需要分别调用stopService(当然也可以是stopSelf)和unbindService才能停止掉。前者是让服务的启动状态失效,后者是让服务的绑定状态清除,调用顺序没有要求。当一个服务既不处于启动状态也没有Context与其绑定时,即可停止掉
- 你有注意到Service的onStartCommand方法的返回值吗?不同返回值有什么区别
onStartCommand()方法必须返回一个整数,这个整数是一个描述了在系统的杀死事件中,系统应该如何继续这个服务的值(虽然你能够修改这个值,但是IntentService处理还是为你提供了默认实现)
START_NOT_STICKY:若执行完onStartCommand()方法后,系统就kill了service,不要再重新创建service,除非系统回传了一个pending intent。这避免了在不必要的时候运行service,您的应用也可以restart任何未完成的操作。
START_STICKY:若系统在onStartCommand()执行并返回后kill了service,那么service会被recreate并回调onStartCommand()。dangerous不要重新传递最后一个Intent(do not redeliver the last intent)。相反,系统回调onStartCommand()时回传一个空的Intent,除非有 pending intents传递,否则Intent将为null。该模式适合做一些类似播放音乐的操作。
START_REDELIVER_INTENT:若系统在onStartCommand()执行并返回后kill了service,那么service会被recreate并回调onStartCommand()并将最后一个Intent回传至该方法。任何 pending intents都会被轮流传递。该模式适合做一些类似下载文件的操作。
START_STICKY_COMPATIBILITY
START_STICKY的兼容版本,但不保证服务被kill后一定能重启。
而输入参数flags正是代表此次onStartCommand()方法的启动方式,正常启动时,flags默认为0,被kill后重新启动,参数分为以下两种
- Service的生命周期方法onCreate、onStart、onBind等运行在哪个线程?
主线程,Service 中执行耗时操作会出现 anr