翻译一下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