Service
被设计为不和用户直接交互,在后台执行长期操作的一种系统组件,也可被其它应用使用。每一个服务必须在AndroidManifest中声明。服务可以通过Context.startService() and Context.bindService().启动。Note:service运行在主线程,因此执行网络操作需要另起线程,但IntentService可以解决这个问题。
What is a Service?
首先,我们来说说服务不是什么:
1:服务不是一个单独的进程,通常情况下它运行在应用进程的一部分
2.服务不是线程,它不能在应用无响应时工作
下面来说说服务两个主要的特征:
1.很方便的通知系统,我有一些后台任务需要处理,直到明确停止服务
2.很方便的给其它应用提供功能
Note:因为服务很简单,所以我们可以以任何我们想交互的方式来设计一个服务。我们可以将服务看成一个可以随时调用它方法的普通的Java对象,通过AIDL来交互。
Service Lifecycle
服务可以通过两种方式启动。如果有人调用了Context.startService(),那么服务的oncreate()和onStartCommand(Intent, int, int)会被回调,不管执行多少次startService,服务都不会重新创建,而会多次调用onStartCommand,所以并不存在停止不了服务的情况。服务会持续下去直到Context.stopService() or stopSelf()被调用。onStartCommand返回的不同值对应不同的服务需要。
用户还可以通过Context.bindService()来持有一个服务连接。当服务没运行的时候将会调用oncreate方法,但不会调用onStartCommand方法。客户端会接收到服务onBind(Intent)方法回调的IBinder对象,允许客户端回调服务里面的方法。通常情况下,IBinder是由复杂的接口创建的。
上述两种启动方式可以同时存在
Permissions
当一个服务在清单文件中声明,全局访问它将会拒绝。这时需要在自己的清单文件中声明合适的权限来启动,停止和绑定特定的服务。以Android 2.3为例,当调用Context.startService(Intent),我们也需要设置Intent.FLAG_GRANT_READ_URI_PERMISSION and/or Intent.FLAG_GRANT_WRITE_URI_PERMISSION。
这会暂时同意Service访问Intent指定的Uri,直到服务停止。这个对Service没有exported也同样适用。
Process Lifecycle
Android系统会尽可能长的保留持有service的进程,但是当内存不足需要杀掉一些进程时,有如下的优先级:
1.当前服务正在回调onCreate(), onStartCommand(), or onDestroy()方法,则视为前台进程,不会被kill
2.当服务长期运行在后台时,有极高的可能性被kill
3.我们可以通过startForeground(int, Notification)来设置前台进程,除非在内存极端紧张下,否则不会被杀
Note 有很大的可能,一个正在运行的服务在内存不足时会被系统杀掉,但是被杀掉后,系统会稍后试着重启这个服务。我们可以在onStartCommand()方法用START_FLAG_REDELIVERY回调一个Intent来继续执行我们的服务