天天看點

Android程序間通信機制——Binder學習

Binder是Android系統中的一種程序間通信機制,有四個元件組成,分别是:Client、Server、Service Manager和Binder驅動程式。其中,Client,Server,Service Manager運作在使用者空間,Binder驅動運作在核心空間。Binder就是這四個元件打起來的一個通信鍊路。

Binder驅動是Binder機制的核心,最終的互動就是通過Binder驅動。Service Manager負責在使用者空間的Binder管理,也就是管理Client和Server。Client和Server就是通常的Client——Server通信模型中的兩端,Client負責提供服務接口給上層應用或者其他程序使用,Server則是這些接口功能的真正的實作者。Android系統中的系統Service(ActivityManagerService、WindowManagerService、PowerManagerService等等)都是這種模型架構。對于應用開發者,也可以開發自己的Client,Server。可以通過獲得Service Manager服務來管理自己的Server。

Android Binder系統的架構如下圖所示。

Android程式間通信機制——Binder學習

如圖所示,Client,Server包括Service Manager都是通過open和ioctl兩個函數與Binder驅動進行通信,然後他們之間的通信就由Binder驅動進行傳遞,這裡的Binder驅動就類似一塊共享記憶體。

Service Manager作為Binder在User空間的管理者,他自己首先注冊到Binder驅動,并告訴Binder驅動他是Binder使用者空間的管理者,下面簡單看下Service Manager如何實作注冊并成為管理者。

Service Manager是在init程序中被啟動,定義在init.rc中(system/core/rootdir):

<span style="font-size:18px;"><span style="font-size:24px;">service servicemanager /system/bin/servicemanager
    class core
    user system
    group system
    critical
    onrestart restart healthd
    onrestart restart zygote
    onrestart restart media
    onrestart restart surfaceflinger
    onrestart restart drm</span></span>
           

其源碼實作位于(Android M):frameworks/native/cmds/servicemanagerservice_manager.c

<span style="font-size:18px;"><span style="font-size:24px;">int main(int argc, char **argv)
{
    struct binder_state *bs;

    bs = binder_open(128*1024);
    if (!bs) {
        ALOGE("failed to open binder driver\n");
        return -1;
    }

    if (binder_become_context_manager(bs)) {
        ALOGE("cannot become context manager (%s)\n", strerror(errno));
        return -1;
    }

    selinux_enabled = is_selinux_enabled();
    sehandle = selinux_android_service_context_handle();
    selinux_status_open(true);

    if (selinux_enabled > 0) {
        if (sehandle == NULL) {
            ALOGE("SELinux: Failed to acquire sehandle. Aborting.\n");
            abort();
        }

        if (getcon(&service_manager_context) != 0) {
            ALOGE("SELinux: Failed to acquire service_manager context. Aborting.\n");
            abort();
        }
    }

    union selinux_callback cb;
    cb.func_audit = audit_callback;
    selinux_set_callback(SELINUX_CB_AUDIT, cb);
    cb.func_log = selinux_log_callback;
    selinux_set_callback(SELINUX_CB_LOG, cb);

    binder_loop(bs, svcmgr_handler);

    return 0;
}</span></span>
           

這裡主要做三件事:

1、bs = binder_open(128*1024);打開Binder裝置。

2、調用binder_become_context_manager(bs),告訴Binder驅動Service Manager是Binder使用者空間管理者。

3、調用binder_loop(bs, svcmgr_handler);進入無限循環中,等待“Client”的請求,這裡“Client”包括上文中的Binder通信雙方Client——Server。

詳細的實作細節參見老羅的博文:http://blog.csdn.net/luoshengyang/article/details/6621566

繼續閱讀