在一个应用程序中, 我们通过 AndroidManifest.xml 中的 <service> 配置服务, 注意它跟<Activity> 是同级的.
<manifest .....> <application ....> <activity ..> ........... </activity> <activity ..> ........... </activity> <service android:name=".CountService" /> <service ...> <intent-filter> .......... </intent-filter> </service> </application> </manifest>
在同一个应用程序中, 每个 Activity 和 Service 都是在 Main Thread 中运行的, 不存在多开一个线程(自己写个例子, 调试一下就很清楚了). 当然, 如果Service 里面的操作是耗时长的, 那在Service 里面手动开多一条线程执行这些耗时长的操作. 还有另一个办法是使用 IntentService 类, 它是Service 类的子类, 拥有自己的线程.
虽然是 Service 运行时是看不到界面的, 但是它有两个方法 startForeground(int, Notification) 和 stopForeground (boolean) (1.5才有的)分别设置 Service 的 前台状态和取消 Service 的前台状态. 可能你会说了, Service 不是没有界面吗, 那什么是他的前台呢? 通过 Notification 对象, 我们可以把在前台的 Service 显示在状态栏上. 前台到后台, 就是一个优先级的变化, 优先级低的, 在资源不足的情况下, 很有可能给杀掉.
在应用程序中, 如果它启动了一些Service, 在Service 没停止前, 应用程序是关闭不了的. 我测试的时候是这种情况.
Service 有两种生命周期, 这两种生命周期是通过不同的方式启动的
多次调用 startService() 是不违法的(但是此举将导致 onStartCommand() 会被多次调用), 不管调用多少次startService () ,只需要调用一次 stopService () 或 stopSelf() 就可以停止service .
Services 可以使用 stopSelf(int startId) 来确保自己不会被停止, 直到 startId 对应的Intent 被处理.
如果没有startService,而调用stopservice不会出错.
如果没有bindservice而调用unbindservice就会出错.
他们的一些用途
刚开始, 看了网上广为流传的 CountService 例子和官方的 LocalService 等例子, 看 CountService 例子前部分, 我觉得使用 Service 很简单. 但是转到中间部分, 多了接口, 多个 binder 类, 多个什么connection, 代码一下子多了很多, 像我这种能力低下的人一看, 傻眼了.
ICountService 出现了, CountService 实现它, ServiceBinder也实现它! 咋那么眼熟呢? 代理模式?????? serviceConnection服务连接, 哇, 难道跟数据库一样, 建立连接再操作吗?
带着疑问, 在看看官方的例子, LocalService 用于startService 和 bindService, 它的 onBind() 返回了一个 Binder对象, 这里没有用到接口, 第一个疑问算是解开了! LocalService 例子的 ServiceConnection 对象没做啥操作, 但是在它的 onServiceConnected() 方法竟然把 LocalService 对象传了过来, 有点乱来呢! 再看回 CountService 的例子, ServiceConnection 对象 的 onServiceConnected() 方法竟然也把 CountService 对象传了过来, 再看清一点, 原来不是 CountService 对象, 是接口 ICountService 的实现对象.
到这里有点豁然开朗了, Binder 对象是Service 和 Activity 交互中Service的信息和服务的提供者, 而 ServiceConnection 对象是 Service 和 Activity交互的一条连接通道, 它提供了一个地方--onServiceConnected 让两个组件进行交互, 并定义其交互规则.
把 Binder 和 ServiceConnection 类的作用搞清楚后, 把这两者过滤一下, 我们发现startService 和 bindService 其他地方基本都一样了.
bindService很像观察者模式 , 被观察者是Service, Binder对象是其notifyObservers(Object arg)方法中的参数;观察者是Activity, ServiceConnection 发挥了update()方法的功能, Context.bindService() 方法等同于 被观察者.addObserver(Observer o).
跟传统观察者模式不同的地方是, 这里是观察者主动去观察, 而不是被动观察. 再想想, 如果需要被动观察的效果, 又要怎么做呢?
ServiceConnection 的回调方法onServiceDisconnected() 在连接正常关闭的情况下是不会被调用的, 该方法只在Service 被破坏了或者被杀死的时候调用. 例如, 系统资源不足, 要关闭一些Services, 刚好连接绑定的 Service 是被关闭者之一, 这个时候 onServiceDisconnected() 就会被调用.