恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

aidl 跨进程通信流程

  • 首页
  • 资讯中心
  • /
  • aidl 跨进程通信流程

相关资讯

解决中兴b862v3.1-m2移动定制机顶盒刷机错误 2026/10/17 6:49:36
在 Python 编程中,**基础数据类型**、**变量**和**常量**是程序最底层的构建块 2026/10/17 6:44:36
【自用】DeepSeek V4架构解读-mHC 2026/10/17 6:44:36

最新资讯

从.sln到.slnx:.NET解决方案迁移实践与Git协作优化
ReadMeABook API Tokens完全指南:开发自动化脚本与第三方集成参考
【基于 Swoole+Hyperf 的微服务实战】第十一周·周一:异步日志采集与实时分析系统
如何10分钟跑通FLUX.2-klein-base-4b-fp8:FP8文生图模型快速上手教程
Qwen2-7B_rai_1.8.0_medusa_1.0_npu 命名深度拆解:RAI 1.8.0、Medusa 1.0 与 NPU 三大关键词到底是什么?
PostgreSQL表膨胀与索引膨胀:从MVCC原理到VACUUM实战

今日推荐

Qwen3.5-122B-A10B-singprobe幻觉检测实战:AUC 0.7806,如何实时揪出大模型一本正经的胡话?
NetSpot 实战:用信道分析与频宽优化解决 Wi-Fi 卡顿
C++ split() 字符串分割的五种实现与性能实测

本周热门

UE动画修改实战:从资产编辑到重定向与蒙太奇驱动
统计随机数生成器攻击下的KLJN安全密钥交换协议Matlab仿真
政务API安全治理:资产测绘、低代码编排与行标对标实践

本月精选

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证
2026 大模型集体涨价:用 Python 做企业 Token 成本测算与选型避坑(附配置)

aidl 跨进程通信流程

发布时间:2026/10/17 6:49:36
aidl 跨进程通信流程 新建一个工程然后想新建aidl文件src/main 右键 → New → AIDL, 弹出的窗口是灰色的提示 AIDL filerequires setting the buildfeatures.aidl to true in the Gradle build files根据提示在build.gradle.kts中开启aidl支持同步之后就可以新建aidl文件了还是这个步骤点击aidl菜单。生成了一个模板aidl文件随意定义点接口然后编译下自动生成了IMyAidlInterface.java文件如下文件内容如下/* * This file is auto-generated. DO NOT MODIFY. * Using: C:\\Users\\86186\\AppData\\Local\\Android\\Sdk\\build-tools\\36.0.0\\aidl.exe -pC:\\Users\\86186\\AppData\\Local\\Android\\Sdk\\platforms\\android-36\\framework.aidl -oE:\\android\\projects\\binderdemo\\app\\build\\generated\\aidl_source_output_dir\\debug\\out -IE:\\android\\projects\\binderdemo\\app\\src\\main\\aidl -IE:\\android\\projects\\binderdemo\\app\\src\\debug\\aidl -IC:\\Users\\86186\\.gradle\\caches\\9.1.0\\transforms\\126ef151667daa32756d4a8a1016b441\\workspace\\transformed\\core-1.18.0\\aidl -IC:\\Users\\86186\\.gradle\\caches\\9.1.0\\transforms\\b4877cb6e78f8cd2f0c4778997dbc841\\workspace\\transformed\\versionedparcelable-1.1.1\\aidl -dC:\\Users\\86186\\AppData\\Local\\Temp\\aidl5851206668669868321.d E:\\android\\projects\\binderdemo\\app\\src\\main\\aidl\\com\\example\\binderdemo\\IMyAidlInterface.aidl * * DO NOT CHECK THIS FILE INTO A CODE TREE (e.g. git, etc..). * ALWAYS GENERATE THIS FILE FROM UPDATED AIDL COMPILER * AS A BUILD INTERMEDIATE ONLY. THIS IS NOT SOURCE CODE. */ package com.example.binderdemo; // Declare any non-default types here with import statements public interface IMyAidlInterface extends android.os.IInterface { /** Default implementation for IMyAidlInterface. */ public static class Default implements com.example.binderdemo.IMyAidlInterface { Override public int add(int a, int b) throws android.os.RemoteException { return 0; } Override public java.lang.String getMessage() throws android.os.RemoteException { return null; } 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.binderdemo.IMyAidlInterface { /** Construct the stub and attach it to the interface. */ SuppressWarnings(this-escape) public Stub() { this.attachInterface(this, DESCRIPTOR); } /** * Cast an IBinder object into an com.example.binderdemo.IMyAidlInterface interface, * generating a proxy if needed. */ public static com.example.binderdemo.IMyAidlInterface asInterface(android.os.IBinder obj) { if ((objnull)) { return null; } android.os.IInterface iin obj.queryLocalInterface(DESCRIPTOR); if (((iin!null)(iin instanceof com.example.binderdemo.IMyAidlInterface))) { return ((com.example.binderdemo.IMyAidlInterface)iin); } return new com.example.binderdemo.IMyAidlInterface.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; if (code android.os.IBinder.FIRST_CALL_TRANSACTION code android.os.IBinder.LAST_CALL_TRANSACTION) { data.enforceInterface(descriptor); } if (code INTERFACE_TRANSACTION) { reply.writeString(descriptor); return true; } switch (code) { case TRANSACTION_add: { int _arg0; _arg0 data.readInt(); int _arg1; _arg1 data.readInt(); int _result this.add(_arg0, _arg1); reply.writeNoException(); reply.writeInt(_result); break; } case TRANSACTION_getMessage: { java.lang.String _result this.getMessage(); reply.writeNoException(); reply.writeString(_result); break; } default: { return super.onTransact(code, data, reply, flags); } } return true; } private static class Proxy implements com.example.binderdemo.IMyAidlInterface { 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 int add(int a, int b) throws android.os.RemoteException { android.os.Parcel _data android.os.Parcel.obtain(); android.os.Parcel _reply android.os.Parcel.obtain(); int _result; try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeInt(a); _data.writeInt(b); boolean _status mRemote.transact(Stub.TRANSACTION_add, _data, _reply, 0); _reply.readException(); _result _reply.readInt(); } finally { _reply.recycle(); _data.recycle(); } return _result; } Override public java.lang.String getMessage() 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); boolean _status mRemote.transact(Stub.TRANSACTION_getMessage, _data, _reply, 0); _reply.readException(); _result _reply.readString(); } finally { _reply.recycle(); _data.recycle(); } return _result; } } static final int TRANSACTION_add (android.os.IBinder.FIRST_CALL_TRANSACTION 0); static final int TRANSACTION_getMessage (android.os.IBinder.FIRST_CALL_TRANSACTION 1); } /** hide */ public static final java.lang.String DESCRIPTOR com.example.binderdemo.IMyAidlInterface; public int add(int a, int b) throws android.os.RemoteException; public java.lang.String getMessage() throws android.os.RemoteException; }新建RemoteService 如下:详细代码如下package com.example.binderdemo; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.os.Process; import android.util.Log; public class RemoteService extends Service { private static final String TAG RemoteService; private final IMyAidlInterface.Stub binder new IMyAidlInterface.Stub() { Override public int add(int a, int b) { Log.d(TAG, add( a , b ) thread Thread.currentThread().getName() , pid Process.myPid()); return a b; } Override public String getMessage() { Log.d(TAG, getMessage thread Thread.currentThread().getName() , pid Process.myPid()); return Hello from pid Process.myPid() , 为人不识陈近南纵称英雄也枉然。; } }; Override public IBinder onBind(Intent intent) { Log.d(TAG, onBind thread Thread.currentThread().getName() , pid Process.myPid()); return binder; } }指定这个服务运行在子进程名字随意MainActivity中调用这个服务package com.example.binderdemo; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.os.Process; import android.os.RemoteException; import android.util.Log; import android.widget.TextView; import androidx.activity.ComponentActivity; import androidx.annotation.Nullable; public class MainActivity extends ComponentActivity { private static final String TAG ClientMainActivity; private IMyAidlInterface remote; private TextView tv; private boolean bound; private final ServiceConnection conn new ServiceConnection() { Override public void onServiceConnected(ComponentName name, IBinder service) { Log.d(TAG, onServiceConnected thread Thread.currentThread().getName()); // 这个service类型是android.os.BinderProxy,远端代理用于跨进程通信。 // asInterface返回一个客户端Proxy对象里面的成员变量mRemote就是这个service对象。 remote IMyAidlInterface.Stub.asInterface(service); try { int result remote.add(1, 2); String msg remote.getMessage(); Log.d(TAG, add result result , msg msg); tv.setText(result result \n msg); Log.d(TAG, 当前客户端进程 Process.myPid()); Log.d(TAG, remote: remote); Log.d(TAG, service: service); } catch (RemoteException e) { e.printStackTrace(); } } Override public void onServiceDisconnected(ComponentName name) { Log.d(TAG, onServiceDisconnected); remote null; } }; Override protected void onCreate(Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); tv new TextView(this); setContentView(tv); Intent intent new Intent(this, RemoteService.class); bound bindService(intent, conn, BIND_AUTO_CREATE); } Override protected void onDestroy() { if (bound) { unbindService(conn); bound false; } super.onDestroy(); } }运行看下日志ok. 由此看出Client 的 pid 和 RemoteService 的 pid 不一样。onBind 在服务端主线程执行。add() 和 getMessage() 不在主线程而在 Binder:xxx_x 线程。客户端调用 remote.add(1, 2) 看起来像普通方法实际跨进程了。追踪下关键代码IMyAidlInterface.Stub.asInterface(service)。这句代码生成客户端代理对象即IMyAidlInterface.java里的Proxy对象其中service参数打印出来类型是android.os.BinderProxy,该参数后续会被用于跨进程调用服务端接口。下面会提到。这个asInterface方法详细代码如下public static com.example.binderdemo.IMyAidlInterface asInterface(android.os.IBinder obj) { if ((objnull)) { return null; } android.os.IInterface iin obj.queryLocalInterface(DESCRIPTOR); // 在当前进程中查询本地 IInterface 实现实例。跨进程则返回null if (((iin!null)(iin instanceof com.example.binderdemo.IMyAidlInterface))) { return ((com.example.binderdemo.IMyAidlInterface)iin); } return new com.example.binderdemo.IMyAidlInterface.Stub.Proxy(obj); }参数android.os.IBinder obj 当跨进程通信时obj类型为android.os.BinderProxy。asInterface最终返回的是Proxy对象。而service和客户端在同一个进程这个obj就是Binder即服务端的 Stub 本身需要理解下android.os.IInterface iin obj.queryLocalInterface(DESCRIPTOR); 这句代码DESCRIPTOR 是接口的唯一标识符。研究下原理先打开IMyAidlInterface.java里面的内部类Stub里面包含有个类Proxy其中add方法是这样调用的Override public int add(int a, int b) throws android.os.RemoteException { android.os.Parcel _data android.os.Parcel.obtain(); android.os.Parcel _reply android.os.Parcel.obtain(); int _result; try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeInt(a); _data.writeInt(b); boolean _status mRemote.transact(Stub.TRANSACTION_add, _data, _reply, 0); _reply.readException(); _result _reply.readInt(); } finally { _reply.recycle(); _data.recycle(); } return _result; }这个Proxy是客户端代理。它把参数写入Parcel对象中然后调用 mRemote.transact()方法发起跨进程调用。然后再从 _reply 里读调用结果。其中mRemote就算刚才IMyAidlInterface.Stub.asInterface(service)这句代码的参数。再看下Stub类的onTransact方法即服务端service接收调用,有这个代码片段switch (code) { case TRANSACTION_add: { int _arg0; _arg0 data.readInt(); int _arg1; _arg1 data.readInt(); int _result this.add(_arg0, _arg1); // 即RemoteService里面内部类实现的那个add方法 reply.writeNoException(); reply.writeInt(_result); break; }Stub 是服务端桩。Binder 线程收到调用后进入 onTransact。它从 _data 读参数。调用服务里的那个add()方法再把结果写进 _reply。ok. 这个是aidl跨进程通信大致调用链路。后面再继续研究下。总结AIDL 就是帮忙生成一个 Proxy 和一个 Stub不用手写 Parcel 的读写、不用手写 transact / onTransact 的分发。Proxy 负责打包参数 → transact → 解包结果Stub 负责解包参数 → 调用实现 → 打包结果接口名 DESCRIPTOR 负责校验调用双方是不是同一个接口TRANSACTION_xxx 负责告诉 Stub 这次调用的是哪个方法

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号