Foreword
I [003] AIDL AIDL what is described, but it seems to have friends do not understand ask me, I'll write a final version of the article, so you ten minutes to completely understand AIDL, the following code are all handwritten.
aims
Server process to sign up for a service Binder SM, the Binder service provides two interfaces: add and minus
proxy class BinderProxy Client service through the process of obtaining Binder SM, and calls the two interfaces add, minus
1 no AIDL world
1.1 Server Process
class CommandBinder extends Binder {
@Override
protected boolean onTransact(int code, @NonNull Parcel data, @Nullable Parcel reply, int flags) throws RemoteException {
if (code == 1) {
int a = data.readInt();
int b = data.readInt();
reply.writeInt(a + b);
return true;
} else if (code == 2) {
int a = data.readInt();
int b = data.readInt();
reply.writeInt(a + b);
return true;
}
return super.onTransact(code, data, reply, flags);
}
}
void main() {
//注册binder服务
ServiceManager.addService("command", new CommandBinder());
}
1.2 Client Process
int add(int a, int b) {
int code = 1;
BinderProxy mClient = ServiceManager.getService("command");
Parcel data = Parcel.obtain();
data.writeInt(a);
data.writeInt(b);
Parcel reply = Parcel.obtain();
mClient.transact(code, data, reply, 0);//flag设置成0,调用这个方法会跨进程调用Binder服务类中onTransact方法
int result = reply.readInt();
return result;
}
int minus(int a, int b) {
int code = 2;
BinderProxy mClient = ServiceManager.getService("command");
Parcel data = Parcel.obtain();
data.writeInt(a);
data.writeInt(b);
Parcel reply = Parcel.obtain();
mClient.transact(code, data, reply, 0);//flag设置成0,调用这个方法会跨进程调用Binder服务类中onTransact方法
int result = reply.readInt();
return result;
}
There are 2 AIDL world
AIDL file
//aidl
interface ICommand {
int add(int a, int b);
int minus(int a, int b);
}
2.1 Server Process
Compared to 1.1 in the code, we find that we are not the direct successor Binder, but inherited aidl file is automatically generated ICommandBinder, we only need to focus and achieve minus write add interface does not require onTransact in Binder class to write a bunch of code if else and Parcel.read write.
class ADILCommandBinder extends ICommandBinder {
@Override
public int add(int a, int b) {
return a + b;
}
@Override
public int minus(int a, int b) {
return a - b;
}
}
void main() {
//注册binder服务
ServiceManager.addService("command", new ADILCommandBinder());
}
2.2 Client Process
Compared to 1.2 in the code, we find that we do not need to write Parcel.read write and BinderProxy.transact, but to construct a CommandBinderProxy object with the BinderProxy object, and then directly call CommandBinderProxy add and minus
int add(int a, int b) {
BinderProxy mClient = ServiceManager.getService("command");
return new CommandBinderProxy(mClient).add(a, b);
}
int minus(int a, int b) {
BinderProxy mClient = ServiceManager.getService("command");
return new CommandBinderProxy(mClient).minus(a, b);
}
3 ADIL what code is automatically generated
Generating three parts: ICommand, ICommandBinder, CommandBinderProxy
3.1 ICommand
Looks almost aidl file
interface ICommand {
int add(int a, int b);
int minus(int a, int b);
}
3.2 ICommandBinder
Inherited from Binder, and implement ICommand, and then calls to add and minus method has not been implemented in the method onTransact
abstract public class ICommandBinder extends Binder implements ICommand {
int add = 1;
int minus = 2;
@Override
protected boolean onTransact(int code, @NonNull Parcel data, @Nullable Parcel reply, int flags) throws RemoteException {
if (code == 1) {
int a = data.readInt();
int b = data.readInt();
reply.writeInt(add(a, b));
return true;
} else if (code == 2) {
int a = data.readInt();
int b = data.readInt();
reply.writeInt(minus(a, b));
return true;
}
return super.onTransact(code, data, reply, flags);
}
abstract public int add(int a, int b);
abstract public int minus(int a, int b);
}
3.3 CommandBinderProxy
BinderProxy of encapsulation, add the call is converted to CommandBinderProxy Parcel.write, read and BinderProxy.transact codes.
public class CommandBinderProxy implements ICommand {
private BinderProxy remote;
int add = 1;
int minus = 2;
public CommandBinderProxy(BinderProxy remote) {
this.remote = remote;
}
@Override
public int add(int a, int b) {
Parcel data = Parcel.obtain();
data.writeInt(a);
data.writeInt(b);
Parcel reply = Parcel.obtain();
remote.transact(add, data, reply, 0);
int result = reply.readInt();
return result;
}
@Override
public int minus(int a, int b) {
int code = 2;
Parcel data = Parcel.obtain();
data.writeInt(a);
data.writeInt(b);
Parcel reply = Parcel.obtain();
remote.transact(code, data, reply, 0);
int result = reply.readInt();
return result;
}
}
to sum up
After reading should understand the role of the main AIDL
a. Lazy, a lot less code you write, especially when hundreds of methods, AIDL come in great handy.
b. Allow the server to focus more on implementation of the interface, while reducing the possibility of mistakes
c. norms client-side and server-side interface definition, contribute iterative code
Of course, this is my own to write pseudo code, AIDL true generated code is more complex, but these pseudo-code is AIDL core point.
Think
oneway of this syntax AIDL have any effect on the generated code, or write about your own oneway method of generating pseudo-code AIDL
Reply to " basketball belly " into the technical group chat
Reply to " 1024 " get 1000G learning materials