当前位置: 首页 > 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===解绑服务回调==


 

http://www.lryc.cn/news/31701.html

相关文章:

  • axios的get请求传入数组参数后端无法接收的问题
  • 奖金发放-课后程序(Python程序开发案例教程-黑马程序员编著-第3章-课后作业)
  • 第十四届蓝桥杯第三期模拟赛 【python】
  • Python——函数(重点内容)
  • 2023年如何在Google做外贸
  • Linux操作系统学习(线程池)
  • JVM运行时数据区—Java虚拟机栈
  • gitlab中文社区
  • 深度学习-第T2周——彩色图片分类
  • GNU C编译器扩展关键字:__attribute__
  • C++基础 | 从C到C++快速过渡
  • 【C++】仿函数 -- priority_queue
  • 盘一盘C++的类型描述符(一)
  • Peppol的发展史和基本框架
  • Linux-GCC介绍+入门级Makefile使用
  • iOS(一):Swift纯代码模式iOS开发入门教程
  • IDEA+Python+Selenium+360浏览器自动化测试
  • 运输层概述及web请求
  • python与pycharm从零安装
  • 叠氮试剂943858-70-6,Azidobutyric acid NHS ester,叠氮-C3-活性酯
  • pycharm激活虚拟环境时报错:无法加载文件activate.ps1,因为在此系统上禁止运行脚本,Windows10系统
  • 刷题小抄4-数组
  • Hbase安装
  • 面向对象设计模式:结构型模式之代理模式
  • CCF大数据专家委员会十周年纪念庆典纪实:拥抱数字时代,展望科技未来
  • Qt学习3-Qt Creator四则运算计算器(哔站视频学习记录)
  • 学习 Python 之 Pygame 开发魂斗罗(九)
  • 最简单的SpringBoot+MyBatis多数据源实现
  • Spring Boot 3.0系列【8】核心特性篇之SpringApplication
  • Nginx的搭建与核心配置