Service 详解

翻译一下Service.java的API文档----哎哟,我去,公司终于可以发文章了

 

简介

service是应用相关组件,主要用于应用要做一个长时间运行的动作,或者不需要跟用户交互或为其他应用提供功能。每一个service,都必须在AndroidManafest.xml中定义,

一个service,通过Context.startService()或Context.bindService()被启动。

 

service在main thread中运行,这意味着service,可以做CPU密集型操作(MP3后台播放)或阻塞操作(比如网络操作),service可以自己创建线程去完成它的任务。

更新信息,可以在 ApplicationFundamentals:Processes and Threads中找到。比如IntentService.java是一个标准的利用它自己的线程去实现其功能的service实现类

主题

1. 什么是service

2. service生命周期

3. permissions

4. Process生命周期

5. 本地 service 范例

6. 远程信息service范例

 

一、什么是service

大多数关于service的疑问都围绕着它不是什么

1. 服务不是一个单独的进程。服务对象本身并不意味着它在自己的进程中运行。除非有其他说明,它同在一个进程中运行,作为应用程序的一部分。

2. 服务不是线程。它不可以脱离主线程进行工作的(以避免应用程序无响应错误)

 

其实服务本身很简单,它只提供了两个主要功能:

1. 应用要在后台做什么事情(甚至用户并没有跟应用直接交互)。这就调用Context.startService(),这要求系统安排工作,直到运行到service或者人为的停止

2. 将其一部分功能应用到其他应用上。这就调用Context.bindService()。这允许长时间保持连接为了服务与它交互。

 

当service组件被创建之后,不管是通过bindService或者startService创建的,系统都将会实例化service,并调用onCreate,以及其他适当的回调。这取决于service实现了什么样的功能行为,比如创建一个在service内部创建了二级线程

 

注意:service本身是简单,你可以用local java object来对待它,或者通过aidl远程调用这种复杂的方式。

二、service生命周期

service的运行有两种方式。Context.startService()或者Context.bindService().

1.Context.startService:系统将会取回service(这可能会创建它同时调用onCreate()方法),然后调用onStartCommand(Intent,int, int)方法(参数由客户端提供)。service会一直运动到Context.stopService()或stopSErlf()被调用。

注意:多次调用Context.startService不会启动多个service,但是这会多次调用onStartCommand(),一旦Context.stop()或stopSelf()被调用,就会立即停止service。

stopSelf()会保证onStartCommand中的方法被执行完毕,才会停止service。

在启动service后,service主要有两种操作模式,这取决于onStartCommand的返回值。

START_STICKY:显式开启关闭service

START_NOT_STICKY|START_REDELIVER_INTENT:用于仅在接受到的指令时才运行。

 

2.Context.bindService:这会获得一个长久的连接服务。如果service没在运行(那会调用onCreate),但不会调用onStartCommand。service会通过onBind(Intent)函数返回一个IBinder给客户端,这允许客户端做一些连接创建后的回调。只要连接被建立,ervice会保持运行(不管客户端还是否保留服务的IBinder)。通常IBinder会被写在一个复杂的interface  AIDL中。

 

service可以同时被started和有多个跟它相连的连接。在这种情况下,只要它被started有一个或多个用Context.BIND_AUTO_CREATE标签的连接,service会一直运行。一旦不存在连接或被stop,系统最终会调用onDestroy(),这样service就正式有效终止。所有的清理动作(stopping threads, unregisteringreceivers)应该在onDestroy之前被处理。

Permissions

全局访问一个service,需要在manifest中定义<service>标签。其他应用需要添加相应的<uses-permission>。

在android2.3版本中,若使用Context.startService(),需要同时设置intent的flag成Intent.FLAG_GRANT_READ_URI_PERMISSION and/orIntent.FLAG_GRANT_WRITE_URI_PERMISSION。

这会给让service有暂时访问指定URI的权限。权限会一直保持到service调用stopSelf,或者一直到service完全被系统停止。

这种方式可以给予对其他apps中未添加permission保护的service的访问权限(even when the service is not exported at all)。

 

此外,通过调用checkcallingpermission(string),service可以限制个别IPC 对它的调用权限。

进程优先级

android系统会一直保持 持有service的进程运行,只要service一直被启动或者有客户端接连上。当内存不足需要杀进程时,持有service的进程的有以下几种可能。

1. 如果service正在执行onCreate,onStartCommand,onDestory函数,这进程会被确保执行完毕

 

2. service已被启动,但优先级比正与用户交互的可见进程低,比不可见的进程高。那么,这个进程就不应该被killed,除非达到extreme low memory的情况

 

3. 如果客户端绑定上来service,那么持有service的进程就跟最重要的进程一样重要,因为只要有一个客户端是可见的,service就应该被视为可见的

 

4. 当系统考虑将service是活跃的同时不是可杀的候选进程,那么已启动的service可以用startForeground函数将service改成前显得状态。(在极端的情况下,这样也仍有可能被杀掉)

 

注意:在内存压力比较大的时候,即便service大多数时间在运行的,也会被杀掉。如果发生这种情况,系统会稍后尝试重新启动service。如果你正在onStartCommand()中安排任务,那么你就可能需要添加START_FLAG_REDELIVERY让系统在重新启动service再次派发这个intent。这样确保service在执行这个intent指令时被杀掉后还能重新执行。

其他的应用组件(比如Activity)也会增加整个进程的重要性。

 

本地Service范例

service其中一种比较常用的典型方法就是应用程序的辅助组件。APK的所有组件都运行在同一个进程中,除非另有明确规定。

采用这种方式,会大大简化应用程序组件之间的交互复杂性:app的组件可以通过IBinder轻松的交互。

 

这种方式的ser

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值