当前位置: 首页 > news >正文

Android Service知识

一. 概览

        Service 是一种可在后台执行长时间运行操作而不提供界面的应用组件。服务可由其他应用组件启动,而且即使用户切换到其他应用,服务仍将在后台继续运行。此外,组件可通过绑定到服务与之进行交互,甚至是执行进程间通信 (IPC)。例如,服务可在后台处理网络事务、播放音乐,执行文件 I/O 或与内容提供程序进行交互.

        本篇文章,我们重点讲一讲绑定服务.  为后面写的理解进程间通信机制文章做个铺垫.

二. 服务类型

2.1 前台服务

前台服务执行一些用户能注意到的操作。例如,音频应用会使用前台服务来播放音频曲目。前台服务必须显示通知。即使用户停止与应用的交互,前台服务仍会继续运行。

2.2 后台服务

后台服务执行用户不会直接注意到的操作。例如,如果应用使用某个服务来进行数据搜集上报,则此服务通常是后台服务。

2.3  绑定服务

当应用组件通过调用 bindService() 绑定到服务时,服务即处于绑定状态。绑定服务会提供客户端-服务器接口,以便组件与服务进行交互、发送请求、接收结果,甚至是利用进程间通信 (IPC) 跨进程执行这些操作。仅当与另一个应用组件绑定时,绑定服务才会运行。多个组件可同时绑定到该服务,但全部取消绑定后,该服务即会被销毁

三. 基础知识

        如要创建服务,您必须创建 Service 的子类(或使用它的一个现有子类)。在实现中,您必须重写一些回调方法,从而处理服务生命周期的某些关键方面,并提供一种机制将组件绑定到服务(如适用)。以下是你应该重写的最重要的回调方法:

onStartCommand()
当另一个组件(如 Activity)请求启动服务时,系统会通过调用 startService() 来调用此方法。执行此方法时,服务即会启动并可在后台无限期运行

如果您实现此方法,则在服务工作完成后,需负责通过调用 stopSelf() 或 stopService() 来停止服务。

onBind()

当另一个组件想要与服务绑定(例如执行 RPC)时,系统会通过调用 bindService() 来调用此方法。在此方法的实现中,您必须通过返回 IBinder 提供一个接口,以供客户端用来与服务进行通信。请务必实现此方法;但是,如果你并不希望允许绑定,则应返回 null。

如果组件通过调用 startService() 启动服务(这会引起对 onStartCommand() 的调用),则服务会一直运行,直到其使用 stopSelf() 自行停止运行,或由其他组件通过调用 stopService() 将其停止为止。

[注意]: 如果通过startService()已经启动了一个服务,再通过startService()方法启动的时候,  只会走onStartCommand()方法,不会重新走onCreate()方法. 

四. 创建绑定服务

绑定服务允许应用组件通过调用 bindService() 与其绑定,从而创建长期连接.

如需与 Activity 和其他应用组件中的Service服务进行交互,或需要通过进程间通信 (IPC) 向其他应用公开某些应用功能,则应创建绑定服务。

[要点]:

如要创建绑定服务,您需通过实现 onBind() 回调方法返回 IBinder,从而定义与服务进行通信的接口;

1. 必须定义指定客户端如何与服务进行通信的接口

2. 服务与客户端之间的这个接口必须是 IBinder 的实现,并且服务端必须从 onBind() 回调方法返回该接口。

3. 收到 IBinder 后,客户端便可开始通过该接口与服务端进行交互。

多个客户端可以同时绑定到服务。完成与服务的交互后,客户端会通过调用 unbindService() 来取消绑定。如果没有绑定到服务的客户端,则系统会销毁该服务。

等同于下面这句话的理解:

多个客户端可以绑定到相同服务,而且当所有绑定全部取消后,系统即会销毁该服务(服务不必自行停止运行).


五. 服务生命周期


  

六. 实践出真知

本篇文章重点只讲绑定本地服务, 在同一个进程间通信

如果您的服务仅供本地应用使用,且无需跨进程工作,您可以实现自有 Binder 类,让客户端通过该类直接访问服务中的公共方法。

注意:只有当客户端和服务处于同一应用和进程内(最常见的情况)时,此方式才有效。例如,对于需要将 Activity 绑定到在后台播放音乐的自有服务的音乐应用,此方式非常有效。

实现步骤:

1. 在你的服务中,创建可执行以下某种操作的 Binder 实例:
     包含客户端可调用的公共方法。
     返回当前的 Service 实例,该实例中包含客户端可调用的公共方法。
     返回由服务承载的其他类的实例,其中包含客户端可调用的公共方法。

2. 从 onBind() 回调方法返回此 Binder 实例。

3. 在客户端中,从 onServiceConnected() 回调方法接收 Binder,并使用提供的方法调用绑定服务。

客户端代码

public class LocalClient extends AppCompatActivity {private Intent intent;//同一进程, 本地服务对象LocalService mService;//是否绑定成功boolean mBound = false;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);intent = new Intent(this, LocalService.class);Button btn = (Button)findViewById(R.id.start_btn);btn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {if(mBound) {int num = mService.getRandomNumber();Toast.makeText(LocalClient.this, "number: " + num, Toast.LENGTH_SHORT).show();}}});}private ServiceConnection connection = new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName componentName, IBinder service) {Log.e("test", "===客户端===onServiceConnected======");mBound = true;//已经绑定到LocalService,强制转换IBinder并获取LocalService实例LocalService.LocalBinder binder = (LocalService.LocalBinder) service;mService = binder.getService();}@Overridepublic void onServiceDisconnected(ComponentName componentName) {Log.e("test", "====onServiceDisconnected=====");mBound = false;}};//在onstart方法中 调用 bindservice 绑定服务@Overrideprotected void onStart() {super.onStart();bindService(intent, connection, Context.BIND_AUTO_CREATE);}//在onstop方法中, 调用unbindservice 解绑服务@Overrideprotected void onStop() {super.onStop();unbindService(connection);mBound = false;}@Overrideprotected void onDestroy() {super.onDestroy();}

本地服务端的代码:

public class LocalService extends Service {// Binder given to clientsprivate final IBinder binder = new LocalBinder();// Random number generatorprivate final Random mGenerator = new Random();public LocalService() {}/** method for clients */public int getRandomNumber() {return mGenerator.nextInt(100);}/*** Class used for the client Binder.  Because we know this service always* runs in the same process as its clients, we don't need to deal with IPC.* 用于客户端的Binder类。因为我们知道该服务总是在与其客户端相同的进程中运行,所以我们不需要处理IPC。*/class LocalBinder extends Binder {LocalService getService() {// Return this instance of LocalService so clients can call public methodsreturn LocalService.this;}}@Overridepublic IBinder onBind(Intent intent) {Log.e("test", "====LocalService  onBind====绑定服务回调===");return binder;}@Overridepublic boolean onUnbind(Intent intent) {Log.e("test", "====LocalService  onUnbind===解绑服务回调==");return super.onUnbind(intent);}

打开app界面后,打印log:

03-06 15:16:16.612 19858 19858 E test    : ====LocalService  onBind====绑定服务回调=
03-06 15:16:16.623 19858 19858 E test    : ===客户端===onServiceConnected======

客户端通过bindservice 绑定服务, 打印'===LocalService  onBind===='然后服务端通过onBind()回调方法返回此Binder实例

在客户端中从 onServiceConnected() 回调方法接收 Binder对象,打印"客户端===onServiceConnected===="

退出app界面后, 解绑服务,打印log:

03-06 15:22:52.460 19858 19858 E test    : ====LocalService  onUnbind===解绑服务回调==


 

相关文章:

Android Service知识

一. 概览 Service 是一种可在后台执行长时间运行操作而不提供界面的应用组件。服务可由其他应用组件启动,而且即使用户切换到其他应用,服务仍将在后台继续运行。此外,组件可通过绑定到服务与之进行交互,甚至是执行进程间通信 (IPC…...

axios的get请求传入数组参数后端无法接收的问题

问题描述 在做项目时,需要把前端的数组通过axios的get请求发送到后端处理,于是像这样直接发送: axios.get(url,{params:{arr: update_arr}})这时在后端接收后报错说:没有 ‘arr’ 这个key: arr request.GET[arr] pr…...

奖金发放-课后程序(Python程序开发案例教程-黑马程序员编著-第3章-课后作业)

实例2:奖金发放 某企业发放的奖金是根据利润和提成计算的,其规则如表1所示。 表1 奖金发放规则 利润(万元) 奖金提成(%) I≤10 10% 10<I≤20 7.5% 20<I≤20 5% 10&#xf…...

第十四届蓝桥杯第三期模拟赛 【python】

第十四届蓝桥杯第三期模拟赛 【python】 文章目录第十四届蓝桥杯第三期模拟赛 【python】✨最小的十六进制(python的16进制)❓️问题描述答案提交🧠思路🖥︎参考答案✨Excel的列(进制转化)❓️问题描述答案…...

Python——函数(重点内容)

函数 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。 函数能提高应用的模块性,和代码的重复利用率。你已经知道Python提供了许多内建函数,比如print()。但你也可以自己创建函数,这被叫…...

2023年如何在Google做外贸

2023年如何在Google做外贸 答案是:利用谷歌SEO获取自然流量促进成交。 随着全球化和数字化的发展,外贸行业越来越重视互联网的渠道拓展。 在Google搜索引擎上做好SEO优化,是吸引国际客户和提高品牌知名度的关键。 本文将探讨2023年如何在…...

Linux操作系统学习(线程池)

文章目录线程池线程池原理代码示例单例模式饿汉模式懒汉模式饿汉懒汉对比其他的锁线程池 线程池原理 ​ 线程池是一种线程使用模式。在多线程应用中,若每有一个任务,线程就去调度相应的函数去创建,当任务过多时,每次都去调度且每…...

JVM运行时数据区—Java虚拟机栈

虚拟机栈的背景 由于跨平台性的设计,java的指令都是根据栈来设计的。不同平台CPU架构不同,所以不能设计为基于寄存器的。 根据栈设计的优点是跨平台,指令集小,编译器容易实现,缺点是性能下降,实现同样的功…...

gitlab中文社区

1、获取gitlab中文社区项目 中文社区版项目:https://gitlab.com/xhang/gitlab 2、克隆中文仓库 git clone https://gitlab.com/xhang/gitlab.git 3、查看gitlab版本 diff 获取对应版本的中文 head -1 /opt/gitlab/version-manifest.txt #安装的是gitlab-ce…...

深度学习-第T2周——彩色图片分类

深度学习-第T2周——彩色图片分类深度学习-第P1周——实现mnist手写数字识别一、前言二、我的环境三、前期工作1、导入依赖项并设置GPU2、导入数据集3、归一化4、可视化图片四、构建简单的CNN网络五、编译并训练模型1、设置超参数2、编写训练函数六、预测七、模型评估深度学习-…...

GNU C编译器扩展关键字:__attribute__

目录 一、section 二、aligned 三、packed 四、format 五、weak 六、alias 七、noinline和always_inline GNU C增加了一个__attribute__关键字用来声明一个函数、变量或类型的特殊属性,可以知道编译器在编译过程中进行特定方面的优化或代码检查。 目前&…...

C++基础 | 从C到C++快速过渡

一、开发环境 c使用的编译器是g。 vim或者vscodeclionVS 二、C版本的Hello World /*** brief c版本helloworld示例* author Mculover666* date 2023/2/26*/#include <iostream> using namespace std;int main() {int a 1;double b 3.14;char c[] "str…...

【C++】仿函数 -- priority_queue

文章目录一、priority_queue 的介绍和使用1、priority_queue 的介绍2、priority_queue 的使用3、priority_queue 相关 OJ 题二、仿函数1、什么是仿函数2、仿函数的作用三、priority_queue 的模拟实现一、priority_queue 的介绍和使用 1、priority_queue 的介绍 priority_queu…...

盘一盘C++的类型描述符(一)

前言 C的类型描述方式是从C语言继承来的&#xff0c;并且进行了扩充&#xff08;例如引用、非静态成员函数、模板实参等&#xff09;。但由于C语言中的类型描述方式就略微有点「反人类」&#xff0c;再经C扩展后就有点「反碳基生物」了~ 是的&#xff0c;当我第一次看到这种描…...

Peppol的发展史和基本框架

Peppol&#xff08;Pan-European Public Procurement Online&#xff09;是欧洲区域内的一个跨境公共采购电子商务平台试点项目&#xff0c;由欧盟委员会和Peppol联盟成员国共同资助建立&#xff0c;旨在通过制定标准化框架&#xff0c;推动欧盟成员国在公共采购相关的电子目录…...

Linux-GCC介绍+入门级Makefile使用

前言&#xff08;1&#xff09;我们都知道&#xff0c;在Linux中编译.c文件需要使用gcc -o .c文件的指令来将C文件变成可执行文件。但是我们有没有发现&#xff0c;如果我们需要编译大一点的工程&#xff0c;后面需要加上的.c文件是不是太多了&#xff1f;感觉非常的麻烦。&…...

iOS(一):Swift纯代码模式iOS开发入门教程

Swift纯代码模式iOS开发入门教程项目初始化&#xff08;修改为纯代码项目&#xff09;安装第三方库&#xff08;以SnapKit库为例&#xff09;桥接OC库&#xff08;QMUIKit&#xff09;封装视图并进行导航跳转示例&#xff1a;使用 TangramKit 第三方UI布局库应用国际化添加 R.s…...

IDEA+Python+Selenium+360浏览器自动化测试

环境配置前提&#xff0c;见文章https://mp.csdn.net/mp_blog/creation/editor/new?spm1001.2101.3001.4503下载360浏览器&#xff0c;并下载对应版本的chromedriver.exe&#xff0c;下载地址http://chromedriver.storage.googleapis.com/index.html下载好360浏览器&#xff0…...

运输层概述及web请求

运输层 运输层概述 运输层向高层用户屏蔽了下面网络核心的细节&#xff08;如网络拓扑、所采用的路由选择协议等&#xff09;它使应用进程看见的就好像是在两个运输层实体之间有一条端到端的逻辑通信信道&#xff1b; 根据需求不同&#xff0c;运输层提供两种运输协议 面向连…...

python与pycharm从零安装

python&#xff08;解释器&#xff09;下载地址&#xff1a;Welcome to Python.orgpycharm&#xff08;编译器&#xff09;下载地址&#xff1a;PyCharm: the Python IDE for Professional Developers by JetBrains一、python的下载与安装到官网后根据步骤下载安装包后&#xf…...

大语言模型如何处理长文本?常用文本分割技术详解

为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

基于Docker Compose部署Java微服务项目

一. 创建根项目 根项目&#xff08;父项目&#xff09;主要用于依赖管理 一些需要注意的点&#xff1a; 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件&#xff0c;否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验

系列回顾&#xff1a; 在上一篇中&#xff0c;我们成功地为应用集成了数据库&#xff0c;并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了&#xff01;但是&#xff0c;如果你仔细审视那些 API&#xff0c;会发现它们还很“粗糙”&#xff1a;有…...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

自然语言处理——循环神经网络

自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元&#xff08;GRU&#xff09;长短期记忆神经网络&#xff08;LSTM&#xff09…...

Mac下Android Studio扫描根目录卡死问题记录

环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中&#xff0c;提示一个依赖外部头文件的cpp源文件需要同步&#xff0c;点…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载&#xff0c;仅供自学使用&#xff0c;侵权必究&#xff0c;如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

基于Springboot+Vue的办公管理系统

角色&#xff1a; 管理员、员工 技术&#xff1a; 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能&#xff1a; 该办公管理系统是一个综合性的企业内部管理平台&#xff0c;旨在提升企业运营效率和员工管理水…...

(一)单例模式

一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...

PostgreSQL——环境搭建

一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在&#xff0…...