概述
1.用法
(1)服务端声明和创建
<!--exported:允许外界访问该服务,AIDL必备条件-->
<service
android:name=".MyService"
android:exported="true"/>
</application>
(2)添加aidl文件, 比如一个+方法
右键包添加aidl. 在生成的文件中写上自己的方法
interface IMyAidlInterface {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
double aDouble, String aString);
int add(int num1, int num2);
}
(3)点击编译按钮, 自动生成
(4)服务端当然是写一个服务, 用来提供这个接口的代理
public class MyService extends Service {
@Override
public IBinder onBind(Intent intent) {
return myS;
}
private IBinder myS = new IMyAidlInterface.Stub() {
@Override
public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
}
@Override
public int add(int num1, int num2) throws RemoteException {
return num1 + num2;
}
};
}
(5)服务端启动这个服务
startService(new Intent(this, MyService.class));
2.客户端
(1)从服务端原封不动拷贝过来
(2)在oncreate中绑定上面生成的服务
Intent intent = new Intent();
intent.setComponent(new ComponentName("lynash.com.aidl_service", "lynash.com.aidl_service.MyService"));
bindService(intent, conn, BIND_AUTO_CREATE);
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);//获取代理
}
@Override
public void onServiceDisconnected(ComponentName name) {
iMyAidlInterface = null;
}
};
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(conn);
}
(3)在业务逻辑中调用代理
int res = iMyAidlInterface.add(1, 2);
2. 调用过程
1.客户端与服务端其实是用过一个binder来进行数据交互.2.分析一下根据IMyAidlInterface.aidl 生成的IMyAidlInterface.java, 它是文件的核心
3.IMyAidlInterface包含一个内部类
public static abstract class Stub extends android.os.Binder implements lynash.com.aidl_service.IMyAidlInterface
4.Stub中包含了一个代理类
private static class Proxy implements lynash.com.aidl_service.IMyAidlInterface
{
private android.os.IBinder mRemote;
5.客户端获得binder的代码
public void onServiceConnected(ComponentName name, IBinder service) {
iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
}
代码定位到Stub类asInterface方法:
return new lynash.com.aidl_service.IMyAidlInterface.Stub.Proxy(obj);
我们将传过来的obj(这个obj 就是服务的具体实现, 他实现了Binder接口). 传给了它的代理类来处理,返回的是代理类的对象.
6.客户端调用方法
int res = iMyAidlInterface.add(1, 2);
服务端代理对add的处理
@Override
public int add(int num1, int num2) 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);
_data.writeInt(num1);
_data.writeInt(num2);
mRemote.transact(Stub.TRANSACTION_add, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
它把数据写进了_data里面,最后调用transact方法,传入_data数据,唯一标识Stub.TRANSACTION_add。
然后, 代理通过
mRemote.transact(Stub.TRANSACTION_add, _data, _reply, 0);
将方法标识和参数, 通过binder的机制, 传给Stub类.调用Stub中的onTransact方法, 这个方法才是真正的计算逻辑.
@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
{
switch (code)
{
...
case TRANSACTION_add:
{
data.enforceInterface(DESCRIPTOR);
int _arg0;
_arg0 = data.readInt();
int _arg1;
_arg1 = data.readInt();
int _result = this.add(_arg0, _arg1);
reply.writeNoException();
reply.writeInt(_result);
return true;
}
}
最后将计算结果返回给客户端, 通过
return super.onTransact(code, data, reply, flags);
super就是Binder.
3. 原理分析
(1)客户端bindservice
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
}
(2)服务返回Binder
public class MyService extends Service {
@Override
public IBinder onBind(Intent intent) {
return myS;
}
private IBinder myS = new IMyAidlInterface.Stub() {
@Override
public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
}
@Override
public int add(int num1, int num2) throws RemoteException {
Log.i("Hensen", "从客户端发来的AIDL请求:num1->" + num1 + "::num2->" + num2);
return num1 + num2;
}
};
}
(3)可见, 服务器返回的Binder是 实现了Binder implements IBinder的 IMyAidlInterface.Stub()对象.
(4)客户端通过这个IBinder, 就是onServiceConnected的参数IBinder service对象, 获取AIDL的代理
iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
(5)通过IMyAidlInterface.Stub.asInterface(service) , 返回来的是一个IMyAidlInterface实例
(6)这个实例是new lynash.com.aidl_service.IMyAidlInterface.Stub.Proxy(obj);
//以上是AIDL的代码obj就是service, Proxy也是实现了IMyAidlInterface接口的, 所以才能利用这个代理来调用add方法
(7)客户端调用,iMyAidlInterface.add
这个是核心调用过程, 代理的add, 设置了data的具体内容. data是android.os.Parcel _data.
然后调用service对象的transact. 这样就将data数据和方法标识(add)传递给了Stub.
Stub调用onTransact进行计算, 然后将运算结果返回给proxy. proxy再将结果返回给客户端.
桥梁代码就是这个:proxy中的add代码
@Override public int add(int num1, int num2) 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);
_data.writeInt(num1);
_data.writeInt(num2);
mRemote.transact(Stub.TRANSACTION_add, _data, _reply, 0);//mRemote就是实现了binder的Stub. 通过binder把数据传递给Stub.进行计算, 并把结果写入到_reply
_reply.readException();
_result = _reply.readInt();//取出结果, 返回给客户端.
}
最后
以上就是生动大门为你收集整理的AIDL原理和调用的全部内容,希望文章能够帮你解决AIDL原理和调用所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复