Service是一种运行在后台进行长时间工作的应用程序组件,并且它没有任何用户界面。另一个应用程序组件能开启一个Service,并且它会继续运行在后台即使用户转换到另一个应用程序。另外要说的是,一个应用程序组件能够绑定一个Service并且和它进行交互,甚至进行进程间的通信。例如,一个Service可能在后台操作网络事务,播放音乐,进行文件的I/O操作,和一个Content Provider进行交互等后台事务。
一个Service可以进行两种操作:Started和Bound。
Started:当一个应用程序组件调用startService()方法启动这个service,那么这个Service就开启了。一旦这个Service开启,那么这个Service就会就会立即运行在后台,即使这个组件被销毁掉。通常情况下,一个被开启的Service表现的是一个单独的操作并且不会给调用者返回一个结果。
Bound:当一个应用程序组件调用bindService()方法绑定一个Service时,那么这个Service就被绑定了。一个Bound Service提供了一套客户端——服务器接口,这个接口允许组件和这个Service进行通信、发送请求、获取结果、甚至用进程间通信(IPC)进行跨进程操作。一个Bind Service和绑定它的其他组件具有相同的存活时间,也就是说当一次性有多个组件绑定这个Service的时候,只有当所有组件与这个Service解绑的时候这个Service才会被销毁。
尽管以上讲述了这两种方式的区别,但是一个Service这两种方式都可以使用,只是在我们定义一个Service的时候,是否实现onStartCommand()或者onBind()方法的问题。
然而,不论你的应用程序的Service是被started或者被bind,甚至是这两种都有的,任何应用程序组件都能通过Intent对象使用你的Service(甚至是不同的应用程序)。但是我们也可以在Manifest文件中定义我们的Service的私有化(android:exported = false),
不允许其他应用程序的组件访问我们的Service。
如何定义一个Service?
为了创建一个Service,我们首先需要定义一个Service的子类,这个子类需要实现Service几个回调方法,以下是最重要的几种需要实现的回调函数:
onStartCommand():当另一个应用程序组件通过startService方法请求这个Service被开启的时候,系统调用这个方法。一旦这个方法被执行的时候,这个Service就会被开启并且立即在后台运行。如果你实现这个方法的时候,当这个Service完成它的任务的时候,你必须调用stopSelf()和stopService()方法来停止这个Service。(如果我们想要使用bind,我们不需要实现这个方法。)
onBind():当两一个应用程序组件想要通过bindService()绑定这个Service的时候,系统调用这个方法。在这个方法的实现中,你必须提供一个客户端用来和这个Service通信的接口,这个接口返回一个IBinder。你必须总是实现这个方法,但是如果我们不允许这个Service被绑定,我们应该返回null。
onCreate():当这个Service第一次被调用的时候系统调用这个方法,在这个方法之后系统调用onStartCommond或者onBind。如果这个Service方法是运行状态,那么这个方法不被调用。
onDestroy():当一个Service不再被用并且要被销毁的时候调用这个方法。你的应用程序应该实现这个方法去回收资源,例如线程、注册的监听器、reciever等,这个方法这个Service调用的最后一个方法。
如果一个组件调用startService方法启动一个Service,那么将会调用这个service的onStartCommond方法,这个service会一直运行着,直到这个service自己调用stopself方法或者另一个组件调用stopService方法停止它。
Android系统仅仅在低内存的情况下才会强制停止service,它必须为获取到用户焦点的Activity回收资源。但是如果一个Service绑定到一个已经获取到焦点的Activity,那么它将要不太可能被杀死,并且如果一个Service被定义运行在前台,那么它将要从不会被杀死。然而,如果一个Service被启动并且长时间工作,那么系统将会降低他在后台任务列表中的位置,并且这个Service就会变得更加可能被杀死。