Android AIDL的使用(配源码)

news2024/11/24 5:01:10

零、完整源代码

链接: 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 的关系。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

speedtest-cli 源码集成

speedtest-cli 是一个开源的测速sdk&#xff0c;可以下载源码集成到自己的项目中&#xff0c;源码是C代码&#xff0c;所以可以集成到linux终端程序中&#xff0c;如果在Android APP中需要通过NDK开发集成&#xff0c;下面是在linux设备中集成过程。 1、首先在github中下载源码…

代码随想录算法训练营第四十九天|121. 买卖股票的最佳时机|122.买卖股票的最佳时机II

LeetCode121. 买卖股票的最佳时机 动态规划五部曲&#xff1a; 1&#xff0c;确定dp数组&#xff08;dp table&#xff09;以及下标的含义&#xff1a;dp[i][0] 表示第i天持有股票所得最多现金&#xff0c;其实一开始现金是0&#xff0c;那么加入第i天买入股票现金就是 -pric…

界面组件DevExpress Reporting v22.2亮点 - 添加更多自定义支持

DevExpress Reporting是.NET Framework下功能完善的报表平台&#xff0c;它附带了易于使用的Visual Studio报表设计器和丰富的报表控件集&#xff0c;包括数据透视表、图表&#xff0c;因此您可以构建无与伦比、信息清晰的报表 界面组件DevExpress Reporting v22.2已正式发布一…

CDN如何帮助我们的网站实现安全?

各类网络攻击正在变得越来越复杂&#xff0c;它们有可能导致服务可用性的严重中断和企业的财务损失。根据Gartner的数据&#xff0c;IT行业平均停机每分钟就将为企业带来超过3万元的损失。 对于每个具有在线相关业务的企业&#xff0c;如何能以安全、可靠和快速的方式服务于用…

MySQL(进阶篇2.0)

SQL优化 插入数据 insert 如果需要一次性往数据库表中插入多条记录&#xff0c;可以从以下三个方面进行优化 1、优化方案一 批量插入数据 insert into tb_test values(1, Tom),(2,Cat),(3,Jerry);2、优化方案二 手动控制事务 start transaction; insert into tb_test v…

ShardingSphere 荣获一等奖!2022 年中国开源创新大赛成绩单公布

&#x1f3c6; 参赛回顾 “2022年中国开源创新大赛”在国家中央网信办信息化发展局的指导下&#xff0c;由中国互联网发展基金会、中国网络空间研究院、中国互联网投资基金联合主办&#xff0c;大赛以“开源创新&#xff0c;共建生态”为主题&#xff0c;围绕国家在开源人才培养…

uniApp页面通讯大汇总,如何页面之间传值

文章目录 往期回顾页面通讯出现场景通讯方案通讯方案小结 如何父传子页面跳转时序图 uni.\$on和eventChannel.on使用推荐 往期回顾 uniapp 踩坑记录 uni.$on为什么不能修改data里面的数据 页面通讯 出现场景 我们在一个页面往另一个页面跳转的时候&#xff0c;希望跳转的页…

golang实现webgis后端开发

目录 前言 二、实现步骤 1.postgis数据库和model的绑定 2.将pg库中的要素转换为geojson (1)几何定义 (2)将wkb解析为几何类型 (3)定义geojson类型 (4)数据转换 &#xff08;5&#xff09;数据返回 2.前端传入的geojson储存到数据库 3、其他功能实现 总结 前言 停更了…

从java直接上手SpringBoot【CTGU启明星】

本文适合刚刚学完java包括面向对象的同学&#xff0c;直接上手SpringBoot教程。 一、写在前面 先说说为什么这样做&#xff0c;现在主流的java后端学习是 面向对象->ssm框架->SpringBoot 其间还穿插数据库的学习&#xff0c;例如MyBatis等。 但是我们认为从项目入手…

来自腾讯AI实验室的Real-ESRGAN将模糊老照片和视频修复成高清晰(一些错误处理)

Real-ESRGAN:Enhanced Super-Resolution GAN&#xff1a;增强的超分辨率的对抗生成网络&#xff0c;对于GAN相信大家都比较熟悉&#xff0c;前有阿尔法狗&#xff0c;现有很多GAN的延伸版本&#xff0c;StyleGAN1~3系列以及DragGAN对于图片的生成和编辑&#xff0c;出来的效果都…

Tomcat顶层架构、服务部署、虚拟主机配置

Tomcat顶层架构、服务部署、虚拟主机配置 一、Tomcat概述1、Tomcat介绍2、Tomcat三个核心组件3、Java Servlet4、JSP 二、Tomcat顶层架构三、Tomcat请求过程四、Tomcat服务部署1、关闭防火墙&#xff0c;将安装 Tomcat 所需软件包传到/opt目录下2、安装JDK3、设置JDK环境变量4、…

Java中导出Excel步骤总结(案例学习)

【辰兮要努力】&#xff1a;hello你好我是辰兮&#xff0c;很高兴你能来阅读&#xff0c;昵称是希望自己能不断精进&#xff0c;向着优秀程序员前行&#xff01; 博客来源于项目以及编程中遇到的问题总结&#xff0c;偶尔会有读书分享&#xff0c;我会陆续更新Java前端、后台、…

怎么把伴奏提取出来?分享两个方法给大家~

对于音乐制作人和音乐爱好者而言&#xff0c;创作个人音乐作品是一项令人兴奋的体验。然而&#xff0c;有时我们希望使用一首现有歌曲的伴奏来创作自己的音乐作品&#xff0c;但却无法找到原版伴奏。为了解决这一难题&#xff0c;现在可以使用记灵在线工具来提取音频伴奏。本文…

瞬息全宇宙:苹果发布虚拟现实头显Vision Pro

WWDC23巅峰时刻 熬夜看了WWDC苹果发布会&#xff0c;传闻了N年的苹果MR&#xff08;增强现实&#xff09;产品&#xff0c;终于来了。 One More Thing&#xff0c;库克说出了这句话&#xff0c;巅峰时刻终于到来&#xff01; 新的交互 名字叫Vision Pro&#xff0c;虽然这名…

《计算机网络——自顶向下方法》精炼——4.1-4.3.0

书读得越多而不假思索&#xff0c;你就会觉得你知道的很多&#xff1b;而当你读书而思考的越多的时候&#xff0c;你就会越清楚的看到&#xff0c;你知道的还很少——伏尔泰 文章目录 概述转发、路由选择网络服务模型 虚电路和数据报网络虚电路网络数据报网络 路由器工作原理 概…

chatgpt赋能python:Python如何出图

Python如何出图 作为一种广泛使用的编程语言&#xff0c;Python不仅仅可以用于数据分析、机器学习等领域&#xff0c;还可以用来生成图像。在这篇文章中&#xff0c;我们将介绍Python如何出图&#xff0c;并将重点放在与SEO相关的方面。 1. Python出图的基本原理 Python有多…

刷题记录:哈希 | leetcode-2352. 相等行列对 2023/6/6

2352. 相等行列对 这题还是非常简单的。如果用模拟的方法&#xff0c;时间复杂度要达到O(n^3)了&#xff0c;感觉不太可。 这回学聪明了&#xff0c;没有一上来就想着暴力模拟。用哈希的办法&#xff0c;可以把时间复杂度降为O(n^2)。 我的思路是先转置矩阵&#xff0c;再用…

Matlab论文插图绘制模板第99期—正负柱状图

在之前的文章中&#xff0c;分享了很多Matlab柱状图的绘制模板&#xff1a; 进一步&#xff0c;再来分享一种特殊的柱状图&#xff1a;正负柱状图。 先来看一下成品效果&#xff1a; 特别提示&#xff1a;本期内容『数据代码』已上传资源群中&#xff0c;加群的朋友请自行下载…

HTML+JS 实现手机号码归属地查询功能

手机号码归属地 API 是一种提供号码归属地信息的接口&#xff0c;它通过与运营商和电信数据库交互&#xff0c;根据手机号码查询相关归属地信息并返回结果。通过使用手机号码归属地API&#xff0c;开发者可以轻松地集成号码归属地查询功能到他们的应用程序和服务中&#xff0c;…

简介- 谷粒商城项目微服务架构图

目录 项目前置知识一、前后端分离开发&#xff0c;分为 内网部署 和 外网部署。二、用户是通过使用 客户端 来完成各种的功能三、网关的作用四、Sentiel组件五、Feign组件六、OAuth2.0认证中心七、SpringSecurity组件八、关于数据存储的解决方案九、定位bug十、注册中心十一、配…