[Go Back] 

[請指教:高老師的免費on-line教學視頻] 

 

1.4   Java层的Binder基类定义

    在Android的Binder.java源代码档案里定义了两个类别,分别为:Binder基类和BinderProxy类别。Binder基类的很重要目的是支持跨进程調用Service,也就是让远程的Client可以跨进程調用某个Service。

 

1.4.1  Binder基类的定义

      这Binder基类定义于Binder.java源代码档案里:

 

// 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();

  }

 

     Binder基类定义了一些函数。其中,主要的函数是:

  • transact()函数 --- 用来实作IBinder的transact()函数接口。
  • execTransact()函数 --- 其角色与transact()函数是相同的,只是这是用来让C/C++本地程序来調用的。
  • onTransact()函数--- 这是一个抽象函数,让应用子类来覆写(Override)的。上述的transact()和execTransact()两者都是調用onTransact()函数来实现反向調用(IoC, Inversion of Control)的。
  • init()函数--- 这是一个本地(Native)函数,让JNI模块来实现这个函数。Binder()构造函数(Constructor)会調用这个init()本地函数。 

兹以UML图形表示之: 

 

  图1-7  Binder框架基类及其本地模块

     当Binder的子类别诞生对象时,会調用到Binder()构造函数。此时,Binder()会調用到init()本地函数。关于这个init()本地函数的工作内涵,后续会有详细说明,于此就先不细说了。 其中,还定义了一个数据项(又称属性):mObject,它是用来指向本地层的对映对象。关于这个mObject属性(Attribute)的用途,后续会有详细说明,于此就先不细说了。[歡迎光臨 高煥堂 網頁:http://www.cnblogs.com/myEIT/ ]

 

1.4.2  BinderProxy类别的定义

     这个BinderProxy类别也是定义在Binder.java源代码档案里,此程序文件如下:

 

// Binder.java(续)

// ………

final class BinderProxy implements IBinder {

    private int mObject;

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

    BinderProxy() {

         // .........

    }

    public native boolean transact(int code, Parcel data, Parcel reply,

                          int flags) throws RemoteException;

    private int mObject;

}

     当我们看到类别名称是 XXXProxy时,就自然会联想到它是摆在Client进程里,担任Service端的分身(Proxy)。关于这个分身的用法,后续会有详细说明,于此就先不细说了。请先看看它的架构,如下图: 

 

  图1-8  BinderProxy类别及其本地模块

     由于跨进程沟通时,并不是从Java层直接沟通的,而是透过底层的Binder Driver驱动来沟通的,所以Client端的Java类别(如Activity)必须透过BinderProxy分身的IBinder接口,转而調用JNI本地模块来衔接到底层Binder Driver驱动服务,进而調用到正在另一个进程里执行的Service。例如上图里,当Client透过IBinder接口而調用到BinderProxy的transact()函数,就調用到其 JNI本地模块的transact()函数,就能进而衔接到底层Binder Driver驱动服务了。 

[Go Back]