Android AIDL的使用(配源码)

零、完整源代码

链接: https://github.com/jx0260/TestGradle

一、创建AIDL文件

// IShopAidlInterface.aidl
package com.example.testgradle;

// Declare any non-default types here with import statements

interface IShopAidlInterface {

    String getProductInfo(int productNo);

    void buyProduct1(int productNo, String address);

}

二、Make Project 生成Binder工具类

AndroidStudio make project
路径为:
在这里插入图片描述
生成代码如下(下一篇文章会分析这些生成的代码):

/*
 * This file is auto-generated.  DO NOT MODIFY.
 */
package com.example.testgradle;
// Declare any non-default types here with import statements

public interface IShopAidlInterface extends android.os.IInterface
{
  /** Default implementation for IShopAidlInterface. */
  public static class Default implements com.example.testgradle.IShopAidlInterface
  {
    @Override public java.lang.String getProductInfo(int productNo) throws android.os.RemoteException
    {
      return null;
    }
    @Override public void buyProduct1(int productNo, java.lang.String address) throws android.os.RemoteException
    {
    }
    @Override
    public android.os.IBinder asBinder() {
      return null;
    }
  }
  /** Local-side IPC implementation stub class. */
  public static abstract class Stub extends android.os.Binder implements com.example.testgradle.IShopAidlInterface
  {
    private static final java.lang.String DESCRIPTOR = "com.example.testgradle.IShopAidlInterface";
    /** Construct the stub at attach it to the interface. */
    public Stub()
    {
      this.attachInterface(this, DESCRIPTOR);
    }
    /**
     * Cast an IBinder object into an com.example.testgradle.IShopAidlInterface interface,
     * generating a proxy if needed.
     */
    public static com.example.testgradle.IShopAidlInterface asInterface(android.os.IBinder obj)
    {
      if ((obj==null)) {
        return null;
      }
      android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
      if (((iin!=null)&&(iin instanceof com.example.testgradle.IShopAidlInterface))) {
        return ((com.example.testgradle.IShopAidlInterface)iin);
      }
      return new com.example.testgradle.IShopAidlInterface.Stub.Proxy(obj);
    }
    @Override public android.os.IBinder asBinder()
    {
      return this;
    }
    @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
    {
      java.lang.String descriptor = DESCRIPTOR;
      switch (code)
      {
        case INTERFACE_TRANSACTION:
        {
          reply.writeString(descriptor);
          return true;
        }
        case TRANSACTION_getProductInfo:
        {
          data.enforceInterface(descriptor);
          int _arg0;
          _arg0 = data.readInt();
          java.lang.String _result = this.getProductInfo(_arg0);
          reply.writeNoException();
          reply.writeString(_result);
          return true;
        }
        case TRANSACTION_buyProduct1:
        {
          data.enforceInterface(descriptor);
          int _arg0;
          _arg0 = data.readInt();
          java.lang.String _arg1;
          _arg1 = data.readString();
          this.buyProduct1(_arg0, _arg1);
          reply.writeNoException();
          return true;
        }
        default:
        {
          return super.onTransact(code, data, reply, flags);
        }
      }
    }
    private static class Proxy implements com.example.testgradle.IShopAidlInterface
    {
      private android.os.IBinder mRemote;
      Proxy(android.os.IBinder remote)
      {
        mRemote = remote;
      }
      @Override public android.os.IBinder asBinder()
      {
        return mRemote;
      }
      public java.lang.String getInterfaceDescriptor()
      {
        return DESCRIPTOR;
      }
      @Override public java.lang.String getProductInfo(int productNo) throws android.os.RemoteException
      {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        java.lang.String _result;
        try {
          _data.writeInterfaceToken(DESCRIPTOR);
          _data.writeInt(productNo);
          boolean _status = mRemote.transact(Stub.TRANSACTION_getProductInfo, _data, _reply, 0);
          if (!_status && getDefaultImpl() != null) {
            return getDefaultImpl().getProductInfo(productNo);
          }
          _reply.readException();
          _result = _reply.readString();
        }
        finally {
          _reply.recycle();
          _data.recycle();
        }
        return _result;
      }
      @Override public void buyProduct1(int productNo, java.lang.String address) throws android.os.RemoteException
      {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        try {
          _data.writeInterfaceToken(DESCRIPTOR);
          _data.writeInt(productNo);
          _data.writeString(address);
          boolean _status = mRemote.transact(Stub.TRANSACTION_buyProduct1, _data, _reply, 0);
          if (!_status && getDefaultImpl() != null) {
            getDefaultImpl().buyProduct1(productNo, address);
            return;
          }
          _reply.readException();
        }
        finally {
          _reply.recycle();
          _data.recycle();
        }
      }
      public static com.example.testgradle.IShopAidlInterface sDefaultImpl;
    }
    static final int TRANSACTION_getProductInfo = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
    static final int TRANSACTION_buyProduct1 = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
    public static boolean setDefaultImpl(com.example.testgradle.IShopAidlInterface impl) {
      // Only one user of this interface can use this function
      // at a time. This is a heuristic to detect if two different
      // users in the same process use this function.
      if (Stub.Proxy.sDefaultImpl != null) {
        throw new IllegalStateException("setDefaultImpl() called twice");
      }
      if (impl != null) {
        Stub.Proxy.sDefaultImpl = impl;
        return true;
      }
      return false;
    }
    public static com.example.testgradle.IShopAidlInterface getDefaultImpl() {
      return Stub.Proxy.sDefaultImpl;
    }
  }
  public java.lang.String getProductInfo(int productNo) throws android.os.RemoteException;
  public void buyProduct1(int productNo, java.lang.String address) throws android.os.RemoteException;
}

IShopAidlInterface这个生成的文件里面有 Stub类、Proxy类等,简单理解就是服务端(Stub)、客户端(proxy)它们为我们提供了跨进程通信的能力。为技术上的通信打通路径,唯一缺少的是业务方法的实现

三、编写服务端

3.1 实现服务端 Stub 业务

class Stub implements com.example.testgradle.IShopAidlInterface

AIDL为我们生成的Stub类,实现了 com.example.testgradle.IShopAidlInterface 接口,我们现在就实现他的业务方法:

private IShopAidlInterface.Stub mBinder = new IShopAidlInterface.Stub() {
        @Override
        public String getProductInfo(int productNo) throws RemoteException {
            Log.i(TAG, "SERVER: receive productNo: " + productNo);
            return "the productNo is: " + productNo + ", productName is LEGO!";
        }

        @Override
        public void buyProduct1(int productNo, String address) throws RemoteException {
            Log.i(TAG, "SERVER: receive productNo: " + productNo + ", address: " +address);
            Log.i(TAG, "YOU buy succeed!");
        }
    };

现在我们就实现好了,简单打印一些消息。有了服务端的Stub类,客户端怎么调用到它呢?
我们通过Android四大组件的Service,将这个服务端的Stub“传到”客户端,再在客户端进行调用:

3.2 定义服务端的Service

public class ShopService extends Service {
    private String TAG = "ShopService";

    public ShopService() {
    }

    private IShopAidlInterface.Stub mBinder = new IShopAidlInterface.Stub() {
        @Override
        public String getProductInfo(int productNo) throws RemoteException {
            Log.i(TAG, "SERVER: receive productNo: " + productNo);
            return "the productNo is: " + productNo + ", productName is LEGO!";
        }

        @Override
        public void buyProduct1(int productNo, String address) throws RemoteException {
            Log.i(TAG, "SERVER: receive productNo: " + productNo + ", address: " +address);
            Log.i(TAG, "YOU buy succeed!");
        }
    };

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }
}

我们在 onBind() 方法中,将Stub对象传出去。
manifest 文件配置一下:

<service
    android:name=".ShopService"
    android:enabled="true"
    android:exported="true">
    <intent-filter>
        <action android:name="com.example.testgradle.ShopService"/>
    </intent-filter>
</service>

(注意 exported=“true”,意味着允许让外部组件启动,我们要做跨进程调用,所以要允许客户端能访问此Service)

四、编写客户端

新建一个Application,创建一个Activity:
在Create() 方法中:

private IShopAidlInterface iShopAidlInterface;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_client);
	Intent serviceIntent = new Intent("com.example.testgradle.ShopService");
	serviceIntent.setPackage("com.example.testgradle");
	bindService(serviceIntent, new ServiceConnection() {
	    @Override
	    public void onServiceConnected(ComponentName name, IBinder service) {
	        Log.i("ClientActivity", "onServiceConnected() service=" + service);
	        iShopAidlInterface = IShopAidlInterface.Stub.asInterface(service);
	        try {
	            iShopAidlInterface.getProductInfo(1221);
	            iShopAidlInterface.buyProduct1(9988, "大连市甘井子区");
	        } catch (RemoteException e) {
	            e.printStackTrace();
	        }
	    }
	
	    @Override
	    public void onServiceDisconnected(ComponentName name) {
	
	    }
	}, BIND_AUTO_CREATE);
	
	findViewById(R.id.btn_getInfo).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            try {
                iShopAidlInterface.getProductInfo(1221);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    });

    findViewById(R.id.btn_buy).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            try {
                iShopAidlInterface.buyProduct1(9988, "大连市西岗区");
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    });
}

我们通过bindService,绑定到刚才在服务端定义的Service。在onServiceConnected()
回调中,将传过来的 IBinder 对象,使用 Stub.asInterface 转成 IShopAidlInterface 对象。再调用其中的业务方法。
由于我们是两个进程,所以此处的 使用 Stub.asInterface 转出的对象 就是一个 Proxy。

五、点按钮运行

打印日志:

com.example.testgradle I/ShopService: SERVER: receive productNo: 1221
com.example.testgradle I/ShopService: SERVER: receive productNo: 9988, address: 大连市西岗区
com.example.testgradle I/ShopService: YOU buy succeed!

下一篇文章,将详细描述,这中间发生了什么 及AIDL 与 Binder 的关系。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【2023最新教程】一文3000字从0到1教你做app自动化测试(保姆级教程)

一、什么是App自动化&#xff1f;为什么要做App自动化&#xff1f; App自动化是指给 Android或iOS上的软件应用程序做的自动化测试。手工测试和自动化测试的对比如下&#xff1a; 手工测试优势&#xff1a;不可替代、发现更多bug、包含了人的想象力与理解力。 注意&#xff0c…

迅为iTOP-RK3588开发板Android12源码定制开发kernel开发

内核版本是 5.10.66 版本&#xff0c;内核默认的配置文件是 3588-android12/kernel-5.10/arch/arm64/configs/rockchip_defconfig 如果我们要使用图形化界面配置内核&#xff0c;操作方法如下所示&#xff1a; 方法一&#xff1a; 1 首先将默认的配置文件 rockchip_defconf…

博客系统测试用例设计之自动化测试

测试用例设计之自动化测试 &#x1f337; 一 测试用例设计&#x1f33a; 1 功能测试&#x1f338; &#xff08;1&#xff09;登录功能&#x1f338; &#xff08;2&#xff09;列表页功能&#x1f338; &#xff08;3&#xff09;编辑博客功能&#x1f338; &#xff08;4&…

DC LAB8SDC约束四种时序路径分析

DC LAB 1.启动DC2.读入设计3. 查看所有违例的约束报告3.1 report_constraint -all_violators (alias rc)3.2 view report_constraint -all_violators -verbose -significant_digits 4 (打印详细报告) 4.查看时序报告 report_timing -significant_digits 45. 约束组合逻辑(adr_i…

17 条件随机场

文章目录 17 条件随机场——CRF&#xff08;Condition Random Field&#xff09;17.1 背景介绍17.2 HMM与MEMM的区别17.3 MEMM与CRF的区别17.4 CRF模型17.4.1 CRF的概率密度函数17.4.2 CRF概率密度函数简化&#xff08;向量形式&#xff09; 17.5 CRF需要解决的问题17.6 边缘概…

测试者必知—如何做Web测试?常见测试点总结

目录 前言&#xff1a; 一、Web应用程序 二、功能测试 三、易用性测试&#xff08;界面测试&#xff09; 四、兼容性测试 五、安全性测试 六、性能测试 前言&#xff1a; Web测试是指对基于Web技术的应用程序进行测试&#xff0c;以测试其功能、性能、安全和稳定性等方面的表…

【图书推荐 | 12】前端系列

【赠书活动第十二期 】 图书推荐 本期书籍&#xff1a;前端系列 图书列表&#xff1a; Vue.js核心技术解析Nuxt.js实战Nuxt.js Web开发实战HTML5CSS 从入门到精通Flutter2 开发实例精解Electron项目开发实战 Vue.js核心技术解析 Nuxt.js实战 Nuxt.js Web开发实战 HTML5CSS 从入…

【业务功能篇20】Springboot java逻辑实现动态行转列需求

在此前&#xff0c;我也写过一个行转列的文章&#xff0c;是用存储过程sql处理的一个动态的逻辑 Mysql 存储过程\Mybatis框架call调用 实现动态行转列 那么后面我们同样又接收了业务的一个新需求&#xff0c;针对的是不同的业务数据&#xff0c;做的同样的一个展示数据报表&…

VueX使用简明笔记

1、作用&#xff1a; vuex是使用vue中必不可少的一部分&#xff0c;基于父子、兄弟组件&#xff0c;我们传值可能会很方便&#xff0c;但是如果是没有关联的组件之间要使用同一组数据&#xff0c;就显得很无能为力&#xff0c;那么vuex就很好的解决了我们这种问题&#xff0c;…

MySQL数据库 – node使用

1 MySQL查询对象 2 MySQL查询数组 3 mysql2库介绍使用 4 mysql2预处理语句 5 mysql2连接池使用 6 mysql2的Promi 这里仅说明如何使用服务器连接数据库并进行操作。 预处理语句就是可以输入变量的语句&#xff08;表现形式是有符号&#xff1a;&#xff1f;&#xff09;。需…

portraiture宿主插件最新v4中文版本下载及使用教程

自拍怎么可以不修图呢&#xff1f;如果要修图的话&#xff0c;磨皮就是其中非常重要的一环。皮肤看起来细腻光滑了&#xff0c;整个人的颜值都会瞬间拉高。下面就让我们介绍一下磨皮用什么软件好用&#xff0c;什么软件可以手动磨皮的相关内容。portraiture是ps人像修图中常用的…

为何唐宋诗词鼎盛,而到了明清变成了小说

我国是一个历史悠久的国家&#xff0c;在漫长的历史长河中&#xff0c;随着朝代的更替&#xff0c;很多事也发生了有趣的变化。 例如唐宋时期盛行的是诗词&#xff0c;而到了明清时代&#xff0c;小说又开始盛行了起来&#xff0c;那么造成这种文风改变的原因是什么呢&#xf…

Java版本spring cloud 工程管理系统软件 系统源代码 自主研发,工程行业适用

Java版工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离 功能清单如下&#xff1a; 首页 工作台&#xff1a;待办工作、消息通知、预警信息&#xff0c;点击可进入相应的列表 项目进度图表&#xff1a;选择&#xff08;总体或单个&#xff09;项目显示…

实战案例|黑灰产肆虐,腾讯ACE一键打造清朗游戏世界

随着游戏行业的快速发展&#xff0c;相关黑色产业链的问题日益严重&#xff0c;各种外挂、违规内容、非法交易现象的出现破坏着游戏的生态&#xff0c;为行业带来诸多安全挑战&#xff0c;也影响着玩家们的游戏体验。越来越多游戏厂商开始重视游戏安全问题&#xff0c;并探索全…

华为OD机试真题 JavaScript 实现【最远足迹】【2022Q4 100分】,附详细解题思路

一、题目描述 某探险队负责对地下洞穴进行探险。探险队成员在进行探险任务时&#xff0c;随身携带的记录器会不定期地记录自身的坐标&#xff0c;但在记录的间隙中也会记录其他数据。探索工作结束后&#xff0c;探险队需要获取到某成员在探险过程中相对于探险队总部的最远的足…

Mujoco210 Ubuntu 22.04配置安装(一)

目录 .1 下载 1.1 解压 1.2 许可问题 1.3 环境配置 1.4 测试mujoco .2 安装mujoco-py 2.1 conda激活虚拟环境\或新创建一个环境 2.2 下载mujoco-py ​编辑 2.3 配置环境变量 2.4 测试mujoco-py 2.5 测试时的一些报错处理 2.5.0 command /usr/bin/gcc failed with…

读写ini配置文件(C++)

文章目录 1、为什么要使用ini或者其它(例如xml,json)配置文件&#xff1f;2、ini文件基本介绍3、ini配置文件的格式4、C读写ini配置文件5、 代码示例6、 配置文件的解析库 文章转载于&#xff1a;https://blog.csdn.net/weixin_44517656/article/details/109014236 1、为什么要…

docker harbor私有仓库部署

docker harbor私有仓库部署 docker system prune -a 删除停掉的服务&#xff0c;自定义网络等。 docker 私有仓库 docker配置文件 vim /etc/docker.daemon.josn { “insecury-registries”: ["192.168.232.10:5000]&#xff0c;#指定私有仓库 } docker pull/push 19…

防雪崩利器之Hystrix

Hystrix作为一个容错组件&#xff0c;本文从它的作用、熔断设计、工作流程和应用方面一一道来&#xff0c;帮助大家了解如何使用。 1、什么是灾难性雪崩效应 要讲Hystrix&#xff0c;我们就要讲一种场景&#xff0c;在微服务架构中&#xff0c;如果底层服务出现故障&#xff0…

BBA EDI 项目数据库方案开源介绍

近期为了帮助广大用户更好地使用 EDI 系统&#xff0c;我们根据以往的项目实施经验&#xff0c;将成熟的 EDI 项目进行开源。用户安装好知行之桥EDI系统之后&#xff0c;只需要下载我们整理好的示例代码&#xff0c;并放置在知行之桥指定的工作区中&#xff0c;即可开始使用。 …