上文《Android系統的Binder機制之一——Service Manager》咱們學習了Service Manager在Android Binder中的做用——服務(Service)註冊,服務(Service)查詢的功能。本文咱們一塊兒學習服務(Service)在客戶端中的代理機制。重點介紹其核心對象BpBinder。
android
以下是客戶端請求service服務的場景:服務器
一、首先客戶端向Service manager查找相應的Service。上文《Android系統的Binder機制之一——Service Manager》有比較詳細的介紹。注意客戶端和Service可能在兩個不一樣的進程中。
二、Android系統將會爲客戶端進程中建立一個Service代理。下文將詳細介紹該建立過程。
三、客戶端視角只有Service代理,他全部對Service的請求都發往Service代理,而後有Service代理把用戶請求轉發給Service自己。Service處理完成以後,把結果返回給Service代理,Service代理負責把處理結果返回給客戶端。注意客戶端對Service代理的調用都是同步調用(調用掛住,直到調用返回爲止),這樣客戶端視角來看調用遠端Service的服務和調用本地的函數沒有任何區別。這也是Binder機制的一個特色。框架
在Android系統中任進程何,要想使用Binder機制,必需要建立一個ProcessState對象和IPCThreadState對象。固然若是Android進程不使用Binder機制,那麼這兩個對象是不用建立的。這種狀況不多見,由於Binder機制是整個Android框架的基礎,能夠說影響到Android方方面面。因此說了解這兩個對象的做用很是重要。函數
臺灣的高煥堂先生一片文章《認識ProcessState類型和對象》,能夠在個人博文《(轉)高煥堂——Android框架底層結構知多少?》中找到。能夠先經過這篇文章對ProcessState進行一個大概瞭解。學習
ProcessState是一個singleton類型,一個進程只能建立一個他的對象。他的做用是維護當前進程中全部Service代理(BpBinder對象)。一個客戶端進程可能須要多個Service的服務,這樣可能會建立多個Service代理(BpBinder對象),客戶端進程中的ProcessState對象將會負責維護這些Service代理。ui
咱們研究一下建立一個Service代理的代碼:this
1: sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
2: {
3: sp<IBinder> result;
4:
5: AutoMutex _l(mLock);
6:
7: handle_entry* e = lookupHandleLocked(handle);
8:
9: if (e != NULL) {
10: // We need to create a new BpBinder if there isn't currently one, OR we
11: // are unable to acquire a weak reference on this current one. See comment
12: // in getWeakProxyForHandle() for more info about this.
13: IBinder* b = e->binder;
14: if (b == NULL || !e->refs->attemptIncWeak(this)) {
15: b = new BpBinder(handle);
16: e->binder = b;
17: if (b) e->refs = b->getWeakRefs();
18: result = b;
19: } else {
20: // This little bit of nastyness is to allow us to add a primary
21: // reference to the remote proxy when this team doesn't have one
22: // but another team is sending the handle to us.
23: result.force_set(b);
24: e->refs->decWeak(this);
25: }
26: }
27:
28: return result;
29: }
當前進程首先調用lookupHandleLocked函數去查看當前進程維護的Service代理對象的列表,該待建立Service代理對象是否已經在當前進程中建立,若是已經建立過了,則直接返回其引用就能夠了。不然將會在Service代理對象的列表增長相應的位置(注意系統爲了減小分配開銷,可能會多分配一些空間,策略是「以空間換時間」),保存將要建立的代理對象。具體代碼請參考lookupHandleLocked的源碼。spa
後面代碼就好理解了,若是Service代理對象已經建立過了,直接增長引用計數就好了。若沒有建立過,則須要建立一個新的Service代理對象。.net
Android進程中能夠建立一個ProcessState對象,該對象建立過程當中會打開/dev/binder設備,並保存其句柄。並初始化該設備。代碼以下:線程
1: ProcessState::ProcessState()
2: : mDriverFD(open_driver())
3: , mVMStart(MAP_FAILED)
4: , mManagesContexts(false)
5: , mBinderContextCheckFunc(NULL)
6: , mBinderContextUserData(NULL)
7: , mThreadPoolStarted(false)
8: , mThreadPoolSeq(1)
9: {
10: if (mDriverFD >= 0) {
11: // XXX Ideally, there should be a specific define for whether we
12: // have mmap (or whether we could possibly have the kernel module
13: // availabla).
14: #if !defined(HAVE_WIN32_IPC)
15: // mmap the binder, providing a chunk of virtual address space to receive transactions.
16: mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
17: if (mVMStart == MAP_FAILED) {
18: // *sigh*
19: LOGE("Using /dev/binder failed: unable to mmap transaction memory.\n");
20: close(mDriverFD);
21: mDriverFD = -1;
22: }
23: #else
24: mDriverFD = -1;
25: #endif
26: }
27: if (mDriverFD < 0) {
28: // Need to run without the driver, starting our own thread pool.
29: }
30: }
1: friend class IPCThreadState;
IPCThreadState也是一個singleton的類型,一個進程中也只能有一個這樣的對象。咱們查看一下它的talkWithDriver函數:
1: ...........
2: if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
3: err = NO_ERROR;
4: else
5: err = -errno;
6: ...........
一、維護當前進程中全部對/dev/binder的讀寫。換句話說當前進程經過binder機制進行跨進程調用都是經過IPCThreadState對象來完成的。
二、 IPCThreadState也能夠理解成/dev/binder設備的封裝,用戶能夠不直接經過ioctl來操做binder設備,都經過IPCThreadState對象來代理便可。
1: BpBinder::BpBinder(int32_t handle)
2: : mHandle(handle)
3: , mAlive(1)
4: , mObitsSent(0)
5: , mObituaries(NULL)
6: {
7: LOGV("Creating BpBinder %p handle %d\n", this, mHandle);
8:
9: extendObjectLifetime(OBJECT_LIFETIME_WEAK);
10: IPCThreadState::self()->incWeakHandle(handle);
11: }
客戶進程對Service的請求都經過調用BpBinder的transact方法來完成:
1: status_t BpBinder::transact(
2: uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
3: {
4: // Once a binder has died, it will never come back to life.
5: if (mAlive) {
6: status_t status = IPCThreadState::self()->transact(
7: mHandle, code, data, reply, flags);
8: if (status == DEAD_OBJECT) mAlive = 0;
9: return status;
10: }
11:
12: return DEAD_OBJECT;
13: }
上面咱們講解了Binder機制比較底層的機制,這些機制直接用仍是比較麻煩的,好比使用binder設備的ioctl,須要記住不少ioctl的代碼。
Android爲了是Binder機制容易使用,對Binder機制進行了抽象,定義了IBinder接口,該接口在C/C++和Java層都有定義。IBinder定義了一套使用Binder機制使用和實現客戶程序和服務器的通信協議。能夠理解以下定義:
一、向Android註冊的Service也必須是IBinder(繼承擴展IBinder接口)對象。後續文章中咱們討論Service的時候咱們會介紹到這方面的內容。
二、客戶端獲得Service代理對象也必須定義成IBinder(繼承擴展IBinder接口)對象。這也是爲何BpBinder就是繼承自IBinder。三、客戶端發送請求給客戶端,調用接口的Service代理對象IBinder接口的transact方法。
四、Android系統Binder機制將負責把用戶的請求,調用Service對象IBinder接口的onTransact方法。具體實現咱們將在之後介紹Service的時候討論。
咱們知道Service Manager是Android Binder機制的大管家。全部須要經過Binder通信的進程都須要先得到Service Manager的代理對象才能進行Binder通信。Service Manager即在C/C++層面提供服務代理,又在Java層面提供服務代理,本文先介紹一下C/C++層面的服務代理,Java層面的服務代理將在後續文章中介紹。
進程在C/C++層面上面,Android在Android命名空間中定義了一個全局的函數defaultServiceManager(定義在framework/base/libs/binder),經過這個函數可使進程在C/C++層面得到Service Manager的代理。咱們先看一下該函數的定義:
1: sp<IServiceManager> defaultServiceManager()
2: {
3: if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
4:
5: {
6: AutoMutex _l(gDefaultServiceManagerLock);
7: if (gDefaultServiceManager == NULL) {
8: gDefaultServiceManager = interface_cast<IServiceManager>(
9: ProcessState::self()->getContextObject(NULL));
10: }
11: }
12:
13: return gDefaultServiceManager;
14: }
咱們能夠看到defaultServiceManager是調用ProcessState對象的getContextObject方法得到Service Manager的getContextObject方法得到Service Manager代理對象。咱們再看一下getContextObject函數的定義:
1: sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller)
2: {
3: if (supportsProcesses()) {
4: return getStrongProxyForHandle(0);
5: } else {
6: return getContextObject(String16("default"), caller);
7: }
8: }
咱們能夠看出實際上是調用咱們上面描述過的getStrongProxyForHandle方法,並以句柄0爲參數來得到Service Manager的代理對象。
ProcessState::self()->getContextObject(NULL)返回一個IBinder對象,怎樣把它轉化成一個IServiceManager的對象呢?這就是模板函數interface_cast<IServiceManager>的做用了。調用的是IServiceManager.asInterface方法。IServiceManager的asInterface方法經過DECLARE_META_INTERFACE和IMPLEMENT_META_INTERFACE宏來定義,詳細狀況請查看IServiceManager類的定義。IMPLEMENT_META_INTERFACE宏關於asInterface的定義以下:
1: android::sp<I##INTERFACE> I##INTERFACE::asInterface( \
2: const android::sp<android::IBinder>& obj) \
3: { \
4: android::sp<I##INTERFACE> intr; \
5: if (obj != NULL) { \
6: intr = static_cast<I##INTERFACE*>( \
7: obj->queryLocalInterface( \
8: I##INTERFACE::descriptor).get()); \
9: if (intr == NULL) { \
10: intr = new Bp##INTERFACE(obj); \
11: } \
12: } \
13: return intr; \
14: } \
最終asInterface將會用一個IBinder對象建立一個BpServiceManager對象,而且BpServiceManager繼承自IServiceManager,這樣咱們就把IBinder對象轉換成了IServiceManager對象。若是你仔細查看BpServiceManager的定義,你會發現查詢Service,增長Service等方法其實都是調用底層的IBinder對象來完成的。
當咱們在C/C++層面編寫程序使用Binder機制的時候將會調用defaultServiceManager函數來得到Service Manager,好比:不少Android系統Service都是在C/C++層面實現的,他們就須要向Service Manager註冊其服務,那麼這些服務將調用defaultServiceManager得到Service Manager代理對象。咱們在後續介紹Android系統Service的時候將會詳細介紹。
本文中咱們介紹了C++層面的Service代理,後續文章咱們將介紹Java層面的Service代理。