Android AIDL机制解析

关于AIDL的使用,已经在之前的博客Android AIDL的基本用法

里介绍过,这次主要通过剖析AIDL生成的java文件来讲解AIDL机制。用的还是之前博客的例子,它在build目录下生成的 IMyAidlInterface.java 文件内容如下:

/*
 * This file is auto-generated.  DO NOT MODIFY.
 * Original file: D:\\AndroidStudioProjects\\AIDLServer\\app\\src\\main\\aidl\\cn\\qiracle\\aidlserver\\IMyAidlInterface.aidl
 */
package cn.qiracle.aidlserver;
// Declare any non-default types here with import statements

public interface IMyAidlInterface extends android.os.IInterface
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements cn.qiracle.aidlserver.IMyAidlInterface
{
private static final java.lang.String DESCRIPTOR = "cn.qiracle.aidlserver.IMyAidlInterface";
/** Construct the stub at attach it to the interface. */
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
/**
 * Cast an IBinder object into an cn.qiracle.aidlserver.IMyAidlInterface interface,
 * generating a proxy if needed.
 */
public static cn.qiracle.aidlserver.IMyAidlInterface asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof cn.qiracle.aidlserver.IMyAidlInterface))) {
return ((cn.qiracle.aidlserver.IMyAidlInterface)iin);
}
return new cn.qiracle.aidlserver.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
{
switch (code)
{
case INTERFACE_TRANSACTION:
{
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_print:
{
data.enforceInterface(DESCRIPTOR);
this.print();
reply.writeNoException();
return true;
}
case TRANSACTION_add:
{
data.enforceInterface(DESCRIPTOR);
int _arg0;
_arg0 = data.readInt();
int _arg1;
_arg1 = data.readInt();
int _result = this.add(_arg0, _arg1);
reply.writeNoException();
reply.writeInt(_result);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements cn.qiracle.aidlserver.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 void print() throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_print, _data, _reply, 0);
_reply.readException();
}
finally {
_reply.recycle();
_data.recycle();
}
}
@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);
mRemote.transact(Stub.TRANSACTION_add, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
static final int TRANSACTION_print = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_add = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
}
public void print() throws android.os.RemoteException;
public int add(int a, int b) throws android.os.RemoteException;
}

结合上面的代码,我们一起看下:

Stub 是aidl接口的静态抽象内部类,它继承于binder同时实现了aidl的接口,因为是抽象类,具体实现还是在server端service里创建一个binder的内部类继承这个Stub实现的

Proxy 是Stub的静态内部类,它也实现了aidl的接口

调用流程
Client 在 bindService 之后,在 onServiceConnected 的回调里,拿到 IBinder 对象,通过 asInterface 方法,拿到proxy对象,前面说的,Proxy是Stub的静态内部类,它也实现了aidl的接口,所以通过这个proxy对象,我们就可以调 aidl 接口里定义的方法。这个 proxy 是个代理,它对 aidl 接口的具体实现是把要调的方法名,参数通过 remote. transact 传给服务端,这里的 remote 就是前面的 binder 对象,binder 通过 IPC 机制把要调用的方法名,方法参数传给了Server端.

这时来到 Server 端,通过 client 端的 remote.transact 方法,会回调 Server 端的 onTransact 方法,onTransact 方法里有个 switch-case,根据回调里的code值,也就是方法名,找到对应的方法去执行,具体执行的方法就是service里创建的内部binder实现类里实现的方法。

总结一下,从这个过程也可以看出,AIDL 用的是代理模式,Binder机制。所谓调用Server方法其实是通过代理对象把要调用的方法名,方法参数通过binder机制传给了Server端,server端再自己调用的一个过程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值