摘要:本文将带你了解Android应用开发之AIDL的设计原理,希望本文对大家学Android有所帮助
本文将带你了解Android应用开发之AIDL的设计原理,希望本文对大家学Android有所帮助
1. 首先从抽象层次上来讲。AIDL实际上是在玩远程代理。远程代理对象,完成进程间通信:
2. 下面这个图展示了BinderProxy,Binder 和IBinder的关系。值得注意的是,其中Binder的transaction方法是没有用处的, 本地的调用没有必要执行transaction。另外,由于本地桩要接收消息,因此Binder有个方法会被调用,也就是execTransact, 这个方法是用native的onTransact调用过来的。因此,onTransact可以被认为是接受消息的事件。
3.
有了以上的理论基础,抛开AIDL语法,自己写AIDL通信。其实也很简单。 看看上面的桩,它继承于Binder,同时又实现了接口IInterface, 这是一个适配者模式。谈到适配者模式,一种方式就是通过继承进行适配。还有一种方式是通过组合, 现在就把这种适配者模式改为组合吧!这里既有代理模式,又有适配者模式,主要看所说的参与者对象是什么。
他们俩最大的区别就是:
l 代理模式俩对象都是相同的接口。
l 而适配者模式不是。
Java代码 public class CommonBinder extends Binder { private OnTransactListener mOnTransactListener; public void setOnTransactListener(OnTransactListener lsr) { mOnTransactListener = lsr; } @Override protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { if (mOnTransactListener != null) { return mOnTransactListener.onTransact(code, data, reply, flags); } return super.onTransact(code, data, reply, flags); } } public class CommonBinder extends Binder {
private OnTransactListener mOnTransactListener;
public void setOnTransactListener(OnTransactListener lsr) {
mOnTransactListener = lsr;
}
@Override
protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
if (mOnTransactListener != null) {
return mOnTransactListener.onTransact(code, data, reply, flags);
}
return super.onTransact(code, data, reply, flags);
}
}
其中的listener
Java代码 public interface OnTransactListener { public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException; } public interface OnTransactListener {
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException;
}
对桩进行修改,使其使用组合的方式来适配
Java代码 public abstract class Stub implements IMyService, OnTransactListener { private static final String DESCRIPTOR = "com.a51droidgame.testmemoryleak.IMyService"; private CommonBinder mCommonBinder; /** * Construct the stub at attach it to the interface. */ public Stub(CommonBinder commonBinder) { mCommonBinder = commonBinder; commonBinder.setOnTransactListener(this); mCommonBinder.attachInterface(this, DESCRIPTOR); } /** * Cast an IBinder object into an com.a51droidgame.testmemoryleak.IMyService interface, * generating a proxy if needed. */ public static IMyService asInterface(android.os.IBinder obj) { if ((obj == null)) { return null; } android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); if (((iin != null) && (iin instanceof IMyService))) { return ((IMyService) iin); } return new Proxy(obj); } @Override public android.os.IBinder asBinder() { return mCommonBinder; } @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_sayHello: { data.enforceInterface(DESCRIPTOR); String _result = this.sayHello(); reply.writeNoException(); reply.writeString(_result); return true; } } return false; } public abstract class Stub implements IMyService, OnTransactListener {
private static final String DESCRIPTOR = "com.a51droidgame.testmemoryleak.IMyService";
private CommonBinder mCommonBinder;
/**
* Construct the stub at attach it to the interface.
*/
public Stub(CommonBinder commonBinder) {
mCommonBinder = commonBinder;
commonBinder.setOnTransactListener(this);
mCommonBinder.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an com.a51droidgame.testmemoryleak.IMyService interface,
* generating a proxy if needed.
*/
public static IMyService asInterface(android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof IMyService))) {
return ((IMyService) iin);
}
return new Proxy(obj);
}
@Override
public android.os.IBinder asBinder() {
return mCommonBinder;
}
@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_sayHello: {
data.enforceInterface(DESCRIPTOR);
String _result = this.sayHello();
reply.writeNoException();
reply.writeString(_result);
return true;
}
}
return false;
}
下面看看service的代码
Java代码 public class TestService extends Service { private static final String TAG = "MainActivity"; private static class MyService extends Stub { public MyService() { super(new CommonBinder()); } @Override public String sayHello() throws RemoteException { Log.e(TAG, "sayHello"); return "hello"; } } @Nullable @Override public IBinder onBind(Intent intent) { Log.e(TAG, "onBind " + intent, new Exception()); return new MyService().asBinder(); } @Override public boolean onUnbind(Intent intent) { return super.onUnbind(intent); } } public class TestService extends Service {
private static final String TAG = "MainActivity";
private static class MyService extends Stub {
public MyService() {
super(new CommonBinder());
}
@Override
public String sayHello() throws RemoteException {
Log.e(TAG, "sayHello");
return "hello";
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.e(TAG, "onBind " + intent, new Exception());
return new MyService().asBinder();
}
@Override
public boolean onUnbind(Intent intent) {
return super.onUnbind(intent);
}
}
本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之Android频道!
您输入的评论内容中包含违禁敏感词
我知道了
请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号