android主板接口定义,范例解析:学习Android的IPC主板模式

一、认识Android的IPC主板模式

系统架构设计最关键的任务就是组合(或称整合),而且最好是能与众不同、深具创新性组合。Android就擅用了主板模式,以通用性接口实践跨进程的IPC通信机制。由于Android是开源开放的系统,其源代码可成为大家观摩的范本。首先,其主板模式提供了IBinder通用性接口。如下图:

d48542885a0e4d39ede776f53d724824.png

Android定义一个Binder父类来实现的IBinder接口。如下图:

bdb28a46aec45c0ee7631b48e6bc2b87.png

然后,以Java来撰写这个实现类,其Java代码如下:

// Android的源代码

// Binder.java

// -------------------------------------------------------------

public class Binder implements IBinder {

// ..........

private int mObject;

public Binder() {

init();

//其它代码

}

public final boolean transact(int code, Parcel data, Parcel reply,  int flags)

throws RemoteException {

//其它代码

boolean r = onTransact(code, data, reply, flags);

return r;

}

private boolean execTransact(int code, int dataObj, int replyObj, int flags) {

Parcel data = Parcel.obtain(dataObj);

Parcel reply = Parcel.obtain(replyObj);

boolean res;

res = onTransact(code, data, reply, flags);

//其它代码

return res;

}

protected boolean onTransact(int code, Parcel data, Parcel reply,  int flags)

throws RemoteException {

}

private native final void init();

}

// End

这个Binder抽象父类的主要函数:

transact()函数--用来实作IBinder的transact()函数接口。

execTransact()函数--其角色与transact()函数是相同的,只是这是用来让C/C++本地程序来调用的。

onTransact()函数-- 这是一个抽象函数,让应用子类来覆写(Override)的。上述的transact()和execTransact()两者都是调用onTransact()函数来实现反向调用(IoC, Inversion of Control)的。

init()函数-- 这是一个本地(Native)函数,让JNI模块来实现这个函数。Binder()构造函数(Constructor)会调用这个init()本地函数。

这Binder.java是抽象类,它含有一个抽象)函数:onTransact()。于是,这个软件主板提供了两个接口:CI和接口。如下图:

09e48d2352e1d85268d7d6513cd9541c.png

这是标准型的主板模式。此图里的Binder抽象父类和两个接口,整合起来成为一个典型的软件主板。如下图:

002c66c04c90f11bda69a55abe54f436.png

这个Binder软件主板是用来整合两个进程里的软件模块(如类),所以我们称之为:。如下图:

2a6e30da387e535197802cb7212e5a49.png

基于这个主板,我们就能开始进行组合了。此时,可设计一个子类,并且装配到主板的接口上。如下图:

09060203-befe1690e69e434098d868286a51b8ed.x-png

这个IBinder接口是Binder基类提供给Client的接口,简称为“CI”。于是,Client端调用IBinder接口的transact()函数,进而调用到Binder抽象类的onTransact()函数。如果Client类与Binder类是执行于同一个进程里,Client端调用IBinder接口的transact()函数,进而调用到Binder抽象类的onTransact()函数。反之,如果Client类与Binder类分别执行于不同的两个进程里,Client端则调用Binder类的exeTransact()函数,透过IPC机制而调用到远方的onTransact()函数。例如,下图里的Activity与Binder之间是跨进程的远距通信(IPC)。如下图:

09060223-49ecc6f651104accb1048e6de2f32a7a.x-png

Android的IPC机制是透过底层Binder驱动来实现的,所以会从底层的C/C++函数来调用exeTransact()函数,再转而调用接口的onTransact()函数。如下图:

09060237-5769db33b16b4c159d9a8f6a008e31af.x-png

Android跨进程通信流程,都由底层Binder驱动模块所掌控。于是,Java层的Activity就能透过底层来调用Binder父类的exeTransact()函数。如下图所示:

09060257-0d55fe47fa8b42c386161571695f991c.x-png

二、主板模式与Proxy-Stub模式的组合应用

在上图里的Activity里可能有多个函数,例如f1()和f2()等。于是,在Activity里,必须从f1()函数转而调用IBinder.transact()函数。如果我们在上述架构里面,加上一个Stub类别(如下图的BinderStub类别),它实现了Binder.onTransact()函数,如下图所示:

09060318-14189911697e44929f74b4c499fd06df.x-png

通常,在框架设计里,myProxy和myStub会是成对的,这称为Proxy-Stub模式。如下图所示:

09060337-8d2198187dc24970b74cdabeeece9e0f.x-png

采用Proxy-Stub设计模式将IBinder接口包装起来,让App与IBinder接口不再产生高度相依性。其将IBinder接口包装起来,转换出更好用的新接口,如下图里的IA接口:

09060356-910e7bd05cae46ffaff1e2e617f1cfc9.x-png

Stub类将onTransact()函数隐藏起来,提供一个更具有美感、更亲切的新接口给subBinder类使用。隐藏了onTransact()函数之后,subBinder类的开发者就不必费心去了解onTransact()函数了。于是,Proxy与Stub两个类遥遥相对,并且将IPC细节知识(例如transact()和onTransact()函数之参数等)包夹起来。由于IBinder接口只提供单一函数(即transact()函数)来进行远距通信,呼叫起来比较不方便。所以Android提供aidl.exe工具来协助产出Proxy和Stub类别,以化解这个困难。只要你善于使用开发环境的工具(如Android的aidl.exe软件工具)自动产生Proxy和Stub类别的程序代码;那就很方便了。◆

~ End ~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值