Android中AIDL的简单使用(Hello world)
AIDL:Android Interface Definition Language(Android接口定义语言)
作用:跨进程通讯。如A应用调用B应用提供的接口
代码实现过程简述:
A应用创建aidl接口,并且创建一个Service来实现这个接口(在onBind方法里面return我们这个接口的实例)。
把A应用创建的aidl文件原封不动的搬至B应用中(注意包名类名都要一样),B应用bindService的方式来绑定A应用创建的这个Service,从而调用A应用提供的接口。
实现:
一、A应用(服务端)(提供接口被调用者):
1、创建AIDL文件:
Android Studio在项目main目录右键新建,找到AIDL,它会帮我们创建文件夹和文件,默认名字IMyAidlInterface,开发者根据需求修改名字
里面有:
interface IMyAidlInterface {/*** Demonstrates some basic types that you can use as parameters* and return values in AIDL.*/void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,double aDouble, String aString);//上面这个是新建的时候自己生成的,可以去掉,我们自己新建以下方法,一个get(从服务端取值),一个set(传值给服务端)String getHelloString();void setHelloString(String string);
}
写了之后make project一下,会自动生成IMyAidlInterface类。
2、创建service:(不需要A应用手动startService,B应用bindService的时候这个服务就会自动起来)
public class AidlTestService extends Service {private String hello;@Overridepublic void onCreate() {super.onCreate();hello = "hello";}@Nullable@Overridepublic IBinder onBind(Intent intent) {return new MyBinder();}public class MyBinder extends IMyAidlInterface.Stub{@Overridepublic void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {Log.i("xaeHu", "basicTypes: \nanInt = "+anInt+"\naLong = "+aLong+"\naBoolean = "+aBoolean+"\naFloat = "+aFloat+"\naDouble = "+aDouble+"\naString = "+aString);}@Overridepublic String getHelloString() throws RemoteException {return hello;}@Overridepublic void setHelloString(String string) throws RemoteException {hello = string;}}
}
3、清单文件声明这个service:(网上有说这个name需要全称,我这里实际没有用全称也能绑定成功)
<service android:name=".AidlTestService"android:enabled="true"android:exported="true" />
A应用的工作完成,接下来是B应用如何使用这个接口:
二、B应用(客户端)(接口调用者):
1、清单文件声明A应用的包名:(Android11新增,如果项目targetSdk>=30的话需要这一步,否则bindService是调不起来A应用的服务的)(这个坑网上很多AIDL的教程博客都没有说)
<!-- 配置服务端的包名--><queries><package android:name="com.example.myapplication" /></queries>
2、把A应用创建的AIDL文件包括A应用包名一起复制到B应用main目录下:
我这边A应用包名是“com.example.myapplication”,B应用包名是“com.example.myapplication2”

注意aidl的包名要与A应用一致,否者调用方法的时候会报异常:java.lang.SecurityException: Binder invocation to an incorrect interface
放进来之后make project一下,会自动生成IMyAidlInterface类。
3、绑定服务,调用aidl接口提供的方法:
比如直接在MainActivity的onCreate里面去绑定服务:
public class MainActivity extends AppCompatActivity{private IMyAidlInterface myAidlInterface;private final ServiceConnection connection = new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {myAidlInterface = IMyAidlInterface.Stub.asInterface(service);}@Overridepublic void onServiceDisconnected(ComponentName name) {myAidlInterface = null;}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//点击按钮一去绑定服务findViewById(R.id.btn1).setOnClickListener(v -> {Intent intent = new Intent();intent.setComponent(new ComponentName("com.example.myapplication","com.example.myapplication.AidlTestService"));boolean re = bindService(intent, connection, Context.BIND_AUTO_CREATE);Log.i("xaeHu", "bindService: "+re);});//点击按钮2调用set方法findViewById(R.id.btn2).setOnClickListener(v -> {if(myAidlInterface != null){try {myAidlInterface.setHelloString("hello world");} catch (RemoteException e) {e.printStackTrace();}}else {Log.e("xaeHu", "btn2 onclick: myAidlInterface == null");}});//点击按钮3调用get方法findViewById(R.id.btn3).setOnClickListener(v -> {if(myAidlInterface != null){try {Toast.makeText(this, myAidlInterface.getHelloString(), Toast.LENGTH_SHORT).show();} catch (RemoteException e) {e.printStackTrace();}}else {Log.e("xaeHu", "btn3 onclick: myAidlInterface == null");}});}@Overrideprotected void onDestroy() {super.onDestroy();unbindService(connection);}
}
简单的AIDL调用就搞定啦。
进阶:
上面的演示是传递基本数据类型为参数的,接下来通过AIDL传递对象
先在aidl文件夹中创建实体对象文件,再在java文件夹中创建实体类,不然的话在java中创建了实体类,再在aidl中创建相同的名字会提示错误。
A应用中:
比如我们创建Student对象,在aidl文件夹中就是Student.aidl,里面代码很简单:
package com.example.myapplication;parcelable Student;
然后再在java中创建Student.java,注意需要实现Parcelable:
public class Student implements Parcelable {private int id;private String name;private int age;private int sex;public Student() {}public Student(int id, String name, int age, int sex) {this.id = id;this.name = name;this.age = age;this.sex = sex;}protected Student(Parcel in) {id = in.readInt();name = in.readString();age = in.readInt();sex = in.readInt();}public static final Creator<Student> CREATOR = new Creator<Student>() {@Overridepublic Student createFromParcel(Parcel in) {return new Student(in);}@Overridepublic Student[] newArray(int size) {return new Student[size];}};public String getName() {return name;}public int getAge() {return age;}public int getSex() {return sex;}public int getId() {return id;}@Overridepublic int describeContents() {return 0;}@Overridepublic void writeToParcel(@NonNull Parcel dest, int flags) {dest.writeInt(id);dest.writeString(name);dest.writeInt(age);dest.writeInt(sex);}@Overridepublic String toString() {return "Student{" +"id=" + id +", name='" + name + '\'' +", age=" + age +", sex=" + sex +'}';}
}
在aidl接口中添加方法:(注意addStudent(in Student student);参数需要添加in表示接收参数,另外有out、inout)
// IMyAidlInterface.aidl
package com.example.myapplication;import com.example.myapplication.Student;
// Declare any non-default types here with import statementsinterface IMyAidlInterface {/*** Demonstrates some basic types that you can use as parameters* and return values in AIDL.*/void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,double aDouble, String aString);String getHelloString();void setHelloString(String string);void addStudent(in Student student);Student getStudent(int id);
}
服务中实现这两个方法:
private Map<Integer,Student> studentMap;@Override
public void addStudent(Student student) throws RemoteException {Log.i("xaeHu", "addStudent: "+student);if(studentMap == null){studentMap = new HashMap<>();}studentMap.put(student.getId(), student);
}@Override
public Student getStudent(int id) throws RemoteException {if(studentMap != null){Student student = studentMap.get(id);Log.i("xaeHu", id + " -> getStudent: "+student);return student;}Log.i("xaeHu", id + " -> getStudent: null");return null;
}
B应用:
同样的把aidl文件和类搬过来,注意实体对象的包名需要与A应用包名一致:

然后同样的,在绑定服务之后就可以调用了:
myAidlInterface.addStudent(new Student(1,"student1",26,0));
myAidlInterface.addStudent(new Student(2,"student2",27,1));Log.i("xaeHu", "getStudent1: "+myAidlInterface.getStudent(1));
Log.i("xaeHu", "getStudent2: "+myAidlInterface.getStudent(2));
完。
相关文章:
Android中AIDL的简单使用(Hello world)
AIDL:Android Interface Definition Language(Android接口定义语言) 作用:跨进程通讯。如A应用调用B应用提供的接口 代码实现过程简述: A应用创建aidl接口,并且创建一个Service来实现这个接口(…...
ZED使用指南(五)Camera Controls
七、其他 1、相机控制 (1)选择视频模式 左右视频帧同步,以并排格式作为单个未压缩视频帧流式传输。 在ZED Explorer或者使用API可以改变视频的分辨率和帧率。 (2)选择输出视图 ZED能以不同的格式输出图像…...
wrk泛洪攻击监控脚本
wrk泛洪攻击介绍 WRK泛洪攻击(WRK Flood Attack)是一种基于WRK工具进行的DDoS攻击(分布式拒绝服务攻击)。WRK是一个高度并行的HTTP负载生成器,可以模拟大量用户访问一个网站,从而导致该网站服务器瘫痪或失效…...
软件I2C读写MPU6050代码
1、硬件电路 SCL引到了STM32的PB10号引脚,SDA引到了PB11号引脚软件I2C协议: 用普通GPIO口,手动反转电平实现协议,不需要STM32内部的外设资源支持,故端口是可以任意指定MPU605在SCL和SDA自带了两个上拉电阻,…...
销售/回收DSOS254A是德keysight MSOS254A混合信号示波器
Agilent DSOS254A、Keysight MSOS254A、 混合信号示波器,2.5 GHz,20 GSa/s,4 通道,16 数字通道。 Infiniium S 系列示波器 信号保真度方面树立新标杆 500 MHz 至 8 GHz 出色的信号完整性使您可以看到真实显示的信号࿱…...
RIDGID里奇金属管线检测仪故障定位仪维修SR-20KIT
里奇RIDGID管线定位仪/检测仪/探测仪维修SR-20 SR-24 SR-60 美国里奇SeekTech SR-20管线定位仪对于初次使用定位仪的用户或经验丰富的用户,都同样可以轻易上手使用SR-20。SR-20提供许多设置和参数,使得大多数复杂的定位工作变得很容易。此外,…...
NodeJs之调试
关于调试 当我们只专注于前端的时候,我们习惯性F12,这会给我们带来安全与舒心的感觉。 但是当我们使用NodeJs来开发后台的时候,我想噩梦来了。 但是也别泰国担心,NodeJs的调试是很不方便!这是肯定的。 但是还好&…...
Java面试知识点(全)- Java并发-多线程JUC二-原子类/锁
Java面试知识点(全) 导航: https://nanxiang.blog.csdn.net/article/details/130640392 注:随时更新 JUC原子类 什么是CAS CAS的全称为Compare-And-Swap,直译就是对比交换。是一条CPU的原子指令,其作用是让CPU先进行比较两个值…...
CSS--移动web基础
01-移动 Web 基础 谷歌模拟器 模拟移动设备,方便查看页面效果 屏幕分辨率 分类: 物理分辨率:硬件分辨率(出厂设置)逻辑分辨率:软件 / 驱动设置 结论:制作网页参考 逻辑分辨率 视口 作用&a…...
Appuploader 常见错误及解决方法
转载:Appuploader 常见错误及解决方法 问题解决秘籍 遇到问题,第一个请登录苹果开发者官网 检查一遍账号是否有权限,是否被停用,是否过期,是否有协议需要同意,并且在右上角切换账号后检查所有关联的账号是否…...
消息通知之系统层事件发布相关流程
前言 Openharmony 3.1Release中存在消息通知的处理,消息通知包括系统层事件发布、消息订阅、消息投递与处理,为了开发者能够熟悉消息的处理流程,本篇文章主要介绍系统层事件发布的相关流程。 整体流程 代码流程 发布消息 { eventAction)w…...
Elsevier Ocean Engineering Guide for Authors 解读
文章目录 ★Types of contributions★Submission checklistEthics in publishing★Declaration of competing interestDeclaration of generative AI in scientific writingSubmission declaration and verificationPreprint posting on SSRNUse of inclusive languageReportin…...
基于Fragstats的土地利用景观格局分析
土地利用以及景观格局是当前全球环境变化研究的重要组成部分及核心内容,其对区域的可持续发展以及区域土地管理有非常重要的意义。通过对土地利用时空变化规律进行分析可以更好的了解土地利用变化的过程和机制,并且通过调整人类社会经济活动,…...
ffmpeg-转码脚本02
ffmpeg-转码脚本详解 高级脚本 以下为主要部分 更高级优化要见git上 mkv转码电影脚本 ECHO OFF REM 以下参数不可乱填 SET FFMPEG%~DP0\ffmpeg.exe ::------------------------------------------------------------------------------ CALL:PRO_LOOPDIR ::CALL:PRO_LOOPDIR_SU…...
SharedPreferences
Android轻量级数据存储 import android.content.Context; import android.content.SharedPreferences;public class SharedPreferencesUtil {private SharedPreferences sharedPreferences;private SharedPreferences.Editor editor;public SharedPreferencesUtil(Context con…...
服务(第二十五篇)redis的优化和持久化
持久化的功能:Redis是内存数据库,数据都是存储在内存中,为了避免服务器断电等原因导致Redis进程异常退出后数据的永久丢失,需要定期将Redis中的数据以某种形式(数据或命令)从内存保存到硬盘;当下…...
David Silver Lecture 7: Policy Gradient
1 Introduction 1.1 Policy-Based Reinforcement Learning 1.2 Value-based and policy based RL 基于值的强化学习 在基于值的 RL 中,目标是找到一个最优的值函数,通常是 Q 函数或 V 函数。这些函数为给定的状态或状态-动作对分配一个值,表…...
知识图谱学习笔记——(五)知识图谱推理
一、知识学习 声明:知识学习中本文主体按照浙江大学陈华钧教授的《知识图谱》公开课讲义进行介绍,并个别地方加入了自己的注释和思考,希望大家尊重陈华钧教授的知识产权,在使用时加上出处。感谢陈华钧教授。 (一&…...
用vs2010编译和调试多个arx版本的arx项目
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、一级标题二级标题三级标题四级标题五级标题六级标题升级原先vs2008版本的项目文件到2010,或直接用vs2010新建一个arx项目; vs中查看项目属性:Project menu -> Properties,项目名上右…...
安全相关词汇
• DEW: Data Encryption Workshop • HSM: Hardware Security Module • KMS: Key Management System • KAM: Key Account Management • DHSM: Dedicated Hardware Security Module • KPS: Key Pair Service • CSMS: Cloud Secret Management Service • PCI-DSS: …...
XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...
如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
【Linux】Linux 系统默认的目录及作用说明
博主介绍:✌全网粉丝23W,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...
Unity UGUI Button事件流程
场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...
Kubernetes 节点自动伸缩(Cluster Autoscaler)原理与实践
在 Kubernetes 集群中,如何在保障应用高可用的同时有效地管理资源,一直是运维人员和开发者关注的重点。随着微服务架构的普及,集群内各个服务的负载波动日趋明显,传统的手动扩缩容方式已无法满足实时性和弹性需求。 Cluster Auto…...
【Linux】Linux安装并配置RabbitMQ
目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的,需要先安…...
PydanticAI快速入门示例
参考链接:https://ai.pydantic.dev/#why-use-pydanticai 示例代码 from pydantic_ai import Agent from pydantic_ai.models.openai import OpenAIModel from pydantic_ai.providers.openai import OpenAIProvider# 配置使用阿里云通义千问模型 model OpenAIMode…...
