Android Binder通信原理(七):java 下的C-S

这篇具有很好参考价值的文章主要介绍了Android Binder通信原理(七):java 下的C-S。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

源码基于:Android R

0. 前言

在之前的几篇博文中,对Android binder 的通信原理进行的深入的剖析,这些博文包括:binder 简介servicemanager启动service注册service获取Java 端的service 注册和获取。

在前一文中,通过实例,详细地说明了native 下 的C-S 通信原理

本文在之前的基础上,以实例的形式进一步的分析 java 下的 C-S 通信。

1. aidl

App 中使用 binder 进行通信时都会使用 aidl,这样的使用 framework 也很常见,而系统在编译的时候都会根据 aidl 的接口定义,自动编译出对应的 Java 文件。

最新的版本中 aidl 不但能够保证 Java 端的 C - S通信,也能保证 Java client - native service 的通信。

这里以PMS 的install 为例,PMS 在进行APK 安装时,会进行dex 的翻译,依赖守护进程installd 完成。

frameworks/native/cmds/installd/binder/android/os/IInstalld.aidl

package android.os;

/** {@hide} */
interface IInstalld {
    ...
}

2. Java 端调用

frameworks/base/services/core/java/com/android/server/pm/installer.java

import android.os.IInstalld;

public class Installer extends SystemService {
    private volatile IInstalld mInstalld;
    
    private void connect() {
        IBinder binder = ServiceManager.getService("installd");
        if (binder != null) {
            ...
        }

        if (binder != null) {
            mInstalld = IInstalld.Stub.asInterface(binder);
            ...
        }
    }
    
    public long createAppData(String uuid, String packageName, int userId, int flags, int appId,
            String seInfo, int targetSdkVersion) throws InstallerException {
        if (!checkBeforeRemote()) return -1;
        try {
            return mInstalld.createAppData(uuid, packageName, userId, flags, appId, seInfo,
                    targetSdkVersion);
        } catch (Exception e) {
            throw InstallerException.from(e);
        }
    }
    ...
}

上述代码中主要注意:

  • 引用的aidl 为android.os.IInstalld;
  • 通过 getService("installd") 获取到IBinder;
  • IInstalld.Stub.asInterface() 获取代理;

主要是确定aidl 编译后的源码位置,对于Android R,framework 下的aidl 会统一到目录out\soong\.intermediates\frameworks\base\module-lib-api\android_common\gen\aidl 下。

Android Binder通信原理(七):java 下的C-S

aidl 编译后的JAVA 文件都会最终打包到 aidl*.srcjar 中,那具体的文件怎么确定呢?需要依赖frameworks 文件夹或者 system 文件夹的 *.aidl.d 文件。

如果aidl 文件是定义在frameworks 下,那么就可以到framework 下对应的目录查找对应的 *.aidl.d 文件。同样,如果aidl 是在 system 下定义,则可以到system 文件夹下查找 *.aidl.d 文件。例如这里的 IInstalld.aidl 是定义在 frameworks/native/cmds/installd 下,那就到frameworks 文件夹下对应位置找到 IIntalld.aidl.d 文件:

out/soong/.intermediates/frameworks/base/module-lib-api/android_common/gen/aidl/aidl27.tmp/frameworks/native/cmds/installd/binder/android/os/IInstalld.java : \
  frameworks/native/cmds/installd/binder/android/os/IInstalld.aidl \
  frameworks/native/cmds/installd/binder/android/os/storage/CrateMetadata.aidl

frameworks/native/cmds/installd/binder/android/os/IInstalld.aidl :
frameworks/native/cmds/installd/binder/android/os/storage/CrateMetadata.aidl :

第一行指定了 IInstalld.aidl 编译出的Java 文件位于aidl27.tmp,即上图中的 aidl27.srcjar 文件中,解压后就能找到 IInstalld.java:

package android.os;
/** {@hide} */
public interface IInstalld extends android.os.IInterface
{
    ...
    public static abstract class Stub extends android.os.Binder implements android.os.IInstalld
    {
        ...
        public static android.os.IInstalld asInterface(android.os.IBinder obj)
        {
          if ((obj==null)) {
            return null;
          }
          android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
          if (((iin!=null)&&(iin instanceof android.os.IInstalld))) {
            return ((android.os.IInstalld)iin);
          }
          return new android.os.IInstalld.Stub.Proxy(obj);
        }
    }
    ...
}

3. Java client 与 service 通信

对于binder service 有两种方式存在,java 端和native 端。但是对于client 只负责通过getService 查找到service 的代理,并通过此代理调用transact 通信,而对于service ,驱动只会通知其BBinder,并通过 onTransact 进行处理。

而,BBinder 也有两种方式存在,java service 为JavaBBinder(继承自BBinder),而native service 为BBinder。

所以,无论client 或service 位于java 端,还是native 端,根本原因都是BpBinder 与BBinder 的通信。

对于 Java 端的 binder 通信下面这个框架图,在 Java 端的service 注册和获取 一文中详细说明。

Android Binder通信原理(七):java 下的C-S

继续上面的  IInstalld.aidl,会在 out/soong/.intermediates/frameworks/native/cmds/installd/installd/.../gen/aidl/ 目录下面编译出几个文件。

该目录下 android/os 下面是编译出来的头文件:

Android Binder通信原理(七):java 下的C-S

该目录下 frameworks/native/cmds/installd/binder/android/os 下面是编译出来的实现文件:

Android Binder通信原理(七):java 下的C-S

而,installd 在native 有个service 继承了 BnInstalld:

frameworks/native/cmds/installd/InstalldNativeService.h

class InstalldNativeService : public BinderService<InstalldNativeService>, public os::BnInstalld {
public:
    ...
};

至此,java下 C-S 的实例已经基本说明完毕,结合实际操作可以更好的理解 binder 的通信。 文章来源地址https://www.toymoban.com/news/detail-508389.html

到了这里,关于Android Binder通信原理(七):java 下的C-S的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android Binder——Java层通信实例(十六)

            前面的文章中我们介绍了 Java 层服务的注册流程,以及代理文件的查找。这里我们看一个 Binder 通信的实例,为了方便我们就以 Android 源码中现有的功能 PMS 的 install 为例,PMS 在进行 APK 安装时,会进行 dex 的翻译,依赖守护进程 installd 完成。         在 Binder

    2024年04月23日
    浏览(53)
  • Binder通信原理

    注:本文大部分代码来自安卓11 ● 从IPC角度来说,Binder是Android中的一种跨进程通信方式,Binder还可以理解为一种虚拟的物理设备驱动,它的设备驱动是/dev/binder,该通信方式以前在linux中没有 ● 从Android Framework角度来说,Binder是ServiceManager连接各种Manager(ActivityManager、Windo

    2024年02月03日
    浏览(37)
  • Android Binder常用案例使用分析,跨进程通信aidl

    service组件的binderService获取binder通信。 servicemanager.getService方法获取相关服务。 本质上都是IBinder通信。 客户端:使用intent,启动服务端的service,使用binderservice,在onServiceConnected回调方法中获取服务端的实际binder对象。使用aidl中的接口调用服务端的方法即可。 服务端:定义

    2024年02月07日
    浏览(43)
  • Android 进阶——Binder IPC之Binder IPC架构及原理概述(九)

    前面几篇文章,为我们学习Binder IPC通信机制提供了扎实的理论基础,接下来将正式进入Binder IPC通信架构及原理的解读。 Binder 是基于 C/S 架构的,由一系列的组件组成,包括 Client进程、Server进程、Service Manager进程、Binder 驱动。其中 Client进程、Server进程、Service Manager进程运行

    2023年04月09日
    浏览(43)
  • Android Binder机制浅谈以及使用Binder进行跨进程通信的俩种方式(AIDL以及直接利用Binder的transact方法实现)

    Binder机制学习 ·为何新增Binder来作为主要的IPC方式 Android也是基于Linux内核,Linux现有的进程通信手段有管道/消息队列/共享内存/套接字/信号量。 既然有现有的IPC方式,为什么重新设计一套Binder机制呢? 主要是出于以上三个方面的考量: 2. binder是什么? 从进程间通信的角度

    2024年02月16日
    浏览(32)
  • BpBinder与PPBinder调用过程——Android开发Binder IPC通信技术

    在Android系统中,进程间通信(IPC)是一个非常重要的话题。Android系统通过Binder IPC机制实现进程间通信,而Binder IPC通信技术则是Android系统中最为重要的进程间通信技术之一。本文将介绍Binder IPC通信技术的原理,并详细解析BpBinder与PPBinder调用过程的使用以及注意事项。 Bind

    2024年02月13日
    浏览(35)
  • 写给 Android 应用工程师的 Binder 原理剖析

    这篇文章我酝酿了很久,参考了很多学习文档,读了很多源码,却依旧不敢下笔。生怕自己理解上还有偏差,对大家造成误解,贻笑大方。又怕自己理解不够透彻,无法用清晰直白的文字准确的表达出 Binder 的设计精髓。直到今天提笔写作时还依旧战战兢兢。 Binder 之复杂远远

    2024年02月13日
    浏览(57)
  • 【Android】Binder(一)Binder的介绍和AIDL使用Binder的实例

    Android 中的 Binder 是一个进程间通信机制,它允许不同进程之间相互调用方法和传递数据。Binder 主要用于实现系统服务和应用程序之间的通信,以及实现 IPC(Inter-Process Communication,进程间通信)。 Binder 的核心是 Binder 驱动程序,它负责管理不同进程之间的通信。每个进程都可

    2024年02月07日
    浏览(40)
  • Android 13(T) - binder阅读(1)- binder driver

    想要使用binder完成进程间通信(IPC)或者完成远程过程调用(RPC),那么我们需要有如下三个要素: 源:即调用者(Client) 目的:即服务提供者(Server)。这里会有一个问题,client怎么知道我要向哪里发送数据呢?这里就需要用到ServiceManager,Server需要先注册到ServiceManager中

    2024年02月11日
    浏览(33)
  • Android 13(T) - binder阅读(3)- binder相关的类

    原先准备在binder阅读(3)中记录ServiceManager的使用,但是写着写着发现,如果不了解和binder相关的类,那么阅读起来将会由很多困惑,所以就先来记录binder相关的类了。记录完发现特别凌乱…先就这样吧。 从 binder阅读(1)一开始的图中可以看到, getService 获得的是一个han

    2024年02月11日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包