分类:C#、Android、VS2015;

创建日期:2016-03-03

一、Bound Services—被绑定的服务

1、什么是Bound Service

Bound Service是指通过接口将Android的组件(比如某个Activity)和某个Service绑定在一起,这是一种类似于C/S的通信机制,组件Activity是客户端(调用服务),Service是服务端(提供服务)。

一旦定义了客户端和服务之间绑定的接口,客户端就可以利用该接口向服务端发送服务请求,并接收服务端响应的结果。另外,利用消息传递机制,还可以实现不同进程之间的通信(IPC)。

Bound Services与Started Service的主要区别是:Bound Services中的Service不会无限期地在后台持续运行(客户端建立连接时创建服务,客户端断开连接时销毁服务),而Started Service中的Service则可以无限期地在后台持续运行。

一旦将客户端的Activity和服务端的Service绑定在一起,这种被绑定的Service就有了自己的生命周期。

2、Bound Services的生命周期

下图说明了Bound Services的生命周期以及自动调用的方法。

从图中可以看出,在Bound Service的完整生存期期间,也是开始时调用OnCreate()方法,结束时调用OnDestroy()方法。与activity类似,服务可以在重写(override)的OnCreate()方法中完成初始设置工作,并在重写的OnDestroy()方法中释放所有未释放的资源。例如,一个音乐播放服务可以在OnCreate()中创建音乐播放线程,而在OnDestroy()中终止该线程。

总之,只要将客户端和服务绑定在一起,不论是用StartService()创建的服务(Started Service),还是用BindService()创建的服务,这些服务都会调用OnCreate()和OnDestroy()方法。

在这些回调方法中,最常用的是OnBind()和OnUnBind(),含义如下:

  • OnBind()方法:用于返回绑定的实例,当客户端与服务建立绑定时系统会自动调用此方法,然后客户端就可以通过该方法返回的实例访问服务了。
  • OnUnbind()方法:当客户端取消与服务的绑定时系统会自动调用此方法。如果该方法返回true,表示该服务可被重新绑定;否则(返回false)表示该方法什么事都没做。

二、Bound Service和Started Service的区别

从Bound Service的生命周期可以看出,在Service的生命周期管理中,Bound Service与Started Service明显不同。

这些区别有:

1、创建和销毁的方式不同

Started Service由其它组件调用StartService()方法来创建,然后该Service就可以保持运行了,而且必须通过它自己调用StopSelf()终止自身或者其它组件通过调用StopService()来终止它。服务终止后,系统会自动把它销毁;而Bound Service则是由其它组件(客户端)调用BindService()来建立连接,然后客户端通过一个IBinder接口与服务进行通信,通过调用UnbindService()关闭连接。另外,多个客户端可以绑定到同一个服务上,当所有的客户端都解除绑定后,系统才会销毁服务。

但是,Bound Service和Started Service并不是完全隔离的。也就是说,你也可以绑定到一个已经用StartService()启动的服务上。例如,你可以通过调用StartService()方法来启动一个后台音乐服务,传入一个指明所需播放音乐的Intent。 之后,用户也许需要用播放器进行一些控制,或者查看当前歌曲的信息,这时其他的activity可以通过调用BindService()与此服务进行绑定。在类似这样的情况下,即使你调用了StopService()方法或者StopSelf()方法,也不会真的终止被绑定的服务,除非所有的客户端都解除了绑定。

本章的例17-2通过具体代码演示了如何绑定到Started Service。

2、活跃生存期不同

Service的活跃生存期开始于OnStartCommand()或OnBind()的调用。这两个方法分别会传给StartService()或BindService()的Intent。如果服务是Started Service,则它的活跃生存期与完整生存期同时结束(即使OnStartCommand()返回后服务仍然处于活跃期)。如果服务是Bound Service,则活跃生存期在OnUnbind()返回后结束。

注意:虽然Started Service是通过它自己调用StopSelf()或通过其他组件调用StopService()来终止的,但是服务却没有提供类似OnStop()的回调方法。因此,除非将服务与客户端绑定在一起,否则系统就会在服务终止时销毁它。或者说,OnDestroy()是服务唯一会收到的回调方法。

上图标明了服务中典型的回调方法。尽管此图把StartService()创建的服务和BindService()创建的服务分开描述了,但请记住,无论启动方式如何,所有的服务实际上都允许被绑定。因此,对于通过OnStartCommand()启动的服务(客户端调用StartService()启动它),当客户端又调用了BindService()方法时,仍然可以接收OnBind()返回的结果,而这个返回的结果就是通过IBinder接口来实现的。

三、实现IBinder接口的方式

实现Bound Service的方式有多种,实现过程也比实现Started Service要复杂一些。

为了让Service支持绑定,服务必须实现OnBind()回调方法。这个方法返回一个IBinder对象,此对象定义了客户端与服务进行交互时所需的编程接口。

在服务中定义IBinder接口的方式有三种。

1、在继承自Binder的类中实现接口

如果你的服务只是为你自己的应用程序执行一些后台工作,此时,在继承自Binder的类中实现接口是首选的技术方案。不使用这种首选技术方案的理由只有一个:就是被绑定的服务可能还要被其它应用程序使用或者需要跨多个进程使用。

具体用法见本章的例17-1、例17-2、例17-3。

2、用Messenger实现接口

当应用程序中的activity或其它组件需要与Service进行交互,或者应用程序中的某些功能需要暴露给其它的应用程序时,此时首选的方案就是创建一个Bound Service,并通过进程间通信(IPC)来完成应用程序之间的消息传递。

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

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

具体用法见本章的例17-4。

3、用AIDL实现接口

AIDL(Android Interface Definition Language,Android接口定义语言)完成以下的所有工作:一是将对象解析为操作系统可识别的原始形态,二是将它们跨进程序列化(marshal)以完成进程间通信(IPC)。

当需要进程间通信(IPC)时,用Messenger实现要比用AIDL实现容易些,因为Messenger会把所有调用服务的请求都放入到一个队列中。而AIDL会把这些请求同时发送给服务,这样服务就必须多线程运行才能及时响应请求。

实际上,Messenger本质上也是基于AIDL的,只不过它仅在一个单独的进程中创建了一个队列,所有客户端请求都先进入该队列然后再依次取出来进行处理,这样服务每次就只会收到一个请求。可是,如果想让你的服务能“同时”处理多个请求,你可以直接用AIDL来实现。这种情况下,一定要确保你的服务必须拥有多线程处理的能力,并且是以线程安全的方式编写的。

总之,对经验不足的编程人员而言,实现进程间通信首选的办法就是用Messenger来实现,这样虽然运行效率低一些,但是不容易出错。而直接用AIDL实现虽然效率很高而且也很灵活,但是这需要有非常丰富的编程经验才能得心应手。这就像开汽车,不是简单学一学怎样把车开走就意味着也能立即会“玩漂移”的,如果你觉得自己对多线程把握不好或者编程经验不老道,最好还是别去招惹AIDL。

如果你的服务需要与远程进程进行通信,你同样可以使用一个Messenger来提供服务的接口。这种技术能让你无需使用AIDL就能实现进程间通信(IPC)。

【Android】17.1 Bound Services基本概念的更多相关文章

  1. Android开发文档翻译之-Services

    Service是一种能长期在后台运行同一时候不须要与用户进行交互的应用组件.其它组件能够开启service,开启后service能够自行运行及时用户已经切换到其它的应用.此外,组件能够与service ...

  2. Service官方教程(6)Bound Services主要用来实现通信服务,以及3种实现通信的方案简介。

    1.Bound Services A bound service is the server in a client-server interface. A bound service allows ...

  3. Service官方教程(3)Bound Services

    Bound Services 1.In this document The Basics Creating a Bound Service Extending the Binder class Usi ...

  4. Android For JNI(一)——JNI的概念以及C语言开发工具dev-c++,编写你的第一个C语言程序,使用C启动JAVA程序

    Android For JNI(一)--JNI的概念以及C语言开发工具dev-c++,编写你的第一个C语言程序 当你的Android之旅一步步的深入的时候,你其实会发现,很多东西都必须去和framew ...

  5. android Gradle的几个基本概念

    什么是Gradle? Gradle是一种依赖管理工具,基于Groovy语言,面向Java应用为主,它抛弃了基于XML的各种繁琐配置,取而代之的是一种基于Groovy的内部领域特定(DSL)语言. Gr ...

  6. 【Android】12.1 Intent基本概念

    分类:C#.Android.VS2015: 创建日期:2016-02-23 一.简介 Intent:意图,含义就是你想利用它调用哪个组件实现相关的功能,比如调用相机组件实现拍照.调用Contact组件 ...

  7. [翻译]API Guides - Bound Services

    官方文档原文地址:http://developer.android.com/guide/components/bound-services.html 一个Bound Service是一个客户端-服务器 ...

  8. android 回调函数一:基本概念

    1.概念 客户程序C调用服务程序S中的某个函数A,然后S又在某个时候反过来调用C中的某个函数B,对于C来说,这个B便叫做回调函数. 一般说来,C不会自己调用B,C提供B的目的就是让S来调用它,而且是C ...

  9. Android中使用"running services"查看service进程内存

    从Android 2.0开始,在Settings中加入了一个新的activity("Running Services" activity),它用于显示当前运行的每个Services ...

随机推荐

  1. Java从零开始学二十(集合简介)

    一.为什么需要集合框架 数组的长度是固定的,但是如果写程序时并不知道程序运行时会需要多少对象.或者需要更复杂的方式存储对象,---那么,可以使用JAVA集合框架,来解决这类问题 二.集合框架主要接口 ...

  2. vue 项目的开发流程

    1.$ node -v (检测node版本,node版本需要在 V4 以上) 2.全局安装vue $ npm install -g vue 3.安装脚手架 $ npm install -g vue-c ...

  3. python中的sort、sorted、reverse、reversed详解

    python语言中的列表排序方法有三个:reverse反转/倒序排序.sort正序排序.sorted可以获取排序后的列表.在更高级列表排序中,后两中方法还可以加入条件参数进行排序. reverse() ...

  4. JBoss AS 7之基本配置和部署(The Return Of The King)

    1.4 JBoss As 7基本配置 1.4.1 IP訪问控制 因默认情况下,jboss仅可通过127.0.0.1和localhost来訪问.假设你想局域网中的其他IP来訪问,你能够在standalo ...

  5. git工具 将源码clone到本地指定目录的三种方式

      git工具 将源码clone到本地指定目录的三种方式 CreationTime--2018年7月27日15点34分 Author:Marydon 1.情景展示 运行git-bash.exe,输入命 ...

  6. ios开发之公交卡系统的设计与实现

    // // main.m // Bus-公交 /* 公交一卡通充值系统.有两种功能选择.第一种投入硬币或者纸币 选择购票,另外一种一卡通充值,充值面额是20,50.100 */ #import < ...

  7. centos7 开启ftp服务

    1.关闭默认防火墙 systemctl stop firewalld.service #停止firewall systemctl disable firewalld.service #禁止firewa ...

  8. RabbitMQ消息队列生产者和消费者

    概述 生产者生产数据至 RabbitMQ 队列,消费者消费 RabbitMQ 队列里的数据. 详细 代码下载:http://www.demodashi.com/demo/10723.html 一.准备 ...

  9. OpenStack 网络:Neutron 初探

    OpenStack Neutron 网络模型 OpenStack nova-network 独立成为单独的组件 Neutron 后,形象的网络模型的多平面网络.混合平面私有网络.如图 3,图 4,图 ...

  10. hdu 4412 Sky Soldiers(区间DP)

    Sky Soldiers Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tot ...