1. 程式人生 > >android (八)Binder淺談

android (八)Binder淺談

 本文主要內容的:

       Java層Binder結構,Java層Binder呼叫的資訊流,Native層Binder的框架結構,Native層Binder呼叫資訊流向。

     在這裡寫下對binder的理解,說到Binder間程序通訊,Linux那麼多程序間通訊工具為何引入了Binder。大概原因有兩點:

1、為了提高通訊的效率。

2、為了方便開發者,讓程序間通訊和本地呼叫一樣簡單方便。

Binder無處不在,日常開發中無形中一直在用Binder進行通訊,例如Activity的建立,視窗的顯示等等。

Java層Binder:

具體的應用比如說:ActivityThread

中的ApplicationThread就是繼承了IBinder,這裡的IBinderjava層的binder。那麼Java層的binder都做了什麼的事呢,看過java層的binder的原始碼後,發現並沒有想象中的複雜,只是java通向native的介面;Java層的binder是呼叫了c++Binder實現。

      Binder分為兩大部分:Binder應用和Binder驅動。

      Binder應用層分為Java層和native層,外加一個Javanative通訊的介面層;android_util_Binder.cpp作為javanative之間介面層。

舉例說明ActivityThread

中的Binder建立過程,ApplicationThreadActivityThread中的內部類,主要負責與核心進行通訊。

private class ApplicationThread extends ApplicationThreadNative

public abstract class ActivityManagerNative extends Binder implements IActivityManager

        這樣ApplicationThread 就是Binder的子類,ApplicationThread 建立物件的時候會呼叫Binder的構造方法。java層的binder的構造方法中呼叫了一個叫init的本地方法。

    public Binder() {
        init(); 省略部分程式碼
            }    

        android_util_Binder.cpp中的init方法主要是建立了JavaBBinderHolder指標,JavaBBinderHolder主要用來管理JavaBBinder例項,JavaBBinder為BBinder的派生類,BBinder為native層的Binder實現。

static void android_os_Binder_init(JNIEnv* env, jobject clazz)
{
    JavaBBinderHolder* jbh = new JavaBBinderHolder(env, clazz);
    if (jbh == NULL) {
        jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
        return;
    }
    LOGV("Java Binder %p: acquiring first ref on holder %p", clazz, jbh);
    jbh->incStrong(clazz);
    env->SetIntField(clazz, gBinderOffsets.mObject, (int)jbh);
}

java層各個部件之間的互相協作圖


Native層Binder:



  • IBinder、BBinder、BpBinder:IBinder是對android binder的抽象,它同時具有BBinder和BpBinder兩個子類。BBinder負責接收RPC程式碼和資料並在Binder Driver內部生成Binder節點。BpBinder儲存有目標服務的Handler資訊,用於在Binder Driver中Binder節點的查詢。
  • IPCThreadState負責與Binder Driver通訊。
  • IInterrace 、 BnInterface 、 BpInterface : IInterface 類提供型別變換功能,將服務或服務代理類轉換為 IBinder 型別。實際的型別轉換是由 BnInterface 、 BpInterface 兩個類完成, BnInterface 將服務類轉換成 IBinder 型別,而 BpInterface 則將服務代理類轉換成 IBinder 型別。在通過 Binder Driver 傳遞 Binder 物件時,必須進行型別轉換,比如在向系統註冊服務時,需要先將服務類轉換成 IBinder ,再將其傳遞給 ServiceManager 。
  • Processstate 、 IPCThreadstate : Processstate 類用來管理 Binder Driver , IPCThreadstate 類用來支援服務客戶端、 Service Server 與 Binder Driver 間的 Binder IPC 通訊。
  •  Parcel :在服務與服務代理服務進行 Binder IPC 時, Parcel 類負責儲存 Binder IPC 資料。 Parcel 類可以處理的資料有 C 語言的基本資料結構和陣列、 Binder 物件、檔案描述符等。

  服務的框架大致分為三層服務層、RPC層和IPC層;在開發服務時需要實現的有服務層中的服務介面、服務類,以及 RPC 層中的服務代理和服務 stub 。

  • 服務層: Ilnterface、 Bnlnterface 、 Bplnterface 、 BpRefBase  、服務介面、服務類 。
  • RPC 層:服務代理類、服務 stub 類 。
  • IPC 層: BBinder、 BpBinder 、 IPCThreadstate、 Processstate、 Parcel。

本地服務的資訊傳遞,可以用這麼一幅圖來描述,層次比較清晰,方便理解Binder的工作流程。

AudioFlinger音訊服務類圖如下

·