服务Service

一、服务概述

Service(服务)是Android四大组件之一,是能够在后台长时间执行操作并且不是供用户界面的应用程序组件。Senice可以与其他组件进行交互,一般由Activity启动,但是并不依赖于Activity。当Activity的生命周期结束时,Service仍然会继续运行直到自己的生命周期结束为止。
Service通常被称为“后台服务”,其中“后台”一词是相对于前台而言的,具体是指其本身的运行并不依赖于用户可视的UI界面。除此之外,Service还具有较长时间运行特性,它的应用场景主要有两个,分别是后台运行和跨进程访问。

1.后台运行:Senvice可以在后台长时间进行操作而不用提供界面信息,只有当系统必须要回收内存资源时,才会被毁,否则Service会一直在后台运行。

2.跨进程运行:当Senvice被其它应用组件启动时,即使用户切换到其它应用程序,服务仍将在后台继续运行。

Service总是在后台运行,其运行并不是在子线程而是在主线程中,只是它没有界面而已,它要处理的耗时操作需要开启子线程进行处理,否则程序会出现ANR(程序没有响应)异常。

Service 执行内容建议写于onCreate()方法中,该方法需自行重写。

二、服务的创建

选中程序包名,单击鼠标右键并选择[New] -> [Service] -> [Service]选项,在弹出的窗口中输入服务名称。创建好的服务如下例:

public class MyService extends Service {
    public MyService() {
        //构造方法
    }
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        //throw new UnsupportedOperationException("Not yet implemented");
        //用于绑定,返回的IBinder用于 程序与服务间的通信
    }
    public void onCreate() {
        //Service执行内容建议写于本方法,本方法需要自行重写
    }
}

上述代码中,创建的Nyfenice继承自Senvice,默认创建了一个构造函数Myservice(),重写了onBind()方法。onBind()方法是Service子类必须实现的方法,该方法返回一个IBinder对象,应用程序可通过该对象与Service组件通信
服务创建完成后,AndroidStudio会自动在AndroidManifest.xml文件中注册服务

例:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <application
        ... ... >

        ... ...

        <service
            android:name=".MyService"
            android:enabled="true"
            android:exported="true">

    </application>
</manifest>

enable属性表示是否可实例化exported属性表示是否可被其他程序中的组件调用或交互

三、服务的生命周期

与Activity类似,服务也有生命周期,服务的生命周期与启动服务的方式有关。服务的启动方式有两种,一种是通过 startService()方法 启动服务,另一种是通过 bindService()方法 启动服务。使用不同的方式启动服务,其生命周期会不同。


onCreate()  第一次创建服务时调用,Service 执行内容建议写于onCreate()方法中,该方法需自行重写。
onStartCommand()  调用startService()方法启动服务时执行的方法。
onBind()  调用bindSeruice()方法启动服务(绑定服务)时执行的方法。
onUnbind()  调用unBindService()方法断开服务绑定时执行的方法。
onDestory()  服务被销毁时执行的方法。

如果想停止通过 startService() 方法启动的服务,只需要通过服务自身调用 stopSelf() 或其它组件stopService();如果想停止通过bindService() 方法启动的服务,需要调用 unbindService() 方法将服务进行解绑。

四、服务的启动

1. startService()方法 (-> stopService()

//启动
Intent intent=new Intent(MainActivity.this,MyService.class);
startService(intent);

//关闭
Intent intent=new Intent(MainActivity.this,MyService.class);
stopService(intent);

2. bindService()方法 (-> unbindService() )

public class MyService extends Service {
    public MyService() {
        //构造方法
    }
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        //throw new UnsupportedOperationException("Not yet implemented");
        //用于绑定,返回的IBinder用于 程序与服务间的通信
        return new MyBinder();
    }

    class MyBinder extends Binder {
        // 该类存放用于控制服务的方法
        // 会传递给ServiceConnection
        public void callMethodInService(){

        }
        public void methodInService(){
            ... ...
        }
    }

    public void onCreate() {
        //Service执行内容建议写于本方法,本方法需要自行重写
    }
}
public class MainActivity extends AppCompatActivity {
    private Button bindbt,callbt,unbindbt;
    private MyService.MyBinder myBinder;
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        bindbt.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {

                MyConnection myConnection=new MyConnection();
                Intent intent=new Intent(MainActivity.this,MyService.class);
                bindService(intent,myConnection,Service.BIND_AUTO_CREATE);
                //bindService()第三个参数为绑定标准
                //Service.BIND_AUTO_CREATE 表示自动创建服务(服务不存在时),服务存在时不自动创建。
                
            }
        });
        callbt.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                //调用服务内置方法
                myBinder.callMethodInService();
            }
        });
        unbindbt.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                
                //解绑
                unbindService(myConnection);
                
            }
        });
    }

    //服务通道类
    private class MyConnection extends ServiceConnection {
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            //成功绑定服务时调用,iBinder为绑定时传入的MyBinder
            myBinder=(MyService.MyBinder) iBinder;
        }
        public void onServiceDisconnected(ComponentName componentName) {
            //服务失去连接时调用
        }
    }
}

四、服务的通信

服务的通信
通过调用 bindService() 方法开启服务后,服务与绑定服务的组件是可以通信的,通过组件可以控制服务并进行一些操作。
在Android中,服务的通信方式有两种,一种是本地服务通信,另一种是远程服务通信。本地服务通信是指应用程序内部的通信,远程服务通信是指两个应用程序之间的通信。使用这两种方式进行通信时必须保证服务以绑定方式开启,否则无法进行通信和数据交换。

1.本地服务通信

在使用服务进行本地通信时,首先需要创建一个Service类,该类会提供一个onBind()方法,onBind()方法的返回值是一个IBinder对象,IBinder对象会作为参数被传递给ServiceCorection类中的onServiceConnected(ComponentName name,IBinder senice)方法,这样访问者(绑定服务的组件)就可以通过IBinder对象与Service进行通信


由图可知,服务在进行通信时使用的是IBinder对象,在SenviceConnection类中得到IBinder对象,通过该对象可以获取到服务中自定义的方法,执行具体的操作。以绑定方式开启服务的案例实际上就用到了本地服务通信。

2、远程服务通信

在Android中,各个应用程序都运行在自己的进程中,如果想要完成不同进程之间的通信,就需要使用远程服务通信。远程服务通信是通过AIDL(Android.Interface DefinitionLanguage)实现的,它是一种按口定义语言(Interface Definition Language),其语法格式非常简单,与Java中定义按口类似,但是存在一些差异,具体介绍如下:
·AIDL定义接口的源代码必须以 .aidl 结尾。
·AIDL按口中用到的数据类型,除了基本数据类型String List Map Charsequence之外,其它类型全部都需要导入包,即使它们在同一个包中。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/115530.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

野火霸天虎 STM32F407 学习笔记_1 stm32介绍;调试方法介绍

STM32入门——基于野火 F407 霸天虎课程学习 前言 博主开始探索嵌入式以来&#xff0c;其实很早就开始玩 stm32 了。但是学了一段时间之后总是感觉还是很没有头绪&#xff0c;不知道在学什么。前前后后分别尝试了江协科技、正点原子、野火霸天虎三次 stm32 的课程学习。江协科…

学Python,一个月从小白到大神?看你怎么学!

Python是一门超强大而且超受欢迎的编程语言。它被用在各种领域&#xff0c;比如网站开发、数据分析、人工智能和机器学习。学会Python会给你创造很多职业机会&#xff0c;所以绝对是值得一试的。 但你有没有过这样的梦想&#xff1a;一个月时间&#xff0c;从Python小白变成Py…

Docker DeskTop安装与启动(Windows版本)

一、官网下载Docker安装包 Docker官网如下&#xff1a; Docker官网不同操作系统下载页面https://docs.docker.com/desktop/install/windows-install/ 二、安装Docker DeskTop 2.1 双击 Docker Installer.exe 以运行安装程序 2.2 安装操作 默认勾选&#xff0c;具体操作如下…

页面淘汰算法模拟实现与比较

1.实验目标 利用标准C 语言&#xff0c;编程设计与实现最佳淘汰算法、先进先出淘汰算法、最近最久未使用淘汰算法、简单 Clock 淘汰算法及改进型 Clock 淘汰算法&#xff0c;并随机发生页面访问序列开展有关算法的测试及性能比较。 2.算法描述 1. 最佳淘汰算法&#xff08;Op…

编写shell脚本,利用mysqldump实现mysql数据库分库分表备份

摘要&#xff1a;本文介绍了如何使用 Shell 脚本和 mysqldump 工具实现 MySQL 数据库的分库分表备份。通过编写脚本&#xff0c;我们可以自动化备份多个数据库以及每个数据库中的所有表&#xff0c;并将备份文件按照数据库和表的层次结构进行存储。 一、准备工作 在开始编写 Sh…

HMDD 4.0:miRNA-疾病关系数据库

拥有多项自主专利技 术和软件著作权&#xff0c;具 有丰富的数据库平台 搭建经验。 凌恩-盈飞团队 MicroRNA&#xff08;miRNA&#xff09;是一类重要的小非编码RNA&#xff0c;在疾病诊断和治疗中发挥着重要作用。人类 MicroRNA 疾病数据库 (HMDD) 为 miRNA 相关医学提供了…

【云原生基础】了解云原生,什么是云原生?

&#x1f4d1;前言 本文主要讲了云原生的基本概念和原则的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是青衿&#x1f947; ☁️博客首页&#xff1a;CSDN主页放风讲故事 &#x1f304;每日一句&#x…

人工智能师求职面试笔试题及答案汇总

人工智能师求职面试笔试题及答案汇总 1.如何在Python中实现一个生成器&#xff1f; 答&#xff1a;在Python中&#xff0c;生成器是一种特殊类型的迭代器。生成器允许你在需要时才生成值&#xff0c;从而节省内存。生成器函数在Python中是通过关键字yield来实现的。例如&…

leetCode 137. 只出现一次的数字 II(拓展篇) + 模5加法器 + 真值表(数字电路)

leetCode 137. 只出现一次的数字 II 有其他的题解可看我的往期文章&#xff1a; leetCode 137. 只出现一次的数字 II 位运算 模3加法器 真值表&#xff08;数字电路&#xff09; 有限状态机-CSDN博客https://blog.csdn.net/weixin_41987016/article/details/134138112?sp…

生成带分表和水印的excel压缩文件

功能描述 将查询结果生成带分表和水印的excel压缩文件 功能点 1、将查询结果导出为excel文件 2、每个表格存放50万条数据&#xff0c;超过50万条数据&#xff0c;生成新的分表 3、生成的表格需要添加水印 4、将生成的全部分表&#xff0c;打包成zip压缩文件 引入依赖 <…

【LeetCode】每日一题 2023_11_2 环和杆(题目质量不错)

文章目录 刷题前唠嗑题目&#xff1a;环和杆题目描述代码与解题思路看看别人的题解 结语 刷题前唠嗑 今天是简单&#xff0c;我快乐了 题目&#xff1a;环和杆 题目链接&#xff1a;2103. 环和杆 题目描述 代码与解题思路 func countPoints(rings string) (ans int) {num…

强化学习的动态规划二

一、典型示例 考虑如下所示的44网格。 图1 非终端状态为S {1, 2, . . . , 14}。在每个状态下有四种可能的行为&#xff0c;A {up, down, right, left}&#xff0c;这些行为除了会将代理从网格上移走外&#xff0c;其他都会确定性地引起相应的状态转换。因此&#xff0c;例如&…

java入门,程序=数据结构+算法

一、前言 在学习java的时候&#xff0c;我印象最深的一句话是&#xff1a;程序数据结构算法&#xff0c;对于写java程序来说&#xff0c;这就是java的入门。 二、java基本数据结构与算法 1、数据类型 java中的数据类型8种基本数据类型&#xff1a; 整型 byte 、short 、int…

32 mysql in 的实现

前言 这里我们主要是来探讨一下 mysql 中 in 的使用, find_in_set 的使用 这两者 在我们实际应用中应该也是 非常常用的了 测试数据表如下 CREATE TABLE tz_test (id int(11) unsigned NOT NULL AUTO_INCREMENT,field1 varchar(16) DEFAULT NULL,field2 varchar(16) DEFAU…

macOS 下 starUML 软件激活方案

starUML每次打开都弹出提示其实挺烦的&#xff0c;于是研究了一下如何 po 解(激活)它。记录一下方法以便以后使用。 我觉得这个软件很好用&#xff0c;大型项目的所有图我都是用这个软件画的。 直接上步骤&#xff01;先关掉starUML 1、安装 asar&#xff0c;以便可以打开 asa…

4+1视图的理解和使用

软件架构 原文&#xff1a; Architectural Blueprints—The “41” View Model of Software Architecture 老外的原文还是很值得一看的&#xff0c;互联网上的很多文章理解得都比较粗浅 什么是软件架构&#xff1f;面试的时候很多面试官可能会问你最近在做的项目的架构。其实这…

通讯录(C语言文件版本)(超详细过程)

❇️❇️❇️❇️❇️❇️❇️❇️❇️❇️❇️❇️❇️ ❇️❇️❇️❇️ 不同的信念 ❇️❇️❇️❇️ ❇️❇️❇️ 决定不同的命运 ❇️❇️❇️ ❇️❇️❇️❇️❇️❇️❇️❇️❇️❇️❇️❇️ &#x1f4d6;通讯录 ✅具备的功能 ℹ️需要的头文件名 #include<…

警惕Mallox勒索病毒的最新变种mallox,您需要知道的预防和恢复方法。

尊敬的读者&#xff1a; 在这个数字时代&#xff0c;恶意软件不再是仅限于技术领域的威胁&#xff0c;而是每个人都可能面临的潜在风险。其中&#xff0c;.mallox勒索病毒崭露头角&#xff0c;它不仅能够以不可思议的方式加密您的数据&#xff0c;还能要求您支付赎金以获取解密…

基于饥饿游戏算法的无人机航迹规划-附代码

基于饥饿游戏算法的无人机航迹规划 文章目录 基于饥饿游戏算法的无人机航迹规划1.饥饿游戏搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要&#xff1a;本文主要介绍利用饥饿游戏算法来优化无人机航迹规划。 …

运维基础-Docker容器命令部署

Docker基础知识 安装问题-有podmanCentos8使用yum install docker -y时&#xff0c;默认安装的是podman-docker软件安装docker yum list installed | grep dockeryum -y remove xxxxDocker安装配置下载安装docker启动docker&#xff0c;并设置开机启动下载所需镜像 centos镜像进…