第7章后台服务本章学习目标了解Service的原理和用途掌握本地服务的管理方法掌握服务的隐式启动和显式启动方法了解线程的启动、挂起和停止方法了解跨线程的界面更新方法掌握远程服务的绑定和调用方法了解AIDL语言的用途和语法7.1Service简介ServiceService是Android系统的服务组件,适用于开发没有用户界面且长时间在后台运行的应用功能因为手机硬件性能和屏幕尺寸的限制,通常Android系统仅允许一个应用程序处于激活状态并显示在手机屏幕上,而暂停其他处于未激活状态的程序因此,Android系统需要一种后台服务机制,允许在没有用户界面的情况下,使程序能够长时间在后台运行,实现应用程序的后台服务功能,并能够处理事件或数据更新7.1Service简介ServiceAndroid系统提供的Service(服务)组件,不直接与用户进行交互,能够长期在后台运行在实际应用中,有很多应用需要使用Service,经常提到的例子就是MP3播放器,软件需要在关闭播放器界面后,仍能够保持音乐持续播放,这就需要在Service组件中实现音乐回放功能7.1Service简介ServiceService适用于无需用户干预,且规则或长期运行的后台功能首先,因为Service没有用户界面,更加有利于降低系统资源的消耗,而且Service比Activity具有更高的优先级,因此在系统资源紧张时,Service不会被Android系统优先终止即使Service被系统终止,在系统资源恢复后Service也将自动恢复运行状态,因此可以认为Service是在系统中永久运行的组件Service除了可以实现后台服务功能,还可以用于进程间通信(InterProcessCommunication,IPC),解决不同Android应用程序进程之间的调用和通讯问题7.1Service简介Service生命周期Service生命周期包括完全生命周期活动生命周期onCreate()事件回调函数:Service的生命周期开始,完成Service的初始化工作onStart()事件回调函数:活动生命周期开始,但没有与之对应的“停止”函数,因此可以近似认为活动生命周期也是以onDestroy()标志结束onDestroy()事件回调函数:Service的生命周期结束,释放Service所有占用的资源调用startService()启动ServiceonCreate()onStart()Service正在运行Service被停止onDestroy()关闭Service7.1Service简介Service生命周期Service生命周期包括完全生命周期活动生命周期还有三个事件回调函数,分别是onCreate()、onStart()和onDestroy(),如下图所示调用startService()启动ServiceonCreate()onStart()Service正在运行Service被停止onDestroy()关闭Service7.1Service简介Service生命周期Service生命周期包括完整生命周期从onCreate()开始到onDestroy()结束,在onCreate()中完成Service的初始化工作,在onDestroy()中释放所有占用的资源活动生命周期从onStart()开始,但没有与之对应的“停止”函数,因此可以粗略的认为活动生命周期是以onDestroy()标志结束Service的使用方式一般有两种启动方式绑定方式7.1Service简介启动方式通过调用Context.startService()启动Service,通过调用Context.stopService()或Service.stopSelf()停止Service。因此,Service一定是由其它的组件启动的,但停止过程可以通过其它组件或自身完成在启动方式中,启动Service的组件不能够获取到Service的对象实例,因此无法调用Service中的任何函数,也不能够获取到Service中的任何状态和数据信息能够以启动方式使用的Service,需要具备自管理的能力,而且不需要从通过函数调用获取Service的功能和数据7.1Service简介绑定方式Service的使用是通过服务链接(Connection)实现的,服务链接能够获取Service的对象实例,因此绑定Service的组件可以调用Service中实现的函数,或直接获取Service中的状态和数据信息使用Service的组件通过Context.bindService()建立服务链接,通过Context.unbindService()停止服务链接如果在绑定过程中Service没有启动,Context.bindService()会自动启动Service,而且同一个Service可以绑定多个服务链接,这样可以同时为多个不同的组件提供服务7.1Service简介启动方式和绑定方式的结合这两种使用方法并不是完全独立的,在某些情况下可以混合使用以MP3播放器为例,在后台的工作的Service通过Context.startService()启动某个音乐播放,但在播放过程中如果用户需要暂停音乐播放,则需要通过Context.bindService()获取服务链接和Service对象实例,进而通过调用Service对象实例中的函数,暂停音乐播放过程,并保存相关信息在这种情况下,如果调用Context.stopService()并不能够停止Service,需要在所有的服务链接关闭后,Service才能够真正的停止7.2本地服务本地服务的调用者和服务都在同一个程序中,是不需要跨进程就可以实现服务的调用本地服务涉及服务的建立、启动和停止,服务的绑定和取消绑定,以及如何在线程中实现服务7.2.1服务管理服务管理主要指服务的启动和停止首先说明如何在代码中实现Service。Service是一段在后台运行、没有用户界面的代码,其最小代码集如下7.2本地服务本地服务的调用者和服务都在同一个程序中,是不需要跨进程就可以实现服务的调用本地服务涉及服务的建立、启动和停止,服务的绑定和取消绑定,以及如何在线程中实现服务7.2.1服务管理服务管理主要指服务的启动和停止首先说明如何在代码中实现Service。Service是一段在后台运行、没有用户界面的代码,其最小代码集如下7.2本地服务7.2.1服务管理7importandroid.app.Service;8importandroid.content.Intent;9importandroid.os.IBinder;1011publicclassRandomServiceextendsService{12@Override13publicIBinderonBind(Intentintent){14returnnull;15}16}7.2本地服务7.2.1服务管理除了在第1行到第3行引入必要包外,仅在第5行声明了RandomService继承了android.app.Service类,在第7行到第9行重载了onBind()函数onBind()函数是在Service被绑定后调用的函数,能够返回Service的对象实例7.2本地服务7.2.1服务管理这个Service最小代码集并没有任何实际的功能,为了使Service具有实际意义,一般需要重载onCreate()、onStart()和onDestroy()。Android系统在创建Service时,会自动调用onCreate(),用户一般在onCreate()完成必要的初始化工作,例如创建线程、建立数据库链接等在Service关闭前,系统会自动调用onDestroy()函数释放所有占用的资源。通过Context.startService(Intent)启动Service,onStart()则会被调用,重要的参数通过参数Intent传递给Service当然,不是所有的Service都需要重载这三个函数,可以根据实际情况选择需要重载的函数7.2本地服务7.2.1服务管理1publicclassRandomServiceextendsService{2@Override3publicvoidonCreate(){4super.onCreate();5}6@Override7publicvoidonStart(Intentintent,intstartId){8super.onStart(intent,startId);9}10@Override11publicvoidonDestroy(){12super.onDestroy();13}14}7.2本地服务7.2.1服务管理1publicclassRandomServiceextendsService{2@Override3publicvoidonCreate(){4super.onCreate();5}6@Override7publicvoidonStart(Intentintent,intstartId){8super.onStart(intent,startId);9}10@Override11publicvoidonDestroy(){12super.onDestroy();13}14}7.2本地服务7.2.1服务管理重载onCreate()、onStart()和onDestroy()三个函数时,务必要在代码中调用父函数,如代码的第4行、第8行和第12行完成Service类后,需要在AndroidManifest.xml文件中注册这个Service注册Service非常重要,如果开发人员不对Service进行注册,则Service根本无法启动AndroidManifest.xml文件中注册Service的代码如下1serviceandroid:name=.RandomService/使用service标签声明服务,其中的android:name表示Service类的名称,一定要与建立的Service类名称一致7.2本地服务7.2.1服务管理在完成Service代码和在AndroidManifest.xml文件中注册后,下面来说明如何启动和停止Service。有两种方法启动Service,显式启动和隐式启动显式启动需要在Intent中指明Service所在的类,并调用startService(Intent)启动Service,示例代码如下1finalIntentserviceIntent=newIntent(this,RandomService.class);2startService(serviceIntent);在上面的代码中,Intent指明了启动的Service所在类为RandomSerevice7.2本地服务7.2.1服务管理隐式启动则需要在注册Service时,声明Intent-filter的action属性1serviceandroid:name=.RandomService2intent-filter3actionandroid:name=edu.hrbeu.RandomService/4/intent-filter5/service7.2本地服务7.2.1服务管理在隐式启动Service时,需要设置Intent的action属性,这样则可以在不声明Service所在类的情况下启动服务。隐式启动的代码如下1finalIntentserviceIntent=newIntent();2serviceIntent.setAction(edu.hrbeu.RandomService);如果Service和调用服务的组件在同一个应用程序中,可以使用显式启动或隐式启动,显式启动更加易于使用,且代码简洁。但如果服务和