以下内容整理自互联网,仅用于个人学习
1. 什么是服务
服务是Android中实现程序后台运行的解决方案,是一个应用程序组件,它能够在后台执行一些耗时较长的操作,它非常适用于去执行那些不需要和用户交互而且要求长期运行的任务。服务不依赖与任何用户界面,即时当程序被切换到后台,或者用户打开另一个应用程序,服务仍然能够保持正常运行。
2. 服务与线程的区别
如果你需要在主线程之外执行一些工作,但仅当用户与你的应用程序交互时才会用到,那你应该创建一个新的线程而不是创建服务。 比如,如果你需要播放一些音乐,但只是当你的activity在运行时才需要播放,你可以在onCreate()中创建一个线程,在onStart()中开始运行,然后在onStop()中终止运行。还可以考虑使用AsyncTask或HandlerThread来取代传统的Thread类。
3. 服务的分类
按运行状态分类可分为两类:前台服务和后台服务
前台服务是指那些经常会被用户关注的服务,因此内存过低时它不会成为被杀的对象。 前台服务必须提供一个状态栏通知,并会置于“正在进行的”(“Ongoing”)组之下。这意味着只有在服务被终止或从前台移除之后,此通知才能被解除。
要把服务设置为前台运行,可以调用startForeground()方法。
要从前台移除服务,可以调用stopForeground()方法。
按使用分类可分为两类:本地服务和远程服务
本地服务用于应用程序内部,实现一些耗时任务,并不占用应用程序所属线程,而是单开线程后台执行。
远程服务用于Android系统内部的应用程序之间,可被其他应用程序复用,比如天气预报服务,其他应用程序不需要再写这样的服务,调用已有的即可。可以定义接口并把接口暴露出来,以便其他应用进行操作。
4. Service生命周期
Service生命周期.pngonStartCommand()的返回值必须是以下常量之一:
-
START_NOT_STICKY:如果系统在onStartCommand()返回后杀死了服务,则不会重建服务了,除非还存在未发送的intent。 当服务不再是必需的,并且应用程序能够简单地重启那些未完成的工作时,这是避免服务运行的最安全的选项.
-
START_STICKY:如果系统在onStartCommand()返回后杀死了服务,则将重建服务并调用onStartCommand(),但不会再次送入上一个intent, 而是用null intent来调用onStartCommand() 。除非还有启动服务的intent未发送完,那么这些剩下的intent会继续发送。 这适用于媒体播放器(或类似服务),它们不执行命令,但需要一直运行并随时待命。
-
START_REDELIVER_INTENT:如果系统在onStartCommand()返回后杀死了服务,则将重建服务并用上一个已送过的intent调用onStartCommand()。任何未发送完的intent也都会依次送入。这适用于那些需要立即恢复工作的活跃服务,比如下载文件。
5. startService
这类服务由其它组件调用startService()来创建,然后保持运行,且必须通过调用stopSelf()自行终止。其它组件也可通过调用stopService() 终止这类服务。服务终止后,系统会把它销毁。
如果一个Service被startService 方法多次启动,那么onCreate方法只会调用一次,onStart将会被调用多次(对应调用startService的次数),并且系统只会创建Service的一个实例(因此你应该知道只需要一次stopService调用)。该Service将会一直在后台运行,而不管对应程序的Activity是否在运行,直到被调用stopService,或自身的stopSelf方法。当然如果系统资源不足,android系统也可能结束服务。
Intent intent = new Intent(this, MyService.class);
startService(intent);
6. bindService
服务由其它组件(客户端)调用bindService()来创建。然后客户端通过一个IBinder接口与服务进行通信。客户端可以通过调用unbindService()来关闭联接。多个客户端可以绑定到同一个服务上,当所有的客户端都解除绑定后,系统会销毁服务。(服务不需要自行终止。)
如果一个Service被某个Activity 调用 Context.bindService 方法绑定启动,不管调用 bindService 调用几次,onCreate方法都只会调用一次,同时onStart方法始终不会被调用。当连接建立之后,Service将会一直运行,除非调用Context.unbindService 断开连接或者之前调用bindService 的 Context 不存在了(如Activity被finish的时候),系统将会自动停止Service,对应onDestroy将被调用。
Intent intent=new Intent(this,BindService.class);
bindService(intent, ServiceConnection conn, int flags)
服务绑定的Flag:
-
Context.BIND_AUTO_CREATE:表示收到绑定请求的时候,如果服务尚未创建,则即刻创建,在系统内存不足需要先摧毁优先级组件来释放内存,且只有驻留该服务的进程成为被摧毁对象时,服务才被摧毁
-
Context.BIND_DEBUG_UNBIND:通常用于调试场景中判断绑定的服务是否正确,但容易引起内存泄漏,因此非调试目的的时候不建议使用
-
Context.BIND_NOT_FOREGROUND:表示系统将阻止驻留该服务的进程具有前台优先级,仅在后台运行。
6. 在AndroidManifest文件中声明服务
以上的服务都需要在AndroidManifest文件中声明
<manifest ... >
...
<application ... >
<service android:name=".ExampleService" ></service>
...
</application>
</manifest>
- android:name:服务类名(唯一必须的属性)
- android:label:服务的名字,如果此项不设置,那么默认显示的服务名则为类名
- android:icon:服务的图标
- android:permission:申明此服务的权限,这意味着只有提供了该权限的应用才能控制或连接此服务
- android:process:表示该服务是否运行在另外一个进程,如果设置了此项,那么将会在包名后面加上这段字符串表示另一进程的名字
- android:enabled:如果此项设置为 true,那么 Service 将会默认被系统启动,不设置默认此项为 false
- android:exported:表示该服务是否能够被其他应用程序所控制或连接,不设置默认此项为 false
网友评论