您的位置:首页 > 大数据 > 人工智能

AIDL 的理解&源码分析

2016-01-26 16:59 465 查看
aidl通讯试所有的对象都得实现Parcelable 接口

onTransact() Binder 驱动执行完毕时需要回调的方法

Proxy 移动端IPC通讯的时候,消息都是通过Binder 进行传递的。

这个代理可以理解为:IPC机制中,Android代码 跟底层对应IPC的Binder驱动 之间进行通讯时的代理

asInterface() 查询本地所有的aidl 接口,判断该Binder对象是否为一个本地的 Binder引用

然后bindService的时候,需要传递一个 ServiceConnection的内部类实现,在ServiceConnection内部类实现中

bindService(intent, conn, BIND_AUTO_CREATE);

ServiceConnection conn=new ServiceConnection() {
//aidl链接失败回调
@Override
public void onServiceDisconnected(ComponentName name) {
}
//aidl连接成功回调
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//在系统内部将执行一下逻辑行为
/*public static com.aidl.lxcay.MyAidlInterface asInterface(android.os.IBinder obj) {
* if ((obj == null)) {
*   return null;
* }
* 查询本地所有的aidl 的描述,判断该Binder对象是否为一个本地的 Binder引用
* android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
* if (((iin != null) && (iin instanceof com.aidl.lxcay.MyAidlInterface))) {
* 返回定义好的代理接口
* return ((com.aidl.lxcay.MyAidlInterface) iin);
* }
* 返回默认代理
* return new com.aidl.lxcay.MyAidlInterface.Stub.Proxy(obj);
* }
*/
//这个localInterface 就是aidl里面规定好的接口引用,即Binder 引用
localInterface = Stub.asInterface(service);
//在客户端可以通过点击事件执行这个引用里对应的函数,如果执行成功,会在相应的Service里面执行相应的 函数;
//下面给出一个demo
}
};
eg:
//客户端
public void click(View v) throws RemoteException{
Log.i(TAG, localInterface.login("24", 24)+"");

Log.i(TAG, localInterface.sayHello(new Person("lxcay", 24))+"");
}
//服务端
public class MyServices extends Service {
@Override
public IBinder onBind(Intent intent) {

return new MyBind();
}
// class MyBind 继承 Stub接口,为什么会重写一下2个回调方法,是因为在aidl文件对应的java代码里面有这句代码
/*
* public static abstract class Stub extends android.os.Binder implements com.aidl.lxcay.MyAidlInterface {}
* 在我自己定义的接口描述文件里面就有
* interface MyAidlInterface {
*      boolean login(String name,int age);
*      String sayHello(in Person p);
* }
*/
class MyBind extends Stub{

@Override
public boolean login(String name, int age) throws RemoteException {

return !name.equals(age);
}

@Override
public String sayHello(Person p) throws RemoteException {
return "lxcay hello world, hello aidl~";
}
}
}


然后在客户端跟服务端交互的时候,我们可以通过看 aidl对应系统生成的java类中的描述,来撸清楚来龙去脉

/*
* This file is auto-generated.  DO NOT MODIFY.
* Original file: D:\\SCode\\SogouGameSDKSample\\src\\com\\intfs\\MyAidlInterface.aidl
*/
package com.aidl.lxcay;

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

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

/**
* Cast an IBinder object into an com.aidl.lxcay.MyAidlInterface interface,
* generating a proxy if needed.
*/
public static com.aidl.lxcay.MyAidlInterface asInterface(android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof com.aidl.lxcay.MyAidlInterface))) {
return ((com.aidl.lxcay.MyAidlInterface) iin);
}
return new com.aidl.lxcay.MyAidlInterface.Stub.Proxy(obj);
}
//这个被重写是因为,咱们的com.aidl.lxcay.MyAidlInterface类extends android.os.IInterface 所以需要提供一个 asBinder 对象
@Override
public android.os.IBinder asBinder() {
return this;
}
//这个是提供给Binder驱动在接受到消息的时候,回调的方法。里面对应的就是aidl接口描述文件里面的固定格式
@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);
java.lang.String _arg0;
_arg0 = data.readString();
int _arg1;
_arg1 = data.readInt();
//---------------->>
boolean _result = this.login(_arg0, _arg1);
reply.writeNoException();
reply.writeInt(((_result) ? (1) : (0)));
return true;
}
case TRANSACTION_sayHello: {
data.enforceInterface(DESCRIPTOR);
com.aidl.lxcay.Person _arg0;
if ((0 != data.readInt())) {
_arg0 = com.aidl.lxcay.Person.CREATOR.createFromParcel(data);
} else {
_arg0 = null;
}
////------------------------>>
java.lang.String _result = this.sayHello(_arg0);
reply.writeNoException();
reply.writeString(_result);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
//这个代理类,是客户端跟服务端之间的一个桥梁,通过阅读以下代码 ①方法 跟②方法,我们可以大致知道他们之间是怎么通讯的。
private static class Proxy implements com.aidl.lxcay.MyAidlInterface {
//mRemote 为 Binder的引用
private android.os.IBinder mRemote;

Proxy(android.os.IBinder remote) {
//在Binder 的驱动中 mRemote 也重载了transact() 函数
mRemote = remote;
}

@Override
public android.os.IBinder asBinder() {
return mRemote;
}

public java.lang.String getInterfaceDescriptor() {
return DESCRIPTOR;
}
//①方法
@Override
public boolean login(java.lang.String name, int age) throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
boolean _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeString(name);
_data.writeInt(age);

//在向Binder通讯的时候,执行以下一句代码,驱动执行完毕之后成功,最后会回调 上面的
//public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags)方法
mRemote.transact(Stub.TRANSACTION_login, _data, _reply, 0);

_reply.readException();
_result = (0 != _reply.readInt());
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
//②方法
@Override
public java.lang.String sayHello(com.aidl.lxcay.Person p) 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);
if ((p != null)) {
_data.writeInt(1);
p.writeToParcel(_data, 0);
} else {
_data.writeInt(0);
}
mRemote.transact(Stub.TRANSACTION_sayHello, _data, _reply, 0);
_reply.readException();
_result = _reply.readString();
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}

static final int TRANSACTION_login = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_sayHello = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
}

public boolean login(java.lang.String name, int age) throws android.os.RemoteException;

public java.lang.String sayHello(com.aidl.lxcay.Person p) throws android.os.RemoteException;
}


ServiceManager 可以得到android系统的各个 ServiceManger对象,而每一个ServiceManger对象,又持有着各自对应的Binder 引用。

所以说,ServiceManager是Binder 驱动的一个引子,在IPC中 是客户端和服务端进行通信的媒介
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android aidl 移动