一、认识Android的IPC主板模式


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

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

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


// Android源代码

// Binder.java

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

publicclassBinderimplementsIBinder{

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

privateintmObject;

publicBinder(){

init();

//其它代码

}

publicfinalbooleantransact(intcode,Parceldata,Parcelreply,intflags)

throwsRemoteException{

//其它代码

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

returnr;

}

privatebooleanexecTransact(intcode,intdataObj,intreplyObj,intflags){

Parceldata=Parcel.obtain(dataObj);

Parcelreply=Parcel.obtain(replyObj);

booleanres;

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

//其它代码

returnres;

}

protectedbooleanonTransact(intcode,Parceldata,Parcelreply,intflags)

throwsRemoteException{

}

privatenativefinalvoidinit();

}

// End

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

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

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

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

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


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

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

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

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

这个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)。如下图:


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

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


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

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

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

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

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


~ End ~









更多相关文章

  1. Android(安卓)Button控件的使用
  2. Android(安卓)onTouchEvent, onClick及onLongClick的调用机制
  3. Android学习之期末复习重点整理
  4. Android(安卓)应用进程启动流程
  5. 刚进入Android终端即可使用busybox的命令
  6. 当我们按下电源键,Android(安卓)究竟做了些什么?
  7. Android应用程序资源管理器(Asset Manager)的创建过程分析
  8. android打开前置摄像头和后置摄像头
  9. 箭头函数的基础使用

随机推荐

  1. Android(安卓)微信登陆
  2. android小记之Animation4种动画效果(贴上
  3. Android(安卓)App 实现分享功能及将应用
  4. 使用BroadcasterRecevier拦截系统短信息_
  5. android 玩转ContentProvider之一--实现Con
  6. Android友盟分享的调不起分享面板,友盟分
  7. Android(安卓)精通 Android(安卓)Data Bi
  8. Android(安卓)NDK开发基础
  9. Android(安卓)- Android(安卓)7.0 拍照,相
  10. 微信小程序多列列表 类似Android的GridVi