分类:C#、Android、VS2015;

创建日期:2016-03-01

一、简介

为了解决在后台运行任务的问题,Android引入了一个称为Service的应用程序组件。Service的职责是专门用于创建、开始和停止在后台执行的任务,同时提供前台和后台交互的编程接口。

注意Android系统中所指的Service和我们平常所说的Web Service不是一回事,Android系统提供的Service只是一个应用程序组件,它能在后台执行一些耗时较长的无用户界面的操作。这种Service能被其它应用程序的组件启动,即使用户切换到另外的应用,它也能保持在后台继续运行。此外,应用程序组件还能与这些Service绑定,并与Sevice进行交互,甚至能进行进程间通信(IPC)。比如,利用Android Service可以处理网络传输、音乐播放、执行文件I/O、或者与content provider进行交互,所有这些都是在后台进行的。

Android Service的生命周期可能用时较短,也可能用时很长。比如,媒体播放器播放歌曲时,为了让用户感觉导航到其他屏幕时音乐还在继续播放,媒体播放器这个Activity就需要通过Context.StartService()方法启动一个Service在后台继续播放音乐。另外,还可以通过Context.BindService()方法将当前Activity绑定到一个后台Service(如果该Service未启动则自动启动它),当连接到该Service之后,还可以利用Sevice提供的接口与它进行通信,比如控制音乐的暂停、重播等动作。

二、Service的分类

对一个安卓服务(Android Service)来说,通常是要么将其作为已启动的服务(Started Service),要么将其作为已被绑定的服务(Bound Service)。

1、Started Service

已启动的服务(Started Service)是指被同一个应用程序的某个对象显式启动,或者在设备引导时就启动了(配置了服务的情况)。通常情况下,已启动的服务在操作系统或服务自身显式调用停止服务之前一直在运行。

2、Bound Service

被绑定的服务(Bound Service)提供直接链接到应用程序中特定的Service。它使用一个Binder提供对Service的引用,这样一来,应用程序就可以直接访问Service中的成员了。一般在同一个应用程序(通常是一个Activity)中的客户端启动时绑定到该Service,导致Android启动该服务,在客户端连接或绑定到它以后,安卓系统会保持被绑定的服务一直运行。当所有客户端断开连接或取消绑定时,Android才会停止该服务。

3、Hybrid Service

也可以将Started Service和Bound Service这两种服务混合在一起,称为混合式服务(Hybrid Service)。即:先显式启动某个服务,然后再绑定到该服务。这种方式的好处是也给别的应用程序提供了一个利用服务做其他事情的机会。换句话说,只要别的应用程序连接到该服务,就可以直接访问它。

混合式服务的办法非常有用,使用也非常普遍。比如说,我们正在编写一个在徒步旅行时跟踪运动位置的应用程序,我们可能想要不断地记录位置以便以后使用,但仅在需要屏幕显示时才去显示特定的位置信息。在这种情况下,当应用程序运行时,仅仅在客户端某一个Activity在前台运行的时候才可能会启动这个服务。该Activity绑定到该服务以后,就可以获取位置信息,但是,即使该Activity取消和这个服务的绑定,该服务仍能继续运行。换言之,混合服务(Hybrid Service)一旦启动起来就会一直运行,直到它被显式停止和没有客户端绑定到它才会关闭它,或者直到系统因为内存不够用时才会关闭它。

三、使用服务还是使用线程

如果你需要在主线程之外执行一些工作,但仅当用户与你的应用程序交互时才会用到它,那你应该创建一个新的线程而不是创建一个服务。比如,如果你需要播放音乐,但只是当你的activity在运行时才需要播放,此时可以在OnCreate()中创建一个线程,在OnStart()中开始运行,在OnStop()中终止运行。还可以考虑使用AsyncTask或HandlerThread来取代传统的Thread类。

要始终记住:

(1)如果你使用了服务,它默认运行在应用程序的主线程中。因此,如果服务执行的是密集计算型的工作,那么它可能会阻塞界面操作,这种情况下,你仍然应该在服务中创建一个新的线程来完成这些工作。

(2)创建自定义的服务时,必须新建一个继承自Service的类或其子类。另外,在实现代码中,还需要重写一些回调方法,这些回调方法用于对服务生命周期中的关键节点进行处理,以及向组件提供绑定机制。

这里再强调一遍,在Android系统中,服务仅仅是一个组件,即使用户不再与你的应用程序发生交互,它可能仍然能在后台运行着。因此,应该只在需要时才创建一个服务。

四、在AndroidManifest.xml中配置服务

用C#实现Android服务时,一般不直接修改清单文件(AndroidManifest.xml)。如果你想这么做当然也可以。不过,此时你要忍受修改AndroidManifest.xml文件时没有智能提示的痛苦。

下面简单说明如何直接在AndroidManifest.xml文件中配置Service。

要在配置文件中直接声明你的服务,只需要把<service>元素作为子元素加入到<application>元素中去即可。例如:

<manifest ... >
...
<application ... >
<service android:name="exampleservice.ExampleService" />
...
</application>
</manifest>

其中,exampleservice是服务子类所在的命名空间(在配置文件中要把命名空间全部变为小写字母才可以),ExampleService是服务子类的类名,大小写均可。

android:name是唯一必需在配置文件中指定的属性——它定义了服务的完整类名。也可以在<service>元素中包含其它属性,比如定义启动服务所需权限、服务运行的进程之类的属性等。

与Activity一样,服务也可以定义intent过滤器。

通过声明intent过滤器,任何安装在用户设备上的应用程序组件都有能力来启动你的服务,只要你的服务所声明的intent过滤器与其它应用程序传递给StartService()的intent相匹配即可。

但是,如果你想让服务只能在你的应用程序内部使用(其它应用程序无法调用),那么就不必(也不应该)提供任何intent过滤器。 如果不存在任何intent过滤器,那你就必须用精确指定服务类名的intent来启动服务。

此外,如果服务配置中包含了android:exported属性并且将其设置为"false",即可确保该服务是你的应用程序的私有服务。即使服务提供了intent过滤器,本属性依然生效。

五、组件与Service的通信

组件与服务进行通信的方式取决于该服务运行的模式。Android提供了三个用于组件和Service进行通信的选项:Service Binding、Service Messengers、AIDL。

1、绑定服务

如果服务是同一个应用程序的一部分,客户端可以直接绑定到服务并直接与之通信。绑定到客户端的服务将重写绑定服务生命周期的方法,并使用Binder和ServiceConnection实现服务与客户端的通信。

2、消息服务

有时客户端需要与另一个应用程序中的服务进行通信,由于应用程序不能访问彼此的内存,因此不可能直接建立连接。此时,需要通过跨进程边界的进程间通信(IPC,Inter-Process Communication)来封送数据。在这种情况下,可以用消息服务跨进程边界,即允许客户端绑定到远程服务(RPC),并调用远程服务器上提供的Service来实现。

3、AIDL

AIDL是Android接口定义语言(Android Interface Definition Language)的缩写。这是跨进程边界通信的另一种方式。AIDL是一个低级别的接口,它对包含元数据类型的对象进行了封装,使其可以跨进程边界。但是,由于消息服务更易于使用,也更容易实现,因此自消息服务推出以来,已经在很大程度上取代了AIDL通信模式。但是,消息服务发送的消息是通过串行方式来实现的而不是用并行方式实现(注意不要把串行方式和异步方式混淆在一起),当需要“并发”调用跨进程边界的通信服务时,还是应该用AIDL来实现。不过,移动应用中需要用AIDL实现的情况并不多,因此,如果是初学者,也可以暂不考虑它。

总之,在实际应用中,其他组件和Service通信时,最常用的是前两种服务模式:绑定服务和消息服务。只有在需要并发执行的情况下才需要用AIDL去实现。

【Android】16.1 Android Service基本概念的更多相关文章

  1. Android学习总结(二)——Service基本概念和生命周期

    好了,前面我们已经学习了Activity的知识,相信大家也有一定的理解,但是还是不能放松,Android四大组件,我们才学习了一个而已,接下我们继续学习Service.计划总结如下内容: 一.Serv ...

  2. Android组件系列----Android Service组件深入解析

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...

  3. Android 四大护法之一 Service

    1.Service的概念 Service是Android 四大组件之一,是默认没有界面的运行于后台的服务程序.Service的开启方式分为启动式服务(startService)和绑定式服务(bindS ...

  4. Android四大组件之Service

    Android四大组件之Service Android支持服务的概念,服务是在后台运行的组件,没有用户界面,Android服务可用有与活动独立的生命周期.Android支持两种类型的服务: 本地服务: ...

  5. 疯狂Android第一章:Android环境配置以及基本概念

    第一章 无关痒痛:Android Studio安装,配置,基本功能介绍! 重点内容:Android应用基本结构分析. 基础概念部分(只需知道作用,原理后见代码): Activity:安卓系统中负责与用 ...

  6. Android菜鸟的成长笔记(17)—— 再看Android中的Unbounded Service

    原文:Android菜鸟的成长笔记(17)-- 再看Android中的Unbounded Service 前面已经写过关于startService(Unbounded Service)的一篇文章:&l ...

  7. Android binder学习一:主要概念

    要看得懂android代码,首先要了解binder机制.binder机制也是android里面比較难以理解的一块,这里记录一下binder的重要概念以及实现.作为备忘. 部分内容来源于网上,如有侵权. ...

  8. Android四大组件之一Service介绍-android学习之旅(十二)

    基本概念: service是android四大组件之一,运行在后台执行耗时操作,并不提供用户界面.其他组件如acticity可以通过startService启动该组件,也可以通过bindService ...

  9. Android四大组件之一 -- Service详解

    相信大多数朋友对Service这个名词都不会陌生,没错,一个老练的Android程序员如果连Service都没听说过的话,那确实也太逊了.Service作为Android四大组件之一,在每一个应用程序 ...

随机推荐

  1. jeecms运行出现 Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.解决

    在/WEB-INF/config/application-context.xml中添加红色字体内容: <bean id="dataSource" class="co ...

  2. python的__slots__节约内存的魔法;检查python每一行代码内存占用情况的工具

    在Python中,每个类都有实例属性.默认情况下Python用一个字典来保存一个对象的实例属性.这非常有用,因为它允许我们在运行时去设置任意的新属性. 然而,对于有着已知属性的小类来说,它可能是个瓶颈 ...

  3. input 输入框默认获得焦点

    JavaScript实现默认焦点: 如下写<body>标签: <body onload="window.formLogin.user.focus()"> & ...

  4. IE、火狐导入收藏夹乱码解决方案

    IE收藏夹导入Firefox书签后出现乱码的原因在于两个浏览器的收藏夹的html文件的编码方式不同,Firefox使用的是UTF-8编码,而IE是ASCII编码.故两者的收藏夹文件互相导入的时候会出现 ...

  5. mysql之子查询

    所谓子查询,就是指在一个查询之中嵌套了其他的若干查询,通过子查询可以实现多表查询,该查询语句中可能包含IN,ANY,ALL和EXISTS等关键字,除此之外还可以包含比较运算符,子查询经常出现在WHER ...

  6. (剑指Offer)面试题53:正则表达式匹配

    题目: 请实现一个函数用来匹配包括'.'和'*'的正则表达式.模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次). 在本题中,匹配是指字符串的所有字符匹配整个模式. ...

  7. ASP.NET MVC4 Jquer 日期控件 测试范例

    <!doctype html>   <html lang="en"> <head> <meta charset="utf-8&q ...

  8. LeetCode Linked List Cycle 解答程序

    Linked List Cycle Given a linked list, determine if it has a cycle in it. Follow up: Can you solve i ...

  9. 总想自己动动手系列·1·本地和外网(Liunx服务器上部署的web项目)按照自定义的报文格式进行交互(准备篇)

    一.准备工作 (1)有一台属于自己的云服务器,并成功部署和发布一个web项目(当然,本质上来说Java-Project也没问题),通过外网IP可以正常访问该web项目. 需要说明的是:任何web项目, ...

  10. IOS手机使用Fiddler抓获HTTPS报文方法

    Configure Fiddler Click Tools > Fiddler Options > Connections. Click the checkbox by Allow rem ...