Android面试题目之(八) AIDL的设计原理

本文深入探讨了AIDL在Android中的实现原理,并提供了一种不依赖标准AIDL语法的自定义实现方案。该方案利用Binder机制和适配器模式,使Service与客户端之间的通信更加灵活。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 首先从抽象层次上来讲。AIDL实际上是在玩远程代理。远程代理对象,完成进程间通信:


 

 

2. 下面这个图展示了BinderProxy,Binder 和IBinder的关系。值得注意的是,其中Binder的transaction方法是没有用处的, 本地的调用没有必要执行transaction。另外,由于本地桩要接收消息,因此Binder有个方法会被调用,也就是execTransact, 这个方法是用native的onTransact调用过来的。因此,onTransact可以被认为是接受消息的事件。

 



 3.

有了以上的理论基础,抛开AIDL语法,自己写AIDL通信。其实也很简单。 看看上面的桩,它继承于Binder,同时又实现了接口IInterface 这是一个适配者模式。谈到适配者模式,一种方式就是通过继承进行适配。还有一种方式是通过组合, 现在就把这种适配者模式改为组合吧!这里既有代理模式,又有适配者模式,主要看所说的参与者对象是什么。

 

 

 

他们俩最大的区别就是:

 

l  代理模式俩对象都是相同的接口。

 

l  而适配者模式不是。

 

 

 

public class CommonBinder extends Binder {

    private OnTransactListener mOnTransactListener;

    public void setOnTransactListener(OnTransactListener lsr) {
        mOnTransactListener = lsr;
    }

    @Override
    protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
        if (mOnTransactListener != null) {
            return mOnTransactListener.onTransact(code, data, reply, flags);
        }
        return super.onTransact(code, data, reply, flags);
    }
}

 

 

其中的listener

 

public interface OnTransactListener {

    public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException;
}

 


对桩进行修改,使其使用组合的方式来适配

 

public abstract  class Stub implements IMyService, OnTransactListener {

    private static final String DESCRIPTOR = "com.a51droidgame.testmemoryleak.IMyService";

    private CommonBinder mCommonBinder;

    /**
     * Construct the stub at attach it to the interface.
     */
    public Stub(CommonBinder commonBinder) {
        mCommonBinder = commonBinder;
        commonBinder.setOnTransactListener(this);
        mCommonBinder.attachInterface(this, DESCRIPTOR);
    }

    /**
     * Cast an IBinder object into an com.a51droidgame.testmemoryleak.IMyService interface,
     * generating a proxy if needed.
     */
    public static IMyService asInterface(android.os.IBinder obj) {
        if ((obj == null)) {
            return null;
        }
        android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
        if (((iin != null) && (iin instanceof IMyService))) {
            return ((IMyService) iin);
        }
        return new Proxy(obj);
    }

    @Override
    public android.os.IBinder asBinder() {
        return mCommonBinder;
    }

    @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_sayHello: {
                data.enforceInterface(DESCRIPTOR);
                String _result = this.sayHello();
                reply.writeNoException();
                reply.writeString(_result);
                return true;
            }
        }
        return false;
    }

 

 

 

 

 

下面看看service的代码

 

public class TestService extends Service {

    private static final String TAG = "MainActivity";

    private static class MyService extends Stub {
        public MyService() {
            super(new CommonBinder());
        }
        @Override
        public String sayHello() throws RemoteException {
             Log.e(TAG, "sayHello");
            return "hello";
        }
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.e(TAG, "onBind " + intent, new Exception());
        return new MyService().asBinder();
    }

    @Override
    public boolean onUnbind(Intent intent) {
        return super.onUnbind(intent);
    }
}

 好了,到此为止了。是不是很酷呢。我们的Service可以不用是Binder了! 完完全全就是个桩(Stub),是不是很酷呢。

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值