一、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. Connection reset by peer的常见原因

    1,如果一端的Socket被关闭(或主动关闭,或因为异常退出而 引起的关闭),另一端仍发送数据,发送的第一个数据包引发该异常(Connect reset by peer). Socket默认连接60秒 ...

  2. [爬虫]BeautifulSoup4

    1.Beautiful Soup的简介 Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据.官方解释如下: Beautiful Soup提供一些简单的.python式的函 ...

  3. I/O-----字节输入流

    package io.day03; import java.io.FileInputStream; import java.io.InputStream; public class day03 { p ...

  4. socketWriter.go

    package blog4go import ( "bytes" "fmt" "net" "sync" ) // Soc ...

  5. SSIS 调试和故障排除

    SSIS内置的调试工具是非常完备的,主要是设置断点和查看变量值,这是在Package的设计阶段可以使用的工具,在Package部署到服务器之后,用户还可以使用事件处理程序以实现Package出错的自我 ...

  6. LoadRunner接口测试方法

    实际上到目前为止,我所做过的几个关于性能测试的项目,都是在UI页面上能正常访问结束所有的前期功能测试而开始的性能测试.但loadrunner不仅仅只能靠录制回放修改脚本进行性能测试. 往往需要对发送报 ...

  7. Java动态代理之JDK实现和CGlib实现

    一:代理模式(静态代理) 代理模式是常用设计模式的一种,我们在软件设计时常用的代理一般是指静态代理,也就是在代码中显式指定的代理. 静态代理由 业务实现类.业务代理类 两部分组成.业务实现类 负责实现 ...

  8. 【BAT面试题系列】面试官:你了解乐观锁和悲观锁吗?

    前言 乐观锁和悲观锁问题,是出现频率比较高的面试题.本文将由浅入深,逐步介绍它们的基本概念.实现方式(含实例).适用场景,以及可能遇到的面试官追问,希望能够帮助你打动面试官. 目录 一.基本概念 二. ...

  9. Spark学习之Spark SQL

    一.简介 Spark SQL 提供了以下三大功能. (1) Spark SQL 可以从各种结构化数据源(例如 JSON.Hive.Parquet 等)中读取数据. (2) Spark SQL 不仅支持 ...

  10. Caffe源码理解1:Blob存储结构与设计

    博客:blog.shinelee.me | 博客园 | CSDN Blob作用 据Caffe官方描述: A Blob is a wrapper over the actual data being p ...