首页 文章 精选 留言 我的

精选列表

搜索[计算机组成原理],共10000篇文章
优秀的个人博客,低调大师

android 进程间通信原理

前言 每个Android进程只能运行在自己拥有的虚拟地址空间,对于用户空间。不同进程之间彼此是不能共享的,而内核空间是可以共享的。Client和Server进程通信就是利用进程间可以共享内核内存空间来完成底层通信工作的,Client和Server通过ioctl等和内核空间进行交互。 进程通信架构 1、android的IPC和RPC RPC指的是跨进程远程调用,强调了调用的功能,即一个进程之间调用另外一个进程的方法。 IPC指的是进程间通信,android使用Binder机制来进行进程间的通信,没有调用的功能。 Android系统的RPC = Binder进程间通信+在Binder基础上建立起来的进程间函数调用机制。 2、android系统的RPC实现 RPC架构图 Android的RPC主要包含Client、Server和ServiceManager。android中使用ServiceManager来管理所有的所有的Server。ServiceManger启动后首先告诉Binder驱动,将自己标识为ServiceManager。在创建一个Server后,首先通过addService将自己交给ServiceMager管理,Client在需要调用Server时直接通过getService到ServiceManager中查找对应的Server,然后调用Server的方法。 下图给出binder在android中的整体架构,从framework到native再到kernel: Binder整体架构 图中红色部分代表整个framework层binder架构的相关组件,Binder类代码Server端,BinderProxy代表客户端。蓝色代码Native层的Binder架构组件。上层framewoek的binder逻辑建立在native层架构的基础之上,核心逻辑都是交给native处理的。Framework的ServiceManager与native的ServiceManager并不完全对应,framework层的ServiceManager类的实现最终是通过BinderProcy传递给native层来完成的。 Server启动后会开启一个线程不停的读取Binder驱动的读接口,这是一个阻塞调用;在需要响应客户端的时候,会调用Binder驱动的写接口进行数据返回。 Client启动后会不停读取Binder驱动的读接口并阻塞;在调用Service时会开启线程调用Binder的写接口;服务器端处理完后调用写接口、唤醒阻塞中的客户端。 所有的通信都是通过底层的Binder驱动实现的。 3、RPC机制java层代码分析 类图 一般我们使用如下方式来获取系统的Service,例如AlarmManager: AlarmManager wm = (AlarmManager)getSystemService(Context.ALARM_SERVICE);该代码的运行时序如下所示: getSystemService时序 客户端通过Context.getSystemService获取远程服务时,会转到ContextImpl中调用,ContextImpl有一个ServiceFetcher内部类,通过名字知道该类用于获取Service;ContextImpl里面有个static的WALLPAPER_FETCHER,在APK启动时会加载里面的函数,如下所示,其中registerService会将每个Service对应的构造器ServiceFetcher放入SYSTEM_SERVICE_MAP中。 创建ServiceFetcher 在调用ContextImpl.getSystemService()时,会调用SYSTEM_SERVICE_MAP对应ServiceFetcher的getService()方法,如下所示。ContextImpl有个全局mServiceCache用于缓存用户创建的Service缓存,这样用户再次获取的时候可以直接从缓存取出,避免再次创建。 SeviceFetcher.getService 如果mServiceCache没有需要的Service缓存,则调用ServiceFetcher的createService进行创建,这里就开始和ServiceManager打交道了,以AlarmManager为例,首先调用ServiceManager.getService()获取IBinder,然后调用IAlarmManager.stub.asInterface将该binder转化成客户端可以直接调用的接口,最后将该接口封装成AlarmManager给客户端使用。 registerService 我们看到这里调用了ServiceManagerNative.asInterface获取应IServiceManager实例,传入了BinderInternal.getContextObject(),如下所示: BinderInternal.getContextObject getContextObject方法是一个JNI方法,其实sServiceManager=ServiceManagerNative.asInterface(BinderInternal.getContextObject());就相当于:sServiceManager=ServiceManagerNative.asInterface(newBinderProxy()); 接下来就是调用ServiceManagerNative的asInterface函数了. ServiceManagerNative.asInterface() 这里的参数obj是一个BinderProxy对象,ServiceManagerProxy提供了addService、getService的实现,也就是ServiceManager最终关联到了ServiceManagerProxy上。到这里,在java层我们已经拥有了ServiceManager的远程接口ServiceManagerProxy,对ServiceManager的所有操作将转接到ServiceManagerProxy中。 如此就实现了对android系统的ServiceManager的RPC调用。那么android系统中提供的那些Service是怎样添加到ServiceManager中去的呢?答案就在SystemServer.java类中,SystemServer伴随系统一起启动,之后会运行ServerThread线程。 SystemServer.init2() ServerThread的run方法会完成所有系统Service的创建,并添加到ServiceManager中去,如下所示: 添加所有的系统Service 其中addService也是调用的ServiceManagerProxy的addService,这样在系统启动后,相当于在OS层维护了一群系统Service的list。 4、几个概念 IBinder是一个接口,它代表了一种跨进程传输的能力;只要实现了这个接口,就能将这个对象进行跨进程传递;这是驱动底层支持的;在跨进程数据流经驱动的时候,驱动会识别IBinder类型的数据,从而自动完成不同进程Binder本地对象(Server端)以及Binder代理对象(Client获取的Proxy)的转换。 IInterface代表的就是远程server对象具有什么能力, 表示client与server端的调用契约。具体来说,就是aidl里面的接口。 Java层的Binder类,代表的其实就是Binder本地对象。BinderProxy类是Binder类的一个内部类,它代表远程进程的Binder对象的本地代理;这两个类都继承自IBinder,因而都具有跨进程传输的能力;实际上,在跨越进程的时候,Binder驱动会自动完成这两个对象的转换。 在使用AIDL的时候,编译工具会给我们生成一个Stub的静态内部类;这个类继承了Binder,说明它是一个Binder本地对象,它实现了IInterface接口,表明它具有远程Server承诺给Client的能力;Stub是一个抽象类,具体的IInterface的相关实现需要我们手动完成,这里使用了策略模式。

优秀的个人博客,低调大师

Cairo 1.17.8 发布,计算机 2D 向量图形绘图库

Cairo 1.17.8 版本已发布,Cairo 是一个开源的图形库,为软件开发者提供了一个基于矢量图形、独立于设备的 API。Cairo 支持输出到一些不同的后端,后端支持包括 X11、Apple Quartz、Win32,以及 PNG、PDF、PostScript、DirectFB 和 SVG 等文件格式。 近年来 Cairo 的开发停滞不前,2018 年底推出了 Cairo 1.16 稳定版,然后就没有了消息。接着就是当前最新的Cairo 1.17.8 版本,Cairo 1.17.8 修复了各种错误,改进了对 macOS 和 Windows 的支持,支持渲染 COLRv1 字体,删除了 Autotools 构建系统以专注于 Meson。 此外,该版本还删除了 OpenGL/GLES 支持,因为该后端大约十年没有得到维护。 macOS 和 Windows 的支持改进涉及大量错误修复和构建更改,详情可查看更新公告。 cairo 使用 C 语言撰写的,但使用 cairo 时支持许多其他语言,包括有 C++、C#、Java、Python、Perl、Ruby、Scheme、Smalltalk 以及许多种语言,cairo 在 GPL 与 Mozilla Public License 两个开源许可证下发布。

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册