AIDL 生成的IInterface接口代码解析
前言
在android 中跨进程通信,我们需要用AIDL,而在Android Studio中,我们编写通信的AIDL时候,只需要简单的定义相关方法,Andrdoid Studio就会给开发者生存对应的Java Interface接口,不过作为开发者我们需要了解这些自动生成的代码的作用。
如下定义个 IPet的AIDL 接口,自动生成了 IDEA自动生成了 IPet.java类。
在IPet java类中,主要有三个类 Default、Stub、Proxy类。其中Default类没什么作用可以忽略,重点是Stub和Stub的子类Proxy。
Stub 类继承了 Binder类且实现了 IPet的接口。 Stub类中有两个重点方法:
- asInterface(android.os.IBinder obj) 方法,用于将Binder对象转发为具体的接口对象,如果在同一进程则强制obj为binder,否则返回一个代理对象。
- onTransact 方法,服务端调用,读取Parcle中客户端传入的参数,执行客户端的指令并且 向Parcle写入执行客户端要求的方法后得到的返回值。 Proxy类是被客户端使用。
Proxy 类中实现了IPet接口中的方法,在方法中向Parcle写入客户端要传入的数据,调用Binder反回结果后,再从Parcle中读取结果(服务端向Parcle写入的方法执行结果),然后将该结果作为该方法的返回值。
显然Proxy类中实现的具体方法对Parcle的操作与onTransact中的操作是一一对应的。
代码解析
/*
* This file is auto-generated. DO NOT MODIFY.
*/
package com.chl.pservice;
public interface IPet extends android.os.IInterface {
/**
* Default implementation for IPet.
*/
public static class Default implements com.chl.pservice.IPet {
@Override
public java.util.List< com.yrj.pservice.Pet > getPets(com.yrj.pservice.Person owner) throws android.os.RemoteException {
return null;
}
@Override
public java.util.List< com.yrj.pservice.Pet > getAllPets() 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 com.chl.pservice.IPet {
//唯一标识,一般为完整路径,一般通过该类来判断是否是同一个接口
private static final java.lang.String DESCRIPTOR = "com.chl.pservice.IPet";
// binder 中的方法,将具体的接口、描述符和Binder进行绑定
public Stub() {
/**
* Convenience method for associating a specific interface with the Binder.
* After calling, queryLocalInterface() will be implemented for you
* to return the given owner IInterface when the corresponding
* descriptor is requested.
*/
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an com.chl.pservice.IPet interface,
* generating a proxy if needed.
*/
//将Binder对象转化为具体的接口,判断如果不在一个进程,则返回一个代理对象
public static com.chl.pservice.IPet asInterface(android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
// 通过描述符查询本地接口,返回本地的对象
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
// 判断本地对象是否存在,如果存在说明是同一个进程,返回该对象
if (((iin != null) && (iin instanceof com.chl.pservice.IPet))) {
return ((com.chl.pservice.IPet) iin);
}
// 本地对象不存在,说明是快进程,生成一个代理对象
return new com.chl.pservice.IPet.Stub.Proxy(obj);
}
// IInterface接口方法具体实现,返回一个binder
@Override
public android.os.IBinder asBinder() {
return this;
}
// 操作标识符,在onTransact方法中根据这些code来进行相应的操作
static final int TRANSACTION_getPets = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_getAllPets = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
// 事务处理类,写入标识符以及执行接口定义的方法
@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;
// 根据通用Binder的一套协议,code的值判断当前读取的是什么作用的值
switch (code) {
// 向 parcel写入 标识符,表示是哪个进程写入的回复
case INTERFACE_TRANSACTION: {
reply.writeString(descriptor);
return true;
}
// 执行接口定义的方法
case TRANSACTION_getPets: {
data.enforceInterface(descriptor);
com.chl.pservice.Person _arg0;
// 从 data中读取客户端进程传入的值
if ((0 != data.readInt())) {
_arg0 = com.chl.pservice.Person.CREATOR.createFromParcel(data);
} else {
_arg0 = null;
}
// 执行方法,返回接口,并将结果写到 replay中
java.util.List< com.chl.pservice.Pet > _result = this.getPets(_arg0);
reply.writeNoException();//写入无异常
reply.writeTypedList(_result);//
return true;
}
// 执行接口定义的方法
case TRANSACTION_getAllPets: {
data.enforceInterface(descriptor);
java.util.List< com.yrj.pservice.Pet > _result = this.getAllPets();
reply.writeNoException();
reply.writeTypedList(_result);
return true;
}
default: {
return super.onTransact(code, data, reply, flags);
}
}
}
// 跨进程通信,生成的代理类,返回给客户端
private static class Proxy implements com.chl.pservice.IPet {
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;
}
// 客户端调用该代理类的方法,该方法处理客户端写入Parcel的数据
//
@Override
public java.util.List< com.chl.pservice.Pet > getPets(com.chl.pservice.Person owner) throws android.os.RemoteException {
// 该data 即是在 Stub.onTransact参数中的data类,_data在客户端被写入数据,在服务端的onTract方法被读取然后进行处理
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
java.util.List< com.chl.pservice.Pet > _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
if ((owner != null)) {
// 写入了 1 表示参数不为空
_data.writeInt(1);
//写入客户端传入的参数数据
owner.writeToParcel(_data, 0);
} else {
//写入 0表示参数为空
_data.writeInt(0);
}
// mRemote.trasact方法中实现了跨进程通信,服务端调用了onTract()方法,
boolean _status = mRemote.transact(Stub.TRANSACTION_getPets, _data, _reply, 0);
if (!_status && getDefaultImpl() != null) {
return getDefaultImpl().getPets(owner);
}
_reply.readException();
_result = _reply.createTypedArrayList(com.chl.pservice.Pet.CREATOR);
} finally {
//将该Parcle对象放回回收池,主要是减少对象的创建,能够重复利用
_reply.recycle();
_data.recycle();
}
return _result;
}
@Override
public java.util.List< com.yrj.pservice.Pet > getAllPets() throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
java.util.List< com.yrj.pservice.Pet > _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
boolean _status = mRemote.transact(Stub.TRANSACTION_getAllPets, _data, _reply, 0);
if (!_status && getDefaultImpl() != null) {
return getDefaultImpl().getAllPets();
}
_reply.readException();
_result = _reply.createTypedArrayList(com.yrj.pservice.Pet.CREATOR);
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
public static com.chl.pservice.IPet sDefaultImpl;
}
public static boolean setDefaultImpl(com.chl.pservice.IPet impl) {
if (Stub.Proxy.sDefaultImpl == null && impl != null) {
Stub.Proxy.sDefaultImpl = impl;
return true;
}
return false;
}
public static com.chl.pservice.IPet getDefaultImpl() {
return Stub.Proxy.sDefaultImpl;
}
}
//将复杂对象作为AIDL接口的形参时,记得加上in
public java.util.List< com.chl.pservice.Pet > getPets(com.chl.pservice.Person owner) throws android.os.RemoteException;
public java.util.List< com.chl.pservice.Pet > getPetsByName(java.lang.String name) throws android.os.RemoteException;
}
以上是AIDL生成的接口代码解析,通过解析,读者能大概了解到 AIDL通信中的部分过程,不过这些显然只是一些浅显的了解。如果想要了解Binder通信的底层原理和过程,可以点击参考文献中的文章去看下。