深入分析 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下也有超级用户…

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;以提高项目效率和质量。 优点 灵活性和便…

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;安装…

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;独立…

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

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

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

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

机器学习笔记 - PyTorch 分布式训练概览

一、简述 对于大规模的数据集,只能进行分布式训练,分布式训练会尽可能的利用我们的算力,使模型训练更加高效。PyTorch提供了Data Parallel包,它可以实现单机、多GPU并行。 PyTorch 数据并行模块的内部工作原理 上面的图像说明了PyTorch 如何在单个系统中利用多个 G…

目标检测——无人机搜索救援数据集

引言 亲爱的读者们&#xff0c;您是否在寻找某个特定的数据集&#xff0c;用于研究或项目实践&#xff1f;欢迎您在评论区留言&#xff0c;或者通过公众号私信告诉我&#xff0c;您想要的数据集的类型主题。小编会竭尽全力为您寻找&#xff0c;并在找到后第一时间与您分享。 …

springboot项目banner生成器

Spring Boot banner在线生成工具&#xff0c;制作下载英文banner.txt&#xff0c;修改替换banner.txt文字实现自定义&#xff0c;个性化启动banner-bootschool.netSpring Boot banner工具实现在线生成banner&#xff0c;轻松修改替换实现自定义banner&#xff0c;让banner.txt文…

基于Lumerical fdtd进行无序光子晶体波导的仿真设计及优化

光子晶体是一类通过不同折射率介质周期性的排列而形成的具有光波长量级的周期性人工微型结构&#xff0c;相比于传统晶体来说&#xff0c;由于介电函数的周期性分布&#xff0c;光子晶体也会产生一些类似于传统晶体的带隙&#xff0c;使光局域在带隙中无法传播。我们在完整的光…

Linux - 文件管理高级2

3.处理字符 sed ① sed 默认情况下不会修改原文件内容 ② sed 是一种非交互式的编辑器 3.1 工作原理 将原文件一行一行的进行处理&#xff0c;取出一行&#xff0c;放入“模式空间进行处理”&#xff0c;处理完成之后将结果输出到屏幕上&#xff0c;然后读取下一行&#xf…

智慧启航 网联无限丨2024高通汽车技术与合作峰会美格智能分论坛隆重举行

5月30日下午&#xff0c;以“智慧启航 网联无限”为主题的2024高通汽车技术与合作峰会&美格智能分论坛在无锡国际会议中心隆重举行&#xff0c;本次论坛由高通技术公司与美格智能技术股份有限公司共同主办&#xff0c;上海市车联网协会、江苏省智能网联汽车产业创新联盟、江…

一键分割视频并生成M3U8格式:高效管理视频内容,畅享流畅播放新体验

视频内容已成为我们日常生活和工作中的重要组成部分。无论是个人分享生活点滴&#xff0c;还是企业宣传产品与服务&#xff0c;视频都以其直观、生动的形式&#xff0c;吸引着我们的眼球。然而&#xff0c;随着视频内容的不断增多&#xff0c;如何高效、便捷地管理这些视频&…

如何让Google收录网站?

Google收录网站的前提条件是确保网站可以公开访问&#xff0c;并且页面加载速度需要快&#xff0c;这样Google爬虫才可以访问到你的网站&#xff0c;并且索引你网站中的内容。实现了上面的前提条件&#xff0c;可以通过优化数据结构、创建站点地图、使用Google Search Console、…

【机器学习】智能选择的艺术:决策树在机器学习中的深度剖析

在机器学习的分类和回归问题中&#xff0c;决策树是一种广泛使用的算法。决策树模型因其直观性、易于理解和实现&#xff0c;以及处理分类和数值特征的能力而备受欢迎。本文将解释决策树算法的概念、原理、应用、优化方法以及未来的发展方向。 &#x1f680;时空传送门 &#x…