Android四大组件之Service

一.定义


Service 是一个可以在后台执行长时间运行操作而不是提供用户界面的应用组件.

二.类型


启动服务

-通过调用startService()启动服务,一旦启动,服务将在后台无限期运行,即使启动服务的组件销毁,服务在任务完成后,将自动停止运行

绑定服务

- 通过调用bindService()绑定到服务,绑定服务提供了一个客户端-服务器接口,允许组件与服务进行交互.

- 只有当与另一个组件绑定时,服务才会运行.多个组件可以同时绑定到该服务. 但全部取消绑定后,改服务会被销毁

服务可以同时以这两种方式运行,关键在于是否实现了这两个回调方法
- onStartCommand() 允许组件启动服务
- onBind() 允许绑定服务

清单文件声明服务


  1. android:exported 属性并将其设置为 “false”.可以保证服务被本应用私有.

创建启动服务


可以扩展下面两个类来创建启动服务

Service

- 适用于所有服务的基类. 必须创建一个用于执行所有服务工作的新线程.
- 默认时,服务使用的是应用的主线程,会降低性能.

IntentService

- Service的子类,使用工作线程逐一处理所有启动请求.适用于单个请求.
- 需实现onHnadleIntent()方法, 该方法接受每个启动请求的intent.

扩展IntentService类 (适合单线程)##

- 创建默认的工作线程,在应用的主线程外执行传递给onStartCommand()的所有Intent

- 创建工作队列, 将intent逐一传递给onHandleIntent实现.避免了多线程

- 处理完所有启动请求后自动停止服务.

- 提供 onBind() 的默认实现(返回null)

- 提供onStartCommand()的默认实现,可将intent依次发送到工作队列和 onHandleIntent实现.

扩展Service类 (可以执行多线程)

- onStartCommand() 方法必须返回整数型.

返回值类型

1.START_NOT_STICKY
  如果系统在onStartCommand()返回后终止服务,除非有挂起Intent要传递,否则系统不会重建服务.

2.START_STICKY
  如果系统在onStartCommand()返回后终止服务,则会重建服务并调用onStartCommand(),但不会重新传递最后一个Intent.
  - eg:
	   不执行命令,但无限期运行并等待作业的媒体播放器(或类似服务)

3.START_REDELIVER_INTENT
  如果系统在onStartCommand()返回后终止服务,则会重建服务,并通过传递给服务的最后一个Intent调用onStartCommand(). 任何挂起的Intent 均依次传递

启动服务


- 可以通过 Intent传递给 startService(),显示启动.然后安卓系统调用服务的onStartCommand()方法,并向其传递Intent

- 如果服务未提供绑定, 并且我们希望服务返回结果. 启动的客户端可以为广播创建一个PendingIntent,并通过启动服务的Intent传递给服务.

停止服务


- 调用stopSelf()自动停止运行,或者另一个组件调用stopService()来停止

创建绑定服务


- 通过bindService()与其绑定,创建长期连接.

- 必须实现onBind()的回调方法以返回IBinder,用于定义与服务通信的接口. 其他应用组件可以调用bindService()来检索该接口,然后对服务调用方法.

可以过三种方式定义接口

扩展Binder类

如果服务只是供自己的自有应用专用,并且在与客服端相同的进程中运行,那么就可以通过扩展Binder类并从onBind()返回它的一个实例来创建接口.

使用Messenger

- 执行进程间通信(IPC)需求的时候,可以用Messenger为服务创建接口.

- 服务可以用这种方式对应于不同类型Message对象的Handler.

- IPC最简单的方法,因为Messenger会在单一线程中创建包含所有请求的队列,可以避免对服务进行线程安全设计.

- 底层实现是AIDL

使用AIDL

- AIDL(Android接口定义语言) 执行所有将对象分解成原语的工作,操作系统可以识别这些原语并将它们编组到各进程中,以执行IPC.

- 可以让服务同时处理多个请求, 服务必须具备多线程处理能力,并才哟个线程安全设计模式.

- AIDL, 要先创建一个定义编程接口的.aidl文件. Android SDK 工具利用该文件生成一个实现接口并处理IPC的抽象类, 然后我们可以在服务内对抽象类进行扩展.

第一种 扩展Binder类


推荐使用场景:

当服务仅供本地应用使用,不需要跨进程工作,那就可以实现Binder类, 让客户端可以通过该类直接调用服务里的方法.

步骤

1. 在服务中,创建满足下列任意一个要求的Binder实例
	(1) 包含客户端可调用的公共方法
	(2) 返回当前Service实例,其中包含客户端可调用的公共方法
	(3) 或返回由服务承载的其他类的实例, 其中包含客户端可调用的公共方法

2. 从 onBinder() 回调方法中返回此Binder实例

3. 在客户端中, 从 onServiceConnected() 回调方法中接受Binder, 并使用提供的方法调用绑定服务.

第二种 使用Messenger类


优势

1. 比AIDL 实现更简单, Messenger会把所有服务调用排入队列依次执行,而 AIDL接口会同时向服务发送多个请求. 
2. 也就是说Messenger是单线程, AIDL是多线程.

步骤

1. 服务实现一个Handler, 来接受客户端的每个调用的回调.
2. Handler 用于创建Messenger对象(持有对Handler的引用)
3. Messenger 创建一个IBinder, 服务通过 onBinder() 使其返回客户端.
4. 客户端使用IBinder 将Messenger(引用服务的Handler)实例化,然后使用 handler将Message对象发送给服务.
5. 服务在Handler的 handleMessage()中接受每个Message.

绑定到服务


**广播接收器无法绑定到服务**

绑定服务步骤

1. 实现 ServiceConnection, 实现类必须重写两个回调方法:
	(1) onServiceConnected()
		系统会调用此方法传递服务的onBind()方法返回的IBiner
	(2) onServiceDisconnected()
		Android系统会在与服务的连接意外中断时调用该方法. 

2. 调用binderService(), 传递ServiceConnection实现.
3. 当系统开始调用 onServiceConnected()回调方法时, 可以直接使用接口定义的方法开始调用.
4. 使用 unbindService()来断开与服务的连接.

绑定服务重要说明


1.应该始终捕获 DeadObjectException 异常,它们是在连接中断时引发的。这是远程方法引发的唯一异常

2.对象是跨进程计数的引用.

3.您通常应该在客户端生命周期的匹配引入 (bring-up) 和退出 (tear-down) 时刻期间配对绑定和取消绑定.

管理绑定服务的生命周期


两种服务的生命周期


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值