深入分析 Android Service (五)

文章目录

    • 深入分析 Android Service (五)
    • 1. 深入分析 Service 与 Activity 之间的通信
    • 2. Messenger 的内部工作原理
      • 2.1 服务端实现
      • 2.2 客户端实现
    • 3. AIDL 的内部工作原理
      • 3.1 定义 AIDL 接口
      • 3.2 服务端实现
      • 3.3 客户端实现
    • 4. Service 的优化建议和最佳实践
      • 4.1 异步操作
      • 4.2 资源管理
      • 4.3 前台服务
      • 4.4 权限管理
    • 5. 使用场景和总结

深入分析 Android Service (五)

1. 深入分析 Service 与 Activity 之间的通信

前面我们介绍了通过 MessengerAIDL 实现 ServiceActivity 之间的通信。接下来,我们将进一步深入分析这些通信机制的内部工作原理和设计思想。

2. Messenger 的内部工作原理

Messenger 是基于 Handler 实现的轻量级进程间通信(IPC)机制。它利用 Binder 传递消息。下面是 Messenger 工作的详细流程:

  1. 创建 Messenger 和 Handler

    • 服务端创建一个 Handler,用于处理客户端发送的消息。
    • 使用这个 Handler 创建一个 Messenger 对象,并通过 Binder 返回给客户端。
  2. 绑定服务

    • 客户端通过 bindService 方法绑定服务,获取服务端的 Messenger 对象。
  3. 发送消息

    • 客户端通过 Messenger.send(Message msg) 方法发送消息到服务端。
    • 消息通过 Binder 通道传递到服务端的 Handler 进行处理。

以下是服务端和客户端实现的具体代码示例:

2.1 服务端实现

public class MessengerService extends Service {static final int MSG_SAY_HELLO = 1;class IncomingHandler extends Handler {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case MSG_SAY_HELLO:Toast.makeText(getApplicationContext(), "Hello!", Toast.LENGTH_SHORT).show();break;default:super.handleMessage(msg);}}}final Messenger messenger = new Messenger(new IncomingHandler());@Overridepublic IBinder onBind(Intent intent) {return messenger.getBinder();}
}

2.2 客户端实现

public class MainActivity extends AppCompatActivity {Messenger messenger = null;boolean isBound = false;private ServiceConnection connection = new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {messenger = new Messenger(service);isBound = true;}@Overridepublic void onServiceDisconnected(ComponentName name) {messenger = null;isBound = false;}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Intent intent = new Intent(this, MessengerService.class);bindService(intent, connection, Context.BIND_AUTO_CREATE);Button sendButton = findViewById(R.id.sendButton);sendButton.setOnClickListener(v -> {if (isBound) {Message msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0);try {messenger.send(msg);} catch (RemoteException e) {e.printStackTrace();}}});}@Overrideprotected void onDestroy() {super.onDestroy();if (isBound) {unbindService(connection);isBound = false;}}
}

3. AIDL 的内部工作原理

AIDL(Android Interface Definition Language)是一种定义接口的语言,用于进程间通信(IPC)。它允许在不同进程间传递复杂的数据结构。AIDL 的内部工作原理如下:

  1. 定义 AIDL 接口

    • 开发者使用 .aidl 文件定义接口和方法。
  2. 编译生成代码

    • 编译器生成用于 IPC 的 StubProxy 类。
  3. 实现 AIDL 接口

    • 服务端实现 Stub 类,处理客户端请求。
  4. 绑定服务

    • 客户端通过 bindService 方法绑定服务,获取 StubProxy 对象。
  5. 调用远程方法

    • 客户端通过 Proxy 对象调用远程方法,方法调用通过 Binder 通道传递到服务端的 Stub 类进行处理。

以下是详细的实现代码示例:

3.1 定义 AIDL 接口

package com.example;interface IMyAidlInterface {int add(int a, int b);
}

3.2 服务端实现

public class MyAidlService extends Service {private final IMyAidlInterface.Stub binder = new IMyAidlInterface.Stub() {@Overridepublic int add(int a, int b) {return a + b;}};@Overridepublic IBinder onBind(Intent intent) {return binder;}
}

3.3 客户端实现

public class MainActivity extends AppCompatActivity {IMyAidlInterface myAidlService = null;boolean isBound = false;private ServiceConnection connection = new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {myAidlService = IMyAidlInterface.Stub.asInterface(service);isBound = true;}@Overridepublic void onServiceDisconnected(ComponentName name) {myAidlService = null;isBound = false;}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Intent intent = new Intent(this, MyAidlService.class);bindService(intent, connection, Context.BIND_AUTO_CREATE);Button addButton = findViewById(R.id.addButton);addButton.setOnClickListener(v -> {if (isBound) {try {int result = myAidlService.add(5, 3);Toast.makeText(MainActivity.this, "Result: " + result, Toast.LENGTH_SHORT).show();} catch (RemoteException e) {e.printStackTrace();}}});}@Overrideprotected void onDestroy() {super.onDestroy();if (isBound) {unbindService(connection);isBound = false;}}
}

4. Service 的优化建议和最佳实践

4.1 异步操作

为了避免阻塞主线程,在 Service 中处理耗时操作时,应使用异步任务或线程池。例如,使用 AsyncTaskExecutorService 来处理后台任务。

4.2 资源管理

确保在 Service 停止时释放所有资源,避免内存泄漏。例如,在 onDestroy 方法中关闭任何打开的资源(如文件、网络连接等)。

4.3 前台服务

对于需要长期运行的服务,使用前台服务,并提供持续显示的通知,确保服务在系统资源紧张时不被杀死。

@Override
public void onCreate() {super.onCreate();executorService = Executors.newSingleThreadExecutor();// Create the notification channel for Android O and aboveif (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {NotificationChannel channel = new NotificationChannel("download_channel", "Download Service", NotificationManager.IMPORTANCE_DEFAULT);NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);if (manager != null) {manager.createNotificationChannel(channel);}}// Start foreground serviceNotification notification = new NotificationCompat.Builder(this, "download_channel").setContentTitle("Downloading").setContentText("Downloading in progress").setSmallIcon(R.drawable.ic_download).build();startForeground(1, notification);
}

4.4 权限管理

在需要与其他应用通信的 Service 中,确保使用适当的权限保护机制,防止未授权访问。例如,使用 android:permission 属性限制哪些应用可以绑定服务。

<service android:name=".MyAidlService"android:permission="com.example.myapp.permission.BIND_MY_SERVICE"><intent-filter><action android:name="com.example.myapp.BIND" /></intent-filter>
</service>

5. 使用场景和总结

Service 在 Android 应用中的使用场景广泛,包括但不限于:

  • 后台音乐播放:使用 Service 处理音乐播放任务,即使用户离开了应用界面,音乐也可以继续播放。
  • 数据同步:使用 Service 定期同步数据,如邮件、联系人、日历等。
  • 位置跟踪:使用 Service 持续获取并处理位置信息,实现位置跟踪功能。
  • 文件下载:使用 Service 在后台下载大文件,并在下载完成后通知用户。
  • 网络请求:使用 Service 处理长时间运行的网络请求,避免阻塞主线程。

通过深入理解和合理设计 Service,可以有效地提升 Android 应用的性能和用户体验。无论是简单的异步任务,还是复杂的跨进程通信,通过合理使用 Service,结合具体需求进行优化,是构建高效、稳定的 Android 应用的重要一环。希望以上示例和详细说明能够帮助开发者更好地理解和使用 Service,实现更强大和高效的应用功能。

欢迎点赞|关注|收藏|评论,您的肯定是我创作的动力

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Linux】权限的概念

1.Linux权限的概念 Linux下有两种用户&#xff1a;超级用户&#xff08;root&#xff09;、普通用户。 超级用户&#xff1a;可以再linux系统下做任何事情&#xff0c;不受权限限制 普通用户&#xff1a;在linux下做有限的事情&#xff0c;受权限设置。 windows下也有超级用户…

Hbase 面试题(二)

1. 阐述HBase有哪些不同的关键组件&#xff1f; HBase是一个分布式的、面向列的NoSQL数据库&#xff0c;它由多个关键组件构成&#xff0c;这些组件共同工作以提供其服务。以下是HBase中一些主要的关键组件&#xff1a; HMaster&#xff1a; HMaster负责管理集群的元数据和状态…

fmc编程入门:探索、挑战与成长之路

fmc编程入门&#xff1a;探索、挑战与成长之路 在当今数字化时代&#xff0c;编程已成为一项重要的技能。而fmc编程&#xff0c;作为一种新兴的编程方式&#xff0c;正逐渐受到人们的关注。本文将从四个方面、五个方面、六个方面和七个方面来深入剖析fmc编程的入门之道&#x…

Object.entries方法的使用

Object.entries() 方法返回一个给定对象自身可枚举属性的键值对数组。 有以下需求&#xff1a; let cpuData reactive([{ label: 总量, content: test },{ label: 已使用, content: test },{ label: 未使用, content: test } ])<el-form label-position"left" l…

环卫车北斗GPS视频监控定位解决方案的应用与优势

一、引言 随着城市化进程的加快&#xff0c;环卫车作为城市环境卫生的重要保障力量&#xff0c;其运行效率与安全性直接关系到城市形象与居民生活品质。然而&#xff0c;传统的环卫车管理模式往往存在信息不对称、调度不合理、行驶不规范等问题&#xff0c;导致城市道路污染和…

微信小程序对接发货功能

注&#xff1a;微信小程序对接发货功能 文档地址&#xff1a;https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/order-shipping/order-shipping.html php代码 common.php use think\Config; use think\Db; use fast\Http; us…

LabVIEW远程开发与调试

在现代项目开发中&#xff0c;远程开发与调试已经成为一种常见的模式&#xff0c;特别是在使用LabVIEW进行工程项目时。本文将详细分析LabVIEW远程开发与调试的优缺点&#xff0c;并从多个角度说明如何建议客户采用这种方式&#xff0c;以提高项目效率和质量。 优点 灵活性和便…

Compose进阶——在非Compose作用域调用Compose函数

第一版&#xff0c;实现在非Compose作用域调用Compose函数&#xff1a; Composable fun test() {val fun1 Composable() {rememberTextMeasurer()}val test1 rememberTextMeasurer()val composer currentComposerButton(onClick {// 这是非Compose作用域&#xff0c;在此通…

2024华为OD机试真题-机场航班调度-C++(C卷D卷)

题目描述 XX 市机场停放了多架飞机,每架飞机都有自己的航班号 CA3385,CZ6678,SC6508 等, 航班号的前 2 个大写字母(或数字)代表航空公司的缩写,后面 4 个数字代表航班信息。 但是 XX 市机场只有一条起飞用跑道,调度人员需要安排目前停留在机场的航班有序起飞。 为保障航班…

Linux【安全 02】OpenSSH漏洞修复(离线升级最新版本流程)网盘分享3个安装包+26个离线依赖

OpenSSH离线升级最新版本流程 1. 漏洞信息2. 环境说明3.依赖安装3.1 在线安装3.2 离线安装 4.备份卸载4.1 备份4.2 卸载旧版本 5.安装5.1 zlib5.2 ssl5.3 openssh5.3.1 安装5.3.2 配置 6.脚本整理7.文件资源 本文仅针对CentOS7.8版本&#xff0c;其他版本未测试&#xff0c;安装…

# 使用 nmtui 命令工具管理 linux 网络,给网卡配置多个 IP 地址

使用 nmtui 命令工具管理 debian 系统 网络&#xff0c;给网卡配置多个 IP 地址 1、nmtui 是什么&#xff1f; nmtui 是 NetworkManager TUI&#xff08;Text User Interface&#xff09;的缩写&#xff0c;它提供了一个可视化的界面来管理网络连接。但是&#xff0c;在 Debi…

GSM信令流程(附着、去附着、PDP激活、修改流程)

1、联合附着流程 附着包括身份认证、鉴权等 2、去附着流程 用户发起去附着 SGSN发起去附着 HLR发起去附着 GSSN使用S4发起去附着 3、Activation Procedures(PDP激活流程) 4、PDP更新或修改流程 5、Deactivate PDP Context 6、RAU(Routeing Area Update)流程 7、鉴权加…

生成式AI,在云端的绽放与盛开

编辑&#xff1a;阿冒 设计&#xff1a;沐由 毫无疑问&#xff0c;生成式AI已然成为当今技术发展和应用创新的重要引擎之一。 过去的一年多时间里&#xff0c;我们每个人都在目睹和见证着生成式AI是如何以移山倒海的力量&#xff0c;为诸多行业带来革命性乃至颠覆性的变革&…

新版校园跑腿外卖独立版+APP+小程序前端外卖配送平台源码

同城校园跑腿外卖配送平台源码&#xff0c;这套目前全网还没有人分享过&#xff0c;这个是开源的&#xff0c;所以没有任何问题了&#xff0c;这套源码非常吊&#xff0c;支持自定义diy 你可以设计你的页面&#xff0c;设计你自己的风格&#xff0c;支持多校园&#xff0c;独立…

联软安全助手卸载教程

目录 1.前言 2.卸载联软安全助手 2.1 尝试杀死联软安全助手进程

Spring Boot集成Spring Task Scheduler快速入门demo

1.Spring Task Scheduler介绍 Spring Scheduler里有两个概念&#xff1a;任务&#xff08;Task&#xff09;和运行任务的框架&#xff08;TaskExecutor/TaskScheduler&#xff09;。TaskExecutor顾名思义&#xff0c;是任务的执行器&#xff0c;允许我们异步执行多个任务。Tas…

前端工程化工具系列(三) —— Stylelint(v16.6.1):CSS/SCSS 代码质量工具

Stylelint 是 CSS/SCSS 代码的静态分析工具&#xff0c;用于检查代码中的错误和样式违规。 1. 环境要求 v16 以上的 Stylelint&#xff0c;支持 Node.js 的版本为 v18.12.0。 在命令行中输入以下内容来查看当前系统中 node 的版本。 node -vNode.js 推荐使用 v18.20.3 或者 …

深度学习中的模型架构详解:RNN、LSTM、TextCNN和Transformer

深度学习中的模型架构详解&#xff1a;RNN、LSTM、TextCNN和Transformer 文章目录 深度学习中的模型架构详解&#xff1a;RNN、LSTM、TextCNN和Transformer循环神经网络 (RNN)RNN的优点RNN的缺点RNN的代码实现 长短期记忆网络 (LSTM)LSTM的优点LSTM的缺点LSTM的代码实现 TextCN…

海外金融牌照

一般来说牌照申请分两个大类&#xff1a;数字货币牌照和外汇牌照。每个国家的牌照具体监管的情况也是不一样的。申请牌照时该如何选择&#xff1f; 今天先说说区块链牌照&#xff0c;具有代表性的有美国msb牌照&#xff0c;加拿大msb牌照&#xff0c;爱沙尼亚数字货币牌照&…

mac电脑安卓设备文件传输助手:MacDroid pro 中文激活版

MacDroid Pro是一款专为Mac电脑和Android设备设计的软件&#xff0c;旨在简化两者之间的文件传输和数据管理&#xff0c;双向文件传输&#xff1a;支持从Mac电脑向Android设备传输文件&#xff0c;也可以将Android设备上的文件轻松传输到Mac电脑上。完整的文件访问和管理&#…