IPC(三)--.aidl生成文件解析

移步Android跨进程通信IPC

简介

在创建完aidl文件并对项目Rebuild后系统会自动生成与之对应的java文件。下面将会对生成的java文件做注释分析,生成的java文件也将使用上篇文章的IService.aidl生成的java文件。

代码分析

全部源码

package com.wuyazhou.learn.IPC.aidl;

//在Binder中可以传输的接口都需要继承IInterface
public interface IService extends android.os.IInterface
{
    //IService的内部类Stub,继承Binder,主体部分关联至服务端Service,内部类Proxy部分关联至客户端Client。Stub继承外部接口,也是接口实体类。
    public static abstract class Stub extends android.os.Binder implements com.wuyazhou.learn.IPC.aidl.IService
    {
        private static final java.lang.String DESCRIPTOR = "com.wuyazhou.learn.IPC.aidl.IService";
        public Stub()
        {
            this.attachInterface(this, DESCRIPTOR);
        }
        //通过此静态方法可获取到aidl实体Stub,或者Stub的代理类Proxy
        public static com.wuyazhou.learn.IPC.aidl.IService asInterface(android.os.IBinder obj)
        {
            if ((obj==null)) {
                return null;
            }
            android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
            //判断客户端和服务端是不是在一个进程内,如果是则直接返回Stub实体对象。如果不是则返回Stub的代理Proxy类。
            if (((iin!=null)&&(iin instanceof com.wuyazhou.learn.IPC.aidl.IService))) {
                return ((com.wuyazhou.learn.IPC.aidl.IService)iin);
            }
            return new com.wuyazhou.learn.IPC.aidl.IService.Stub.Proxy(obj);
        }
        @Override
        //获取binder对象
        public android.os.IBinder asBinder()
        {
            return this;
        }
        @Override 
        //客户端请求通过系统底层封装后交由此方法执行,此方法运行在服务端的Binder线程池中,将会根据请求标志位flag调用服务端Server的方法。
        public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {
            java.lang.String descriptor = DESCRIPTOR;
            //根据标志位flag调用服务端方法
            switch (code)
            {
                case INTERFACE_TRANSACTION: {
                    reply.writeString(descriptor);
                    return true;
                }

                case TRANSACTION_hello: {
                    data.enforceInterface(descriptor);
                    java.lang.String _arg0;
                    _arg0 = data.readString();
                    java.lang.String _result = this.hello(_arg0);
                    reply.writeNoException();
                    reply.writeString(_result);
                    return true;
                }
                case TRANSACTION_addBook: {
                    data.enforceInterface(descriptor);
                    com.wuyazhou.learn.IPC.aidl.Book _result = this.addBook();
                    reply.writeNoException();
                    if ((_result!=null)) {
                        reply.writeInt(1);
                        _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
                    }
                    else {
                        reply.writeInt(0);
                    }
                    return true;
                }
                default: {
                    return super.onTransact(code, data, reply, flags);
                }
            }
        }
        //Stub的代理类Proxy,跨进程调用时将由此类作为客户端和服务端的连接。
        private static class Proxy implements com.wuyazhou.learn.IPC.aidl.IService {
            private android.os.IBinder mRemote;
            Proxy(android.os.IBinder remote) {
                mRemote = remote;
            }
            //获取Binder对象
            @Override 
            public android.os.IBinder asBinder(){
                return mRemote;
            }
            public java.lang.String getInterfaceDescriptor() {
                return DESCRIPTOR;
            }
            //客户端方法对应转化,将调用交付给binder处理
            @Override 
            public java.lang.String hello(java.lang.String name) 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.writeString(name);
                    //将请求参数和请求方法标志位flag和返回数据的存储器交付给Binder处理
                    mRemote.transact(Stub.TRANSACTION_hello, _data, _reply, 0);
                    _reply.readException();
                    _result = _reply.readString();
                }
                finally {
                    _reply.recycle();
                    _data.recycle();
                }
                return _result;
            }
            //客户端方法对应转化,将调用交付给binder处理
            @Override 
            public com.wuyazhou.learn.IPC.aidl.Book addBook() throws android.os.RemoteException {
                android.os.Parcel _data = android.os.Parcel.obtain();
                android.os.Parcel _reply = android.os.Parcel.obtain();
                com.wuyazhou.learn.IPC.aidl.Book _result;
                try {
                    _data.writeInterfaceToken(DESCRIPTOR);
                    //将请求参数和请求方法标志位flag和返回数据的存储器交付给Binder处理
                    mRemote.transact(Stub.TRANSACTION_addBook, _data, _reply, 0);
                    _reply.readException();
                    if ((0!=_reply.readInt())) {
                        _result = com.wuyazhou.learn.IPC.aidl.Book.CREATOR.createFromParcel(_reply);
                    }
                    else {
                        _result = null;
                    }
                }
                finally {
                    _reply.recycle();
                    _data.recycle();
                }
                return _result;
            }
        }
        //客户端调用接口时会在Proxy的方法内将方法标志flag传入,以便Binder可以通过标志flag查找对应的方法在服务端调用
        static final int TRANSACTION_hello = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
        static final int TRANSACTION_addBook = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
    }
    //aidl定义的接口
    public java.lang.String hello(java.lang.String name) throws android.os.RemoteException;
    public com.wuyazhou.learn.IPC.aidl.Book addBook() throws android.os.RemoteException;
}

上面代码主要分为三部分

  • 1. aidl接口部分
  • 2. aidl内部类Stub部分
  • 3. Stub内部类Proxy部分

1. aidl接口部分

    //aidl定义的接口
    public java.lang.String hello(java.lang.String name) throws android.os.RemoteException;
    public com.wuyazhou.learn.IPC.aidl.Book addBook() throws android.os.RemoteException;

这部分只是单纯的声明一下aidl内写的接口,并抛出异常

3. Stub内部类Proxy部分

        //Stub的代理类Proxy,跨进程调用时将由此类作为客户端和服务端的连接。
        private static class Proxy implements com.wuyazhou.learn.IPC.aidl.IService {
            private android.os.IBinder mRemote;
            Proxy(android.os.IBinder remote) {
                mRemote = remote;
            }
            //获取Binder对象
            @Override 
            public android.os.IBinder asBinder(){
                return mRemote;
            }
            public java.lang.String getInterfaceDescriptor() {
                return DESCRIPTOR;
            }
            //客户端方法对应转化,将调用交付给binder处理
            @Override 
            public java.lang.String hello(java.lang.String name) 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.writeString(name);
                    //将请求参数和请求方法标志位flag和返回数据的存储器交付给Binder处理
                    mRemote.transact(Stub.TRANSACTION_hello, _data, _reply, 0);
                    _reply.readException();
                    _result = _reply.readString();
                }
                finally {
                    _reply.recycle();
                    _data.recycle();
                }
                return _result;
            }
            //客户端方法对应转化,将调用交付给binder处理
            @Override 
            public com.wuyazhou.learn.IPC.aidl.Book addBook() throws android.os.RemoteException {
                android.os.Parcel _data = android.os.Parcel.obtain();
                android.os.Parcel _reply = android.os.Parcel.obtain();
                com.wuyazhou.learn.IPC.aidl.Book _result;
                try {
                    _data.writeInterfaceToken(DESCRIPTOR);
                    //将请求参数和请求方法标志位flag和返回数据的存储器交付给Binder处理
                    mRemote.transact(Stub.TRANSACTION_addBook, _data, _reply, 0);
                    _reply.readException();
                    if ((0!=_reply.readInt())) {
                        _result = com.wuyazhou.learn.IPC.aidl.Book.CREATOR.createFromParcel(_reply);
                    }
                    else {
                        _result = null;
                    }
                }
                finally {
                    _reply.recycle();
                    _data.recycle();
                }
                return _result;
            }
        }

此类为Stub的内部类主要是作为客户端Client到Binder的桥梁,内部也是继承Stub实现的aidl类,实现aidl的接口,主要是做一些跨进程进入Binder的准备工作,比如将参数放入Parcel容器内,创建一个Parcel容器用来存储返回结果。
需要注意的是在实现的aidl接口方法内调用了mRemote.transact()方法后当前线程会挂起,经过一些列Binder操作后服务端的onTransact()方法会被调用,直到IPC过程返回后,当前线程继续执行。所以这里可能会导致ANR,使用时要特别注意。

2. aidl内部类Stub部分

//IService的内部类Stub,继承Binder,主体部分关联至服务端Service,内部类Proxy部分关联至客户端Client。Stub继承外部接口,也是接口实体类。
    public static abstract class Stub extends android.os.Binder implements com.wuyazhou.learn.IPC.aidl.IService {
        private static final java.lang.String DESCRIPTOR = "com.wuyazhou.learn.IPC.aidl.IService";
        public Stub()
        {
            this.attachInterface(this, DESCRIPTOR);
        }
        //通过此静态方法可获取到aidl实体Stub,或者Stub的代理类Proxy
        public static com.wuyazhou.learn.IPC.aidl.IService asInterface(android.os.IBinder obj)
        {
            if ((obj==null)) {
                return null;
            }
            android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
            //判断客户端和服务端是不是在一个进程内,如果是则直接返回Stub实体对象。如果不是则返回Stub的代理Proxy类。
            if (((iin!=null)&&(iin instanceof com.wuyazhou.learn.IPC.aidl.IService))) {
                return ((com.wuyazhou.learn.IPC.aidl.IService)iin);
            }
            return new com.wuyazhou.learn.IPC.aidl.IService.Stub.Proxy(obj);
        }
        @Override
        //获取binder对象
        public android.os.IBinder asBinder()
        {
            return this;
        }
        @Override 
        //客户端请求通过系统底层封装后交由此方法执行,此方法运行在服务端的Binder线程池中,将会根据请求标志位flag调用服务端Server的方法。
        public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {
            java.lang.String descriptor = DESCRIPTOR;
            //根据标志位flag调用服务端方法
            switch (code)
            {
                case INTERFACE_TRANSACTION: {
                    reply.writeString(descriptor);
                    return true;
                }

                case TRANSACTION_hello: {
                    data.enforceInterface(descriptor);
                    java.lang.String _arg0;
                    _arg0 = data.readString();
                    java.lang.String _result = this.hello(_arg0);
                    reply.writeNoException();
                    reply.writeString(_result);
                    return true;
                }
                case TRANSACTION_addBook: {
                    data.enforceInterface(descriptor);
                    com.wuyazhou.learn.IPC.aidl.Book _result = this.addBook();
                    reply.writeNoException();
                    if ((_result!=null)) {
                        reply.writeInt(1);
                        _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
                    }
                    else {
                        reply.writeInt(0);
                    }
                    return true;
                }
                default: {
                    return super.onTransact(code, data, reply, flags);
                }
            }
        }
        ...
    }

这个类是对aidl外部类的实现是binder层到Server层的桥梁,主要是通过onTransact()方法。也是获取客户端到binder层的桥梁proxy的入口,主要是通过asInterface()方法,获取Stub类的代理Proxy。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,137评论 6 511
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,824评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,465评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,131评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,140评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,895评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,535评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,435评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,952评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,081评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,210评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,896评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,552评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,089评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,198评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,531评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,209评论 2 357

推荐阅读更多精彩内容