aidl使用_通过代码例子详解aidl跨进程通信的调用流程

使用aidl进行跨进程通信

563fc6bd07224fcdaf28125a345d885c

aidl跨进程通信流程

1、首先创建aidl文件,并声明接口:

// IRemoteService.aidlpackage source.analysis.android29.aidl;// Declare any non-default types here with import statementsparcelable User;interface IRemoteService {    int getValue();    User getUser(in String username);}

2、创建接口需要的Parcelable实体类:

public class User implements Parcelable {    private int age;    private String nickname;    private int gender;    public int getAge() {        return age;    }    public User setAge(int age) {        this.age = age;        return this;    }    public String getNickname() {        return nickname;    }    public User setNickname(String nickname) {        this.nickname = nickname;        return this;    }    public int getGender() {        return gender;    }        public User setGender(int gender) {        this.gender = gender;        return this;    }    public User() {    }    @Override    public int describeContents() {        return 0;    }    @Override    public void writeToParcel(Parcel dest, int flags) {        dest.writeInt(this.age);        dest.writeString(this.nickname);        dest.writeInt(this.gender);    }    protected User(Parcel in) {        this.age = in.readInt();        this.nickname = in.readString();        this.gender = in.readInt();    }    public static final Creator CREATOR = new Creator() {        @Override        public User createFromParcel(Parcel source) {            return new User(source);        }        @Override        public User[] newArray(int size) {            return new User[size];        }    };}

3、编译后自动生成接口和空的实体类:

IRemoteService

/* * This file is auto-generated.  DO NOT MODIFY. */package source.analysis.android29.aidl;// Declare any non-default types here with import statementspublic interface IRemoteService extends android.os.IInterface {    /**     * Default implementation for IRemoteService.     */    public static class Default implements source.analysis.android29.aidl.IRemoteService {        @Override        public int getValue() throws android.os.RemoteException {            return 0;        }        @Override        public source.analysis.android29.aidl.User getUser(java.lang.String username) 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 source.analysis.android29.aidl.IRemoteService {        private static final java.lang.String DESCRIPTOR = "source.analysis.android29.aidl.IRemoteService";        /**         * Construct the stub at attach it to the interface.         */        public Stub() {            this.attachInterface(this, DESCRIPTOR);        }        /**         * Cast an IBinder object into an source.analysis.android29.aidl.IRemoteService interface,         * generating a proxy if needed.         */        public static source.analysis.android29.aidl.IRemoteService asInterface(android.os.IBinder obj) {            if ((obj == null)) {                return null;            }            android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);            if (((iin != null) && (iin instanceof source.analysis.android29.aidl.IRemoteService))) {                return ((source.analysis.android29.aidl.IRemoteService) iin);            }            return new source.analysis.android29.aidl.IRemoteService.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;            switch (code) {                case INTERFACE_TRANSACTION: {                    reply.writeString(descriptor);                    return true;                }                case TRANSACTION_getValue: {                    data.enforceInterface(descriptor);                    int _result = this.getValue();                    reply.writeNoException();                    reply.writeInt(_result);                    return true;                }                case TRANSACTION_getUser: {                    data.enforceInterface(descriptor);                    java.lang.String _arg0;                    _arg0 = data.readString();                    source.analysis.android29.aidl.User _result = this.getUser(_arg0);                    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);                }            }        }        private static class Proxy implements source.analysis.android29.aidl.IRemoteService {            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 getValue() 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);                    boolean _status = mRemote.transact(Stub.TRANSACTION_getValue, _data, _reply, 0);                    if (!_status && getDefaultImpl() != null) {                        return getDefaultImpl().getValue();                    }                    _reply.readException();                    _result = _reply.readInt();                } finally {                    _reply.recycle();                    _data.recycle();                }                return _result;            }            @Override            public source.analysis.android29.aidl.User getUser(java.lang.String username) throws android.os.RemoteException {                android.os.Parcel _data = android.os.Parcel.obtain();                android.os.Parcel _reply = android.os.Parcel.obtain();                source.analysis.android29.aidl.User _result;                try {                    _data.writeInterfaceToken(DESCRIPTOR);                    _data.writeString(username);                    boolean _status = mRemote.transact(Stub.TRANSACTION_getUser, _data, _reply, 0);                    if (!_status && getDefaultImpl() != null) {                        return getDefaultImpl().getUser(username);                    }                    _reply.readException();                    if ((0 != _reply.readInt())) {                        _result = source.analysis.android29.aidl.User.CREATOR.createFromParcel(_reply);                    } else {                        _result = null;                    }                } finally {                    _reply.recycle();                    _data.recycle();                }                return _result;            }            public static source.analysis.android29.aidl.IRemoteService sDefaultImpl;        }        static final int TRANSACTION_getValue = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);        static final int TRANSACTION_getUser = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);        public static boolean setDefaultImpl(source.analysis.android29.aidl.IRemoteService impl) {            if (Stub.Proxy.sDefaultImpl == null && impl != null) {                Stub.Proxy.sDefaultImpl = impl;                return true;            }            return false;        }        public static source.analysis.android29.aidl.IRemoteService getDefaultImpl() {            return Stub.Proxy.sDefaultImpl;        }    }    public int getValue() throws android.os.RemoteException;    public source.analysis.android29.aidl.User getUser(java.lang.String username) throws android.os.RemoteException;}

User.java

// This file is intentionally left blank as placeholder for parcel declaration.

4、实现接口方法

RemoteServiceImpl

public class RemoteServiceImpl extends IRemoteService.Stub {    @Override    public int getValue() throws RemoteException {        return 100;    }    @Override    public User getUser(String username) throws RemoteException {        User user = new User();        user.setAge(18);        user.setGender(0);        user.setNickname("昵称");        return user;    }}

5、创建独立进程服务

RemoteService

public class RemoteService extends Service {    @Nullable    @Override    public IBinder onBind(Intent intent) {        return new RemoteServiceImpl();    }}

在AndroidManifest.xml中注册独立进程服务:

6、绑定独立进程服务

绑定独立进程服务

Intent intent = new Intent(this, RemoteService.class);bindService(intent, this, Context.BIND_AUTO_CREATE);

7、获取独立进程服务代理

public class AidlActivity extends AppCompatActivity implements ServiceConnection {/** * Called when the connection with the service is established */@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {    // Following the example above for an AIDL interface,    // this gets an instance of the IRemoteInterface, which we can use to call on the service    iRemoteService = IRemoteService.Stub.asInterface(service);}/** * Called when the connection with the service disconnects unexpectedly */@Overridepublic void onServiceDisconnected(ComponentName name) {    Log.e(TAG, "Service has unexpectedly disconnected");    iRemoteService = null;}

8、通过独立进程服务代理进行通信

iRemoteService.getValue()
iRemoteService.getUser("android")

aidl跨进程通信调用流程

1、绑定服务

fa83ffb91d744d97a8637b6cde98cb30

aidl绑定服务流程

1.1、Activity中通过bindService()方法绑定远程服务RemoteService,具体实现方法是ContextImpl的bindService()方法。

1.2、远程服务RemoteService绑定成功后会回调onBinder()方法,返回远程服务RemoteService的具体实现RemoteServiceImpl()。

1.3、远程服务绑定成功后,会回调onServiceConnected()方法,通知当前进程也就是AidlActivity,远程服务RemoteService已经连接成功,可以获取远程服务的代理进行进程间的通信了。

2、获取服务代理并通过服务代理进行通信

7a200efe346e44f4bfbdca1e5afd8d5a

aidl获取代理调用服务流程

2.1、获取IRemoteService.Stub获取远程服务的代理,也就是IRemoteService.Stub.Proxy。

2.2、通过代理IRemoteService.Stub.Proxy调用远程服务的方法,代理IRemoteService.Stub.Proxy通过asBinder()方法获取BinderProxy调用transact()方法通知远程服务,而transact()方法使用JNI技术调用了native方法transactNative()方法。

2.3、transactNative()方法最后会调用远程服务IRemoteService.Stub的onTransact()方法,onTransact()方法会通过asBinder()方法获取RemoteServiceImpl,并调用RemoteServiceImpl的实际实现方法。

Android技术堆栈

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值