Android高级-架构师-Binder的架构设计

我们通过一个Demo将AIDL的实现,然后明白他的调用过程。方便后面的源码学习

这个Demo主要是模拟qq授权登录的过程:从Binder_A,点击QQ登录,跳转到Binder_B(假装为QQ)登录获取授权,授权成功后再调用Binder_A,将结果返回,完成登录。

首先我们先准备Binder_B,因为它需要先向Binder注册成为ServiceManager,并提供哪些方法?

1:首先准备Binder_B的界面:

如上图所示,

2:然后我们开始准备AIDL文件,告诉Binder我们能提供哪些方法

// ILoginInterface.aidl
//注意包名
package com.netease.binder;

// Declare any non-default types here with import statements

interface ILoginInterface {

    // 登录
    void login();

    // 登录返回
    void loginCallback(boolean loginStatus, String loginUser);
}

点击Build 我们可以看到生成了一个 java文件


public interface ILoginInterface extends android.os.IInterface {
    /**
     * Local-side IPC implementation stub class.
     */
    public static abstract class Stub extends android.os.Binder implements com.netease.binder.ILoginInterface {
        private static final java.lang.String DESCRIPTOR = "com.netease.binder.ILoginInterface";

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

        /**
         * Cast an IBinder object into an com.netease.binder.ILoginInterface interface,
         * generating a proxy if needed.
         */
        public static com.netease.binder.ILoginInterface asInterface(android.os.IBinder obj) {
            if ((obj == null)) {
                return null;
            }
            android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
            if (((iin != null) && (iin instanceof com.netease.binder.ILoginInterface))) {
                return ((com.netease.binder.ILoginInterface) iin);
            }
            return new com.netease.binder.ILoginInterface.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_login: {
                    data.enforceInterface(DESCRIPTOR);
                    this.login();
                    reply.writeNoException();
                    return true;
                }
                case TRANSACTION_loginCallback: {
                    data.enforceInterface(DESCRIPTOR);
                    boolean _arg0;
                    _arg0 = (0 != data.readInt());
                    java.lang.String _arg1;
                    _arg1 = data.readString();
                    this.loginCallback(_arg0, _arg1);
                    reply.writeNoException();
                    return true;
                }
            }
            return super.onTransact(code, data, reply, flags);
        }

        private static class Proxy implements com.netease.binder.ILoginInterface {
            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 login() 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_login, _data, _reply, 0);
                    _reply.readException();
                } finally {
                    _reply.recycle();
                    _data.recycle();
                }
            }
// 登录返回

            @Override
            public void loginCallback(boolean loginStatus, java.lang.String loginUser) throws android.os.RemoteException {
                android.os.Parcel _data = android.os.Parcel.obtain();
                android.os.Parcel _reply = android.os.Parcel.obtain();
                try {
                    _data.writeInterfaceToken(DESCRIPTOR);
                    _data.writeInt(((loginStatus) ? (1) : (0)));
                    _data.writeString(loginUser);
                    mRemote.transact(Stub.TRANSACTION_loginCallback, _data, _reply, 0);
                    _reply.readException();
                } finally {
                    _reply.recycle();
                    _data.recycle();
                }
            }
        }

        static final int TRANSACTION_login = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
        static final int TRANSACTION_loginCallback = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
    }
// 登录

    public void login() throws android.os.RemoteException;
// 登录返回

    public void loginCallback(boolean loginStatus, java.lang.String loginUser) throws android.os.RemoteException;
}

 生成的Java文件分为几部分,首先ILoginInterface 是继承的IInterface

 1:IInterface : IInterface 代表的就是 Server 进程对象具备什么样的能力(能提供哪些方法,其实对应的就是 AIDL 文件中定义的接口)

IInterface的实现类是IServiceManager:

 

   内部类 ILoginInterface.Stub,是一个抽象类, 具体的 IInterface 的相关实现需要调用方自己实现

2: IBinder 是一个接口,代表了一种跨进程通信的能力。只要实现了这个借口,这个对象就能跨进程传输。

3:Proxy::同样也实现了ILoginInterface接口,重写了里面的方法。后面我们会一点点走调用过程。

3:准备服务:

public class MyService extends Service {

    @Override
    public IBinder onBind(Intent intent) {

        return new ILoginInterface.Stub() {
            @Override
            public void login() throws RemoteException {
             //to do 登录成功,返回给调用方结果
 

        }
            @Override
            public void loginCallback(boolean loginStatus, String loginUser) throws RemoteException {
            }
        };
    }

}

这个MyService里面 我们能可以看到,extends Service ,这里的new ILoginInterface.stub就是上面抽象类的实现类,里面定义了接口方法。

    @Nullable
    public abstract IBinder onBind(Intent intent);

返回值我们可以看到  是new 了一个ILoginInterface.Stub,重写了他里面定义的接口方法

在AndroiMainfest.xml 中注册这个组件,表明过滤我action为"BinderB_Action"的动作/请求
 

       <service
            android:name=".service.MyService"
            android:enabled="true"
            android:exported="true"
            android:process=":remote_service">

            <intent-filter>
                <!-- 激活 MyService 唯一name,不能重名-->
                <action android:name="BinderB_Action" />
            </intent-filter>
        </service>

到此  我们的服务端准备暂时高一段落。

 

 

首先我们开始制作Binder的界面:

截图如下所示:

然后开始准备跨进程的AIDL文件

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值