Android Binder Mechanism (1)

來源:互聯網
上載者:User

    Binder是Android系統中實現處理序間通訊的核心機制,其本質是一種Proxy模式的具體實現,就像COM,CORBA一樣。

 

    Proxy模式的基本思想是用戶端程式通過某種方式得到伺服器端的代理對象,所有對伺服器端的服務要求都發送給該代理對象,該代理對象負責同伺服器端進行通訊。從用戶端的角度看,訪問代理對象就如同訪問其它本機物件一樣;伺服器代理對象則屏蔽了所有的處理序間通訊細節。

 

    本文計劃給出一個具體的例子,然後以這個例子為基礎,深入剖析一下Android系統的綁定機制。

 

    執行個體:新增加一個系統服務ExampleService,該服務可以接受一個整形參數,將其值加上100並返回。用戶端應用程式使用此服務計算1+100的值。

 

    代碼1: 系統服務ExampleService的具體實現

// File: ExampleService.h<br />#ifndef ANDROID_EXAMPLE_SERVICE_H<br />#define ANDROID_EXAMPLE_SERVICE_H<br />#include <utils/threads.h><br />#include <utils/RefBase.h><br />#include <binder/IInterface.h><br />#include <binder/BpBinder.h><br />#include <binder/Parcel.h></p><p>namespace android {<br /> class ExampleService : public BBinder<br /> {<br /> mutable Mutex mLock;<br /> int32_t mNextConnId;<br /> public:<br /> static int instantiate();<br /> ExampleService();<br /> virtual ~ExampleService();<br /> virtual status_t onTransact(uint32_t, const Parcel&, Parcel*, uint32_t);<br />};<br />}; //namespace<br />#endif

 

// File: ExampleService.cpp<br />#include "ExampleService.h"<br />#include <binder/IServiceManager.h><br />#include <binder/IPCThreadState.h></p><p>namespace android {</p><p> static struct sigaction oldact;<br /> static pthread_key_t sigbuskey;</p><p> int ExampleService::instantiate()<br /> {<br /> LOGE("ExampleService instantiate");<br /> // 調用ServiceManager的addService方法進行系統服務註冊,這樣用戶端程式就可以通過ServiceManager獲得此服務的代理對象,從而請求其提供的服務<br /> int r = defaultServiceManager()->addService(String16("byn.example"), new ExampleService());<br /> LOGE("ExampleService r = %d/n", r);<br /> return r;<br /> }</p><p> ExampleService::ExampleService()<br /> {<br /> LOGV("ExampleService created");<br /> mNextConnId = 1;<br /> pthread_key_create(&sigbuskey, NULL);<br /> }</p><p> ExampleService::~ExampleService()<br /> {<br /> pthread_key_delete(sigbuskey);<br /> LOGV("ExampleService destroyed");<br /> }<br /> // 每個系統服務都繼承自BBinder類,都應重寫BBinder的onTransact虛函數。當使用者發送請求到達Service時,系統架構會調用Service的onTransact函數<br /> status_t ExampleService::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)<br /> {<br /> switch(code)<br /> {<br /> case 0: {<br /> pid_t pid = data.readInt32();<br /> int num = data.readInt32();<br /> num = num + 100;<br /> reply->writeInt32(num);<br /> return NO_ERROR;<br /> }<br /> break;<br /> default:<br /> return BBinder::onTransact(code, data, reply, flags);<br /> }<br /> }<br />}; //namespace

 

# File: Android.mk<br />LOCAL_PATH:= $(call my-dir)<br />include $(CLEAR_VARS)<br />LOCAL_SRC_FILES:= /<br />ExampleService.cpp<br />LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)<br />LOCAL_SHARED_LIBRARIES := /<br />libutils libbinder<br />LOCAL_PRELINK_MODULE := false<br />LOCAL_MODULE := libExample</p><p>include $(BUILD_SHARED_LIBRARY)

 

    在/framework/android/src/frameworks/base下面建立一個檔案夾ExampleService,將以上三個檔案複製到該檔案夾中。

 

    代碼2:啟動ExampleService的應用程式

// File: ExampleServer.cpp<br />#include <sys/types.h><br />#include <unistd.h><br />#include <grp.h><br />#include <binder/IPCThreadState.h><br />#include <binder/ProcessState.h><br />#include <binder/IServiceManager.h><br />#include <utils/Log.h><br />#include <private/android_filesystem_config.h><br />#include "../ExampleService/ExampleService.h"</p><p>using namespace android;</p><p>int main(int argc, char** argv)<br />{<br /> sp<ProcessState> proc(ProcessState::self());// 要想使用Binder機制,必須要建立一個ProcessState對象<br /> sp<IServiceManager> sm = defaultServiceManager();<br /> LOGI("ServiceManager: %p", sm.get());<br /> ExampleService::instantiate();<br /> ProcessState::self()->startThreadPool();<br /> IPCThreadState::self()->joinThreadPool();<br /> return 0;<br />}

 

# File: Android.mk<br />LOCAL_PATH:= $(call my-dir)<br />include $(CLEAR_VARS)<br />LOCAL_SRC_FILES:= /<br />ExampleServer.cpp<br />LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)<br />LOCAL_SHARED_LIBRARIES := /<br />libutils libbinder libExample<br />LOCAL_PRELINK_MODULE := false<br />LOCAL_MODULE := ExampleServer</p><p>include $(BUILD_EXECUTABLE)

 

    在/framework/android/src/frameworks/base下面建立一個檔案夾ExampleServer,將以上兩個檔案複製到該檔案夾中。

 

    代碼3:使用ExampleService的用戶端應用程式

// File: Example.h<br />#ifndef ANDROID_BYN_EXAMPLE_H<br />#define ANDROID_BYN_EXAMPLE_H</p><p>namespace android<br />{<br /> class Example {<br /> public:<br /> void add100(int n);<br /> private:<br /> static const void getExampleService();<br /> };<br />}; //namespace<br />#endif // ANDROID_BYN_EXAMPLE_H

 

// File: Example.cpp<br />#include <binder/IServiceManager.h><br />#include <binder/IPCThreadState.h><br />#include "Example.h"</p><p>namespace android<br />{<br /> sp<IBinder> binder;<br /> void Example::add100(int n)<br /> {<br /> getExampleService();<br /> Parcel data, reply;<br /> int answer;</p><p> data.writeInt32(getpid());<br /> data.writeInt32(n);<br /> LOGE("BpExampleService::create remote()->transact()/n");<br /> binder->transact(0, data, &reply);<br /> answer = reply.readInt32();<br /> printf("answner=%d/n", answer);<br /> return;<br /> }</p><p> const void Example::getExampleService()<br /> {<br /> sp<IServiceManager> sm = defaultServiceManager();<br /> binder = sm->getService(String16("byn.example"));<br /> LOGE("Example::getExampleService %p/n",sm.get());<br /> if (binder == 0) {<br /> LOGW("ExampleService not published, waiting...");<br /> return;<br /> }<br /> }<br />}; //namespace</p><p>using namespace android;</p><p>int main(int argc, char** argv)<br />{<br /> Example* p = new Example();<br /> p->add100(1);<br /> return 0;<br />}

 

# File: Example<br />LOCAL_PATH:= $(call my-dir)<br />include $(CLEAR_VARS)<br />LOCAL_SRC_FILES:= /<br />Example.cpp<br />LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)<br />LOCAL_SHARED_LIBRARIES := /<br />libutils libbinder libExample<br />LOCAL_PRELINK_MODULE := false<br />LOCAL_MODULE := Example</p><p>include $(BUILD_EXECUTABLE)

 

    在/framework/android/src/frameworks/base下面建立一個檔案夾Example,將以上三個檔案複製到該檔案夾中。

 

    Build整個Android系統,這裡一共會在系統中產生三個檔案,分別是

    /system/lib/libExample.so

    /system/bin/ExampleServer

    /system/bin/Example

 

    然後啟動我們新添加的ExampleService系統服務,並啟動用戶端程式驗證運行結果。

    $> adb shell

    # cd /system/bin

    # ./ExampleServer &

    # ./Example

    answer=101

 

    在接下來的幾篇文章中,我們會以這個例子為基礎,深入分析一下Android系統中Binder機制的各個部分。

 

 

    參考文獻:

    1. 雲中漫步部落格:http://my.unix-center.net/~Simon_fu/

    2. 如何撰寫自己的第一個核心服務--高煥堂:http://www.android1.net/Topic.aspx?BoardID=21&TopicID=990

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.