Android Service全解(一)之 startService

本系列文章的序介绍了Service的大概情况,本章详细介绍Service的启用运行方法。

运行Service的方法有2种,一种是使用startService(),另一种是使用bindService(),bindService()是一个比较复杂但非常有用的方法,关于bindService()的内容在这个系列的后面会详细讲解。

startService()是Android提供的启动Service的方法,任何继承于android.content.Context的Android组件(component)都可以使用一个Intent(android.content.Intent)来开启一个Service。Intent里面可以以类对象(Class<?>)或者action进行构造,使用action构造对于初学者来说不太直观,而且action构造的适用范围比类对象构造使用范围更广,所以action构造的方法将在本系列文章后面的内容进行介绍,现在就都使用类对象进行构造。

如果Service并没有运行,则新建一个Service(这里涉及到Service指派Task的问题将在以后的内容中介绍),并运行之,相继Service的回调onCreate(),onStart()/onStartCommand()(onStartCommand()是在Android2.0及之后SDK加入推荐使用的,用来代替老版的onStart()方法)被调用;如果Service已经在运行了,则只有回调onStart()/onStartCommand()被调用。

参看Android官方文档可以发现,onStart()和onStartCommand()均会传入一个Intent对象参数,这个Intent对象就是使用startService()时传入的同一个Intent对象(同一个表示使用“==”比较返回true)。因为Intent对象可以携带Extra数据,所以启用Service的组件可以随意的向Service传递Extra数据(使用putXXExtra()/putExtra()等方法,最常见的就是使用Java基本类型、String对象或者封装在Bundle对象中作为Extra数据,关于Extra数据的类型限制请自行参见文档)。当组件要传数据到Service时,只需要调用startService()并传入相应的携带了Extra数据的Intent对象,并在Service的onStart()/onStartCommand()中接收取出Extra数据,而不用理会Service是否已经运行,数据始终能够到达Service并进行处理。这样,就可以完成单向的IPC(进程间通信)功能(组件->Service)。

当不想再让Service运行的时候,只需要(任一)组件调用stopService()并传入相应的Intent对象,如果Service正在运行,则会停止,如果Service没有运行,则系统会自动当什么事也没发生。如果Service自己不想再运行,可以在Service里使用stopSelf()自杀,可以看出,如果可以运行到自杀代码的话,那么Service肯定在运行。

onStart()/onStartCommand()都会传入参数startId:int,用来标识Service的启用号。每次startService()系统会自动为开启的Service产生一个不同的startId,之前赋予它的startId(如果有)将会被覆盖,并且这个新产生的startId会成为这个Service的新的startId,无论Service是否正在运行。

考虑如下情况,当多个组件启用了同一个Service,Service提供互斥的服务(使用synchronized关键字),且要保证在Service把所有工作完成之前不能自杀,这个时候,startId就相当有用了,在Service onStart()/onStartCommand()时把startId保存起来,因为互斥的使用服务,则Service是按顺序提供服务的,则Service自杀的时候只用检查当前Service的startId与保存的这个startId是否相同,不同则说明Service之后还有任务,不能自杀,相同则说明正在运行的任务已经是最后一个任务了,运行完后就可以自杀(使用stopSelf(int startId)方法)。关于这个问题的代码在下面的Demo中列出。

最后,这里有个包就是一个最简单的Service程序,用以展示本章的内容,请到 Juwend’s Apps – Demos – service start(待贴)下载学习使用。

本文《Android Service全解(一)之 startService》来自 www.juwends.com ,欢迎转载或CV操作,但请注明出处,谢谢!