一个服务就是一个能够在后台执行长时操作的应用程序组件,并且不提供用户界面。一个应用程序组件能够启动一个服务,即使用户切换到另一个应用程序,这个服务也会继续在后台运行。另外,一个组件能够绑定一个跟它交互的服务,甚至是进程间通信(IPC)。例如,一个服务可以处理网络事务、播放音乐、执行文件I/O、或者跟内容提供器交互,所有这些都是在后台完成的。
一个Service基本上有两种形式:
被启动(Started)
当应用程序组件(如一个Activity)通过调用startService()方法启动的服务是“被启动(started)”的。服务一旦启动,它就能够无限期的在后台运行,即使启动它的组件被销毁。通常,一个被启动的服务之星一个单一操作,并且不给调用者返回结果。例如,这个服务可能在网络上下载或上传文件。当操作完成的时候,服务应该自己终止。
被绑定(Bound)
当一个应用程序组件通过调用bindService()方法绑定的服务是“被绑定(bound)”的。一个被绑定的服务会提供一个允许组件跟服务交互的客户端接口,用于发送请求、获取结果、甚至是跨进程的进程间通信(IPC)。一个被绑定的服务的运行时间跟绑定它的应用程序组件一样长。多个组件能够绑定一个服务,但是只有所有这些绑定解绑,这个服务才被销毁。
尽管这份文档分开讨论服务的这两种方式,但是你的服务能够用这两种方式工作---它能够被启动(无限期的运行),也允许绑定。这取决你是否实现了一对回调方法:运行组件启动的onStartCommand()方法和允许绑定的onBind()方法。
无论你的应用程序是启动、绑定或同时使用这两种方式开启一个服务,任何应用程序组件都能使用这个服务(即使是单独的应用程序),用同样的方法,任何组件能够使用一个Activity---通过Intent启动Activity。但是,你能够在清单文件中声明私有的服务,并且阻止来自其他应用程序的访问。
警告:一个服务运行在它的宿主进程的主线程中---这个服务不创建它自己的线程,并且不在一个单独的进程中运行(除非你指定)。这就意味着如果你的服务要做一些频繁的CPU工作或阻塞操作操作(如MP3的回放或网络操作),你应该在这个服务中创建一个新的线程来做这项工作。通过使用一个单独的线程,你会减少应用程序不响应(ANR)的错误风险,并且应用程序的主线程能够保留给用户,专用于跟Activity的交互。