您好!欢迎来到爱源码

爱源码

热门搜索: 抖音快手短视频下载   

Android开发IPC进程通信详解 [网站源码]

  • 时间:2022-09-08 01:24 编辑: 来源: 阅读:331
  • 扫一扫,手机访问
摘要:Android开发IPC进程通信详解 [网站源码]
来源:微信微信官方账号-谢宁科技原作者:西井村夫参考链接:https://mp.weixin.qq.com/s/bjaC0tSB0R87kFZSe_G8sA本文已获原作者授权发布。如需转载,请联系作者获得授权。 据说以前的应用层开发者想要在Android端更上一层楼,必须掌握Android的基础知识,启动流程,编译打包apk的过程,Android框架层的实现原理。逐渐需要熟悉Android的四个组件的深层通信流程和原理,以及Android构建工具gradle的实现原理,这就像是应用层高级工程师的一扇门,但这扇门对于应用层初学者来说是极其坚实的。 这篇文章旨在为我们学习Android的运行机制打下一个基础,因为它包括了启动过程(理解后,可以做启动优化),四个组件的交互,以及最常见的Hanlder。 通过这些研究,你的应用可以实现最直观的启动优化。 比如在很多应用的后续使用中,除了默认的进程之外,还会启动少量的服务进程(有三方类似的推送,或者我们自己创建的其他服务进程)。当应用程序从启动桌面启动时(可以在性能测试中看到,或者自己调试),系统创建应用程序默认进程(与applicationId一致),然后在应用程序进程中做少量必要的初始化工作。大多数初始化工作是缺省过程所必需的。 也就是说,当我们安全快速的做好所有单个进程(ApplicationId同名的进程)的初始化,就实现了从最初的4-5s到后来的2-3s的应用,纯原生鱼雷基本不到2s(自动着陆接口响应需要1s以上)。如果再配合其他几个优化方法,画面就太好了。 什么?你觉得推广2s没用?你没见过启动页面十几个广告凑在一起。至于显示,我们不管,但是你必须全部初始化。如果代码任性,超过10s是常事(初始化太多不在讨论范围内),正常到3s差别还是很大的。 你只做默认做的工作,每个流程你都做;而且和多进程多线程一样,在操作数据的时候也要考虑到安全性。这些问题将在后面讨论。 在这里,我们将正式开始讲解Binder的通信机制和流程所涉及的相关内容(本文如有误解,欢迎不吝赐教):一、进程间通信的方式有很多种。这里主要详细介绍Android进程间通信绑定器的特点和实现过程。在Android中,一个进程通常不能访问另一个进程的内存。 为了进行通信,进程需要将其对象分解为操作系统可以理解的原语,并将其分组为开发人员可以操作的对象。 如果开发者直接编写代码来执行这个操作很繁琐,Android引入了AIDL来为你解决这个问题。 首先,对AIDL(Android Interface Definition Language,Android界面定义语言)的界面定义语言进行了概括性的详细描述。 它可用于定义客户端和服务都可以识别的编程接口,以便它们可以使用IPC相互通信。 在学习Binder通信之前,强烈建议了解aidl的实现过程。通过学习aidl的整个工作过程,我们会对进程通信过程有一个大致的概念,有利于对底层执行的命令,调用接口,执行上层写/读的相应理解。后面学习底层流程,就像验证每个流程的更深层次的实现。 比如C/S端通信以transact/onTransact方法实现数据交互,消息源选择、数据类型、数据读写的特点一目了然;鉴于篇幅,请自行了解aidl的实现过程,尽量做到了如指掌(可以看《Android开发艺术查询》和张弘扬的博客)。 特点:安全性,相对于socket/ pipeline通信方式,Binder通信过程中,系统每创建一个进程都会分配相应的Pid和Uid(该特性也可用于多进程项目的某些方向的区分和优化),进程间进程ID匹配确认消息来源;传输性能高,数据传输不需要tcp协议的三次握手,传输过程只需要一份拷贝;操作简单,虽然共享内存不需要复制,但是实现相对复杂。 2.了解内存映射函数mmap和读写数据接口ioctlmmap是用来建立客户端空间和内核空间的映射关系,从而共享映射内存空间中的数据;建立了映射关系的不同内存空间中的数据操作会被映射到其他建立了关系的内存空间中,被映射的内存空间可以直接使用数据。 对应关系如下图所示:ioctl是在底层和应用层之间定义的接口协议(用于操作写/读数据),不提供单独的读/写接口。一个调用可以用来写和读数据,可以满足数据交互和同步。 假设需要写入/读取数据(write_size和read_size都大于0),在写入和读取的过程中,write_buffer中的数据先写入Binder;然后等待数据同步返回,从Binder中读取数据并存储在read_buffer中,其中写/读以Binder为操作对象。 因为BINDER_WRITE_READ命令包含了写入和读取数据两个步骤,而能否进行写入和读取操作是根据BINDER的write_size和read_size来决定的。 如果是写,只需设置Binder的write_size大于0,read_size等于0即可;只要阅读情况是一样的。 第三,进程通信的C/S端使用Binder通信进程来写/读和传输数据以获得细节。在aidl操作的过程中,我们有不同的写和读方法,但是底层命令是直接一次性执行的,按照顺序进行写和读来决定是否需要执行(write_size/read_size)。 比如服务器/客户端进行写/读后,进入等待接收数据的状态,接收到数据后,进行相应的操作,响应回复。 写/读数据:调用TRANSITION命令执行客户端向服务器发送数据请求,s从数据体数据中取出数据,然后调用REPLY做出相应的响应(响应的数据也可以根据是否能对应到进程ID来回答) 数据读取过程涉及SPAWN_LOOPER,用于管理Binder数据读取端的线程池。当所有线程都有任务要执行,并且没有超过这个SET_MAX_THREADS的最大线程数时,就要求接收方创建更多的线程来等待任务(looper在这里也确认了为什么先写这个,然后关联到handler) Binder写/读的数据结构都是binder_transaction_data,包含上面的,比如接收方用来确认发送方的进程id和客户id,data_size缓冲区中存储的数据长度(由发送方设置,接收方用来确定接收的数据大小)。 系统为每个应用分配一定的内存(虽然应用可以自行配置,但不能超过系统能分配的最大值),每次解完之后都会释放BUFFER_FREE命令。 上面我们提到了mmap()映射函数。在绑定器通信的写/读过程中,采用接收数据缓存的动态分配和释放。 程序解决了某个缓冲区的数据后,底层会调用命令释放缓冲区,否则缓冲区会耗尽,无法接收数据。 关于binder的C/S通信,可以概括为:客户端对函数参数进行封装,通过transact()中的服务端Binder向服务器发送数据包请求,等待数据返回,服务端通过onTransact()中的客户端Binder获取binder_transaction_data的数据,取出进程id等数据进行相应求解,并回复客户端。 在解释这一段内容时,提到了使用对方客户端/服务器的Binder进行数据操作,实现数据交互。 本质上,在底层,进程是通过ServiceManager(以下简称SMgr)注册的,使用时可以直接在注册表中查找,即可以实现两端持有对方的引用(可以暂时知道对象的引用遍地都是)。因为应用级实现不需要修改底层代码,所以这也是一个容易理解的说法。 在客户端与服务器的通信过程中,SMgr类似于域名服务器。当客户端向服务器发出请求时,SMgr找到初始进程对应的Binder引用(就像在域名服务器中找到域名对应的主机)进行写/读。 SMgr流程的转换和Binder的创建如下图所示:通信主要由服务器、客户端、SMgr和Binder驱动四部分组成。前两部分是需要实现通信的两端。驱动程序负责将服务器端的Binder相关信息以数据包的形式发送给SMgr。SMgr收到数据包后分析数据并注册服务器端的Binder引用,然后SMgr会负责在Binder的注册中查找每个进程对应的Binder引用。 流程大致如下:服务器创建Binder实体后,通过驱动程序以transaction_data packet的形式发送给SMgr,并通过SMgr向内核Binder注册表注册相应的引用。 发送和注册引用的具体过程如下:绑定器实体创建后,驱动会在内核中创建其对应的实体节点和绑定器引用,用于传递给SMgr,然后将实体信息和新创建的绑定器内核引用等信息传递给SMgr。SMgr进程解析数据并将引用插入Binder注册表,以便客户端可以在表中查找引用并执行write_buffer/read_buffer之类的操作。 其他进程发送数据,SMgr接收数据并执行注册进程,如下图所示:其实要完成上面的进程,首先Server和SMgr还涉及进程间通信,SMgr可以理解为系统的默认进程。当其他进程与SMgr通信时,SMgr充当服务器端;那么SMgr与服务器通信时,SMgr中谁传递了Binder引用就需要它注册,那么谁注册自己的Binder呢?例如,SMgr流程是项目经理,其他流程是项目组织的成员,项目经理赋予每个人完成工作的权力(Binder)。那么项目经理在分配权限时,权力从何而来?管理层必须赋予他责任。 接下来解释一下SMgr的Binder引用从何而来。当一个进程执行BINDER_SET_CONTEXT_MGR命令将自己注册为SMgr进程时,驱动程序会为该进程创建一个BINDER实体(引用号为0),其他所有进程都可以获得该引用,所以系统只能有一个SMgr进程。 当任何后续进程向SMgr注册Binder时,它必须通过该引用(SMgr的Binder实体引用)与SMgr进程通信。 进程注册和进程间通信的全过程可以大致理解为SMgr作为主导注册/搜索来写/读对应的Binder对象,如下图所示:因此,进程间通信可以分为SMgr和其他进程、服务器、客户端和SMgr。 本质上,它们都使用相应进程的Binder对象来实现写/读操作。 区别在于进程对应的Binder对象:前者在系统注册时会被设置为引用号0;后者需要SMgr(Binder Object Management Center)注册,然后根据定义的键取出注册表中对应进程的Binder引用来执行操作。 这里我们扩展一下通信过程中的线程交互(关于Handler的内容后面会更详细的解释),如下图:本文参考文献:https://blog . csdn . net/aug fun/article/details/82343249 https://baike . Baidu . com/item/mmap/132229 fr = aladdinhttps://baike . Baidu . com/item/ioctl/6392403?fr = aladdinhttps://developer . Android . Google . cn/guide/components/aidl . html?HL = zh-cn http://www . jcode project . com/a/anzhuokaifa/androidkaifa/2015/0319/2619 . html https://www.zhihu.com/question/20122137/answer/14049112读者感谢您的支持,特别是准备了少量的珍藏资料,包括:Android学习PDF+架构视频+访谈文档+源码笔记、高级架构技术、高级脑图、Android开发访谈专题资料、高级架构资料,如有需要可以去GitHub免费获取!


  • 全部评论(0)
资讯详情页最新发布上方横幅
最新发布的资讯信息
【技术支持|常见问题】1556原创ng8文章搜索页面不齐(2024-05-01 14:43)
【技术支持|常见问题】1502企业站群-多域名跳转-多模板切换(2024-04-09 12:19)
【技术支持|常见问题】1126完美滑屏版视频只能显示10个(2024-03-29 13:37)
【技术支持|常见问题】响应式自适应代码(2024-03-24 14:23)
【技术支持|常见问题】1126完美滑屏版百度未授权使用地图api怎么办(2024-03-15 07:21)
【技术支持|常见问题】如何集成阿里通信短信接口(2024-02-19 21:48)
【技术支持|常见问题】算命网微信支付宝产品名称年份在哪修改?风水姻缘合婚配对_公司起名占卜八字算命算财运查吉凶源码(2024-01-07 12:27)
【域名/主机/服务器|】帝国CMS安装(2023-08-20 11:31)
【技术支持|常见问题】通过HTTPs测试Mozilla DNS {免费源码}(2022-11-04 10:37)
【技术支持|常见问题】别告诉我你没看过邰方这两则有思想的创意广告! (2022-11-04 10:37)

联系我们
Q Q:375457086
Q Q:526665408
电话:0755-84666665
微信:15999668636
联系客服
企业客服1 企业客服2 联系客服
86-755-84666665
手机版
手机版
扫一扫进手机版
返回顶部