Android把生命周期传给sdk,Android开发者指南 -Bound服务

Android服务可以是started和bound的,允许在后台运行并与其他组件交互。当同时支持这两种类型时,服务不会在所有客户端解绑后自动停止,需要手动调用stopSelf()或stopService()。服务通过实现onBind()返回IBinder接口供客户端绑定,bindService()用于建立连接。多个客户端可以绑定到同一服务,首次绑定时调用onBind(),后续绑定则重用相同的IBinder。服务接口可以通过Binder、Messenger或AIDL实现,其中Binder适用于同一进程,Messenger适合跨进程,而AIDL用于更复杂的跨进程通信。定义服务接口是实现bound服务的核心工作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

绑定到一个started服务

正如 Services 一文中所述,你可以创建一个同时支持started和bound的服务。也就是说,服务可以通过调用 startService() 来启动,这使它一直保持运行,同时它也允许客户端通过调用 bindService() 来与之绑定。

如果你的服务确实可以是started和bound的,那么服务启动后,系统将不会在所有客户端解除绑定时销毁它。取而代之的是,你必须通过调用 stopSelf() 或 stopService() 显式终止此服务。

虽然你通常应该要实现 onBind() 或 onStartCommand() 中的一个,但有时需要同时实现两者。 比如,音乐播放器的服务也许就需要同时实现后台运行和支持绑定。 这样,activity就可以启动服务来播放音乐,并且音乐会一直播放下去,即使用户离开该应用程序也没关系,这个activity可以绑定播放服务来重新获得播放控制权。

请确保已经阅读了 管理Bound服务的生命周期 章节,以获取更多向started服务添加绑定时的服务生命周期的有关信息。

bound服务是 Service 类的一种实现,它允许其它应用程序与其绑定并交互。为了让服务支持绑定,你必须实现 onBind() 回调方法。这个方法返回一个 IBinder 对象,此对象定义了客户端与服务进行交互时所需的编程接口。

客户端可以通过调用 bindService() 方法来绑定服务。在调用时,必须提供一个 ServiceConnection 的实现代码,用于监控与服务的联接。 bindService() 将会立即返回,没有返回值。但是Android系统在创建客户端与服务之间的联接时,会调用 ServiceConnection 中的 onServiceConnected() 方法,传递一个 IBinder ,客户端将用它与服务进行通信。

多个客户端可以同时联接到一个服务上。不过,只有在第一个客户端绑定时,系统才会调用服务的 onBind() 方法来获取 IBinder 。然后,系统会向后续请求绑定的客户端传送这同一个 IBinder ,而不再调用 onBind() 。

当最后一个客户端解除绑定后,系统会销毁服务(除非服务同时是通过 startService() 启动的)。

当你实现自己的bound服务时,最重要的工作就是定义 onBind() 回调方法所返回的接口。定义服务 IBinder 接口的方式有好几种,后续章节将会对每种技术进行

创建一个支持绑定的服务时,你必须提供一个 IBinder ,用作客户端和服务间进行通信的编程接口。定义这类接口的方式有三种:

1、扩展Binder类

如果服务是你的应用程序所私有的,并且与客户端运行于同一个进程中(通常都是如此),你应该通过扩展 Binder 类来创建你的接口,并从 onBind() 返回一个它的实例。客户端接收该 Binder 对象并用它来直接访问 Binder 甚至 Service 中可用的公共(public)方法。

如果你的服务只是为你自己的应用程序执行一些后台工作,那这就是首选的技术方案。不用这种方式来创建接口的理由只有一个,就是服务要被其它应用程序使用或者要跨多个进程使用。

2、使用Messenger

如果你需要接口跨越多个进程进行工作,可以通过 Messenger 来为服务创建接口。在这种方式下,服务定义一个响应各类消息对象 Message 的 Handler 。此 Handler 是 Messenger 与客户端共享同一个 IBinder 的基础,它使得客户端可以用消息对象 Message 向服务发送指令。此外,客户端还可以定义自己的 Message ,以便服务能够往回发送消息。

这是执行进程间通信(IPC)最为简便的方式,因为 Messenger 会把所有的请求放入一个独立进程中的队列,这样你就不一定非要把服务设计为线程安全的模式了。

3、使用AIDL

Android接口定义语言AIDL(Android Interface Definition Language) 完成以下的所有工作:将对象解析为操作系统可识别的原始形态,并将它们跨进程序列化(marshal)以完成IPC。 前一个使用 Messenger 的方式,实际上也是基于AIDL的,它用AIDL作为底层结构。如上所述, Messenger 将在一个单独的进程中创建一个包含了所有客户端请求的队列,这样服务每次就只会收到一个请求。 可是,如果想让你的服务能同时处理多个请求,那你就可以直接使用AIDL。 这种情况下,你的服务必须拥有多线程处理能力,并且是以线程安全的方式编写的。

要直接使用AIDL,你必须创建一个.aidl文件,其中定义了编程的接口。 Android SDK 工具使用此文件来生成一个抽象类(abstract class),其中实现了接口及对IPC的处理,然后你就可以在自己的服务中扩展该类。

注意: 绝大多数应用程序都不应该用AIDL来创建bound服务,因为这可能需要多线程处理能力并且会让代码变得更为复杂。 因此,AIDL对绝大多数应用程序都不适用,并且本文也不会讨论如何在服务中使用它的内容。如果你确信需要直接使用AIDL,那请参阅 AIDL 文档。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值