一、Service是什么

对于这个问题,想必大家都能说出一二,如“它是四大组件之一”、“在后台处理一些操作”等。咱们这里看看官方文档中的描述,官方语言一般都是准确且言简意赅的,这里可以体验一下其风格。如下是从官方文档中提取的关键部分,比较容易看懂,咱就不翻译了,详情可以阅读原文【What is a Service:https://developer.android.google.cn/reference/android/app/Service.html#what-is-a-service】。

A Service is an application component representing either an application's desire to perform a longer-running operation while not interacting with the user or to supply functionality for other applications to use.
......
Thus a Service itself is actually very simple, providing two main features:
● A facility for the application to tell the system about something it wants to be doing in the background (even when the user is not directly interacting with the application).
● A facility for an application to expose some of its functionality to other applications.

当笔者读到“perform a longer-running operation”的时候,深切感受到官网语言的准确性。因为笔者和很多开发者一样一般会说“在后台处理耗时操作”,显然这是不准确的,但是却找不到更好的语言来描述,知道看到官网的这句,有了“醍醐灌顶”的感觉。另外,如果以后在回答类似“Service是什么”的时候,咱们如果说“官网上说...第一点:XXX,第二点:XXX”,想必档次也会高不少吧!

二、Service使用概述

Service的使用是一种类似于C/S的形式,Service为Server端,正如第一节中提到的它的功能一样——在后台处理事务和向其他app提供功能,而调用服务的地方为Client端。由此可以看出,Service可以在app内部使用,也可以跨进程在不同的app中调用,对应的使用方法也略有不同,但整体上都是分为三个步骤:1)创建Service子类;2)在AndroidManifest.xml中声明;3)在Client端调用Service。后面会分不同的章节依次对这三步进行说明。

三、Service在AndroidManifest.xml中的声明

Service定义好以后,需要在AndroidManifest.xml中声明。这其中有很多可以定义的属性值,android开发者官方文档【<service>:https://developer.android.google.cn/guide/topics/manifest/service-element.html】中有详细的介绍。其给出的可以设置的属性有:

 <service android:description="string resource"
android:directBootAware=["true" | "false"]
android:enabled=["true" | "false"]
android:exported=["true" | "false"]
android:icon="drawable resource"
android:isolatedProcess=["true" | "false"]
android:label="string resource"
android:name="string"
android:permission="string"
android:process="string" >
. . .
</service>

其中有很多属性的含义,在笔者另外一篇文章【【朝花夕拾】四大组件之(一)Broadcast篇】第三节“广播的注册”的“静态注册中的属性简介”中介绍过,虽然是声明Broadcast Receiver的属性,但在Service中其含义基本上是一致的,这里就不赘述了。这里仅介绍一下之前没有介绍过的属性含义,主要是翻译官网中的内容并做一些补充。

  • android:description

它是一个向用户描述该service的字符串。它应该被设置为对字符串资源的引用,使得它能够像其它用户界面中字符串那样本地化。

  • android:isolatedProcess

如果被设置为true,该service将运行在一个特殊的进程中,该进程独立于系统的其他进成并且没有自己的权限。和该service通信的唯一方式就是 Servcie API(binding和starting)。

  • android:process

在<application>及其它组件的声明中,都有该属性。这个属性在前面提到的广播篇中介绍过,这里补充说明一些内容。如果该进程以“:”打头,那么它的意思是指要在当前进程名称前面附加上当前的包名,如“:remote”表示当前进程为“packageName:remote”,它是当前app进程私有的一个进程,其他App的组件就不能和它运行在一个进程中。而如果以小写字母打头,如“com.remote”(官方文档中说命名规范中要求必须要含有".",否则会报错),则表示该进程名为“com.remote”,是一个全局进程,可以让不同app中的不同组件共享这个进程。

对于如何正确使用多进程,为什么要用多进程,使用多进程有什么陷阱,在博文【Android多进程总结一:生成多进程(android:process属性)—https://blog.csdn.net/lixpjita39/article/details/77435156】中有更多的讲解,另外该篇文章所参考的文章也值得一读。

Service的启动方式

Service生命周期

IntentService

Service工作线程

Service跨进程通信

Service与子线程

当提起Service的时候,很多人会联想到子线程,尤其对于初学者而言,甚至会把这两者的功能混为一谈,分不清楚这两者之间的区别。事实上,笔者在工作的前几年也没有很清楚地分清过它们的区别,所以这里就重点探讨一下这两者之间的联系、区别以及如何选择吧。

1、Service和子线程的联系

之所以会把这两者联系在一起,有很大一部分原因是它们都和后台和耗时扯上了关系。子线程是相对主线程而言的,在Android中,说到主线程就是指的UI线程,在UI线程中不允许处理耗时的操作,否则在系统规定的时间内会报ANR。耗时的操作如请求网络、操作数据库等就需要在子线程中去完成,所以子线程也被称为工作线程,相对于UI线程来说,子线程就是一个在后台运行的线程。而Service呢,在我们的认识当中,它也是用来处理一些后台任务的,一些需要长时间运行和比较耗时操作也会考虑放到这里运行,比如下载任务 ,播放音乐等。所以,如果没有一定的经验,确实是很容易混淆的。

2、Service和子线程的区别

事实上,如果没有做特别的处理,Service的生命周期函数在默认情况下都是运行在UI线程中的。Android这里提到的后台的概念,也是相对UI来说的,是指它的运行完全不依赖于UI,譬如正在使用的app就是一个前台进程,当按下Home键后,就变成了一个后台进程了。所以Service和子线程是没有半毛钱的关系的。既然Service是运行在UI线程的,那么它如何处理那些耗时操作的呢,难道不会阻塞UI线程发生ANR吗?事实上,这些耗时的操作也是在Service中开启子线程来完成的。

3、Service与子线程的选择

既然在Service中处理耗时操作也需要开启子线程,那为什么不直接在Acitivty中开启子线程,而非要多此一举开启服务然后再开子线程呢?这是因为Activity由于用户使用情况,经常会退出某个Activity去做其它操作,不会长时间停留在该Activity,如果在Acitivity中开了一个子线程,当Activity销毁以后,就没有办法再获取并控制这个子线程的实例了。而Service却可以长时间在后台运行,只要这个Service不被销毁,那么其他组件即便是销毁了,只要和该Service重新建立关联,就又能够获取到原有的Service中Binder的实例,对其中的子线程实例进行操作。

当然,启用Service也不是一本万利的,因为Service是一个组件,势必要增到系统的开销,谷歌官方文档【https://developer.android.google.cn/guide/components/services#Basics】中也明确说明,应仅在必要时才创建服务。一般来说,如果是耗时不是太长的操作,且和activity有较多的交互,那么选择直接在Activity中开启子线程比较好。比如读取数据库中的数据并显示在界面上,以及获取网络数据并显示等,耗时不会太长且得到数据后要及时与activity交互,很明显就没有必要开启Service了。但是,如果像下载大文件这类需要较长时间完成的操作,就需要开启Service来完成了。Service也可以和界面交互,如前台Service,就会在通知栏上有和Service交互的界面。

另外需要注意的是,这里所说的子线程,并不仅仅指传统的Thread类,还包括AsyncTask、HandlerThread等形式。

不同版本中Service重要功能变迁

android 8.0启动后台服务

Service处理耗时操作

https://blog.csdn.net/javazejian/article/details/52709857

https://www.jianshu.com/p/95ec2a23f300

https://developer.android.google.cn/reference/android/app/Service.html

【朝花夕拾】四大组件之(二)Service篇的更多相关文章

  1. Android 四大组件之二(Service)

    service可以在和多场合的应用中使用,比如播放多媒体的时候用户启动了其他Activity这个时候程序要在后台继续播放,比如检测SD卡上文件的变化,再或者在后台记录你地理信息位置的改变等等,总之服务 ...

  2. [Android四大组件之二]——Service

    Service是Android中四大组件之一,在Android开发中起到非常重要的作用,它运行在后台,不与用户进行交互. 1.Service的继承关系: java.lang.Object → andr ...

  3. 6、四大组件之二-Service初步

    一.什么是Service 有些用时比较长得操作我们希望他在后台运行 ,不耽误我们当前的操作 . 这就引入了Service概念 . 常见的比如:访问网络 , 文件IO操作 , 大数据的数据库任务,播放音 ...

  4. 11、四大组件之二-Service高级(二)Native Service

    一.Service的分类 1.1>Android Service 使用Java编写在JVM中运行的服务 1.2>Native Service 使用C/C++完成的服务,一般在系统开始时完成 ...

  5. 7、四大组件之二-Service高级

    一.Native Service 1>什么是Native Service 使用JNI编写,在系统启动完成之前启动的系统级服务. 2>哪些服务是Native Service ACCESSIB ...

  6. Android四大组件之服务-Service 原理和应用开发详解

    一.Android 服务简介 Service是android 系统中的四大组件之一(Activity.Service.BroadcastReceiver.ContentProvider),它跟Acti ...

  7. Android四大组件初识之Service

    Service作为Android四大组件之一,可以与Activity建立双向连接(绑定模式),提供数据和功能.也能够接收Intent单方面请求(调用模式),进行数据处理和调度功能. Service与A ...

  8. 入职小白随笔之Android四大组件——服务(Service)

    Service Android多线程编程 当我们在程序中执行一些耗时操作时,比如发起一条网络请求,考虑到网速等原因,服务器未必会立刻响应我们的请求,此时我们就需要将这些操作放在子线程中去运行,以防止主 ...

  9. Android四大组件之一:Service(服务)

    Service跟Activity也是出于统一级别的组件,且与Activity的最大区别之一主要是没有人机界面,主要是运行在程序的后台(我是这么理解的),帮助文档上说的是运行于进程的主线程中,但是服务并 ...

  10. Android 四大组件(Activity、Service、BroadCastReceiver、ContentProvider)

    转载于:http://blog.csdn.net/byxdaz/article/details/9708491 http://blog.csdn.net/q876266464/article/deta ...

随机推荐

  1. Python 枚举

    1. 枚举的定义 首先,定义枚举要导入enum模块.枚举定义用class关键字,继承Enum类.用于定义枚举的class和定义类的class是有区别. 示例代码: from enum import E ...

  2. redis基础操作~~数据备份与恢复、数据安全、性能测试、客户端连接、分区

    数据备份与恢复 数据备份redis save 命令用于创建当前数据库的备份. redis 127.0.0.1:6379> SAVE OK 该命令将在 redis 安装目录中创建dump.rdb文 ...

  3. mybatis批量提交

    之前在做项目时,使用mybatis,批量执行sql,这里简单写下步骤 在配置数据库连接时,加入一个参数,例如 jdbc:mysql://127.0.0.1:3307/mvs-report?allowM ...

  4. BZOJ_4269_再见Xor_线性基

    BZOJ_4269_再见Xor_线性基 Description 给定N个数,你可以在这些数中任意选一些数出来,每个数可以选任意多次,试求出你能选出的数的异或和的最大值和严格次大值. Input 第一行 ...

  5. B20J_2733_[HNOI2012]永无乡_权值线段树合并

    B20J_2733_[HNOI2012]永无乡_权值线段树合并 Description:n座岛,编号从1到n,每座岛都有自己的独一无二的重要度,按照重要度可以将这n座岛排名,名次用1到 n来表示.某些 ...

  6. C语言文件 "w+"与"wb+"区别

    这是我今天碰到的问题,现在已经解决, 希望我的整理能够帮助到你们! w+以纯文本方式读写,而wb+是以二进制方式进行读写. mode说明: w 打开只写文件,若文件存在则文件长度清为0,即该文件内容会 ...

  7. Redis+Restful 构造序列号和压力测试【后续】

    大家还记上篇博文https://www.cnblogs.com/itshare/p/8643508.html,测试redis构造流水号的tps是600多/1s. 这个速度显然不能体现redis 集群在 ...

  8. TF.learn学习

    官网地址:https://www.tensorflow.org/versions/r1.1/get_started/tflearn 1.代码例子 实现自定义的Estimator 使用DNNClassi ...

  9. 部署Chart应用并使用.net core读取Kubernetes中的configMap

    上一篇文章讲了 k8s使用helm打包chart并上传到腾讯云TencentHub,今天就讲一下使用Helm部署应用并使用configMap代替asp.net core 中的appsettings.j ...

  10. Java注解(一):介绍,作用,思想及优点

    “注解优先于命令模式”-出自<Effective Java> Java 注解,从名字上看是注释,解释.但功能却不仅仅是注释那么简单.注解(Annotation) 为我们在代码中添加信息提供 ...