編輯:關於Android編程
本文參考《Android系統源代碼情景分析》,作者羅升陽。
一、測試代碼:
~/Android/external/binder/server
----FregServer.cpp
~/Android/external/binder/common
----IFregService.cpp
----IFregService.h
~/Android/external/binder/client
----FregClient.cpp
Binder庫(libbinder)代碼:
~/Android/frameworks/base/libs/binder
----BpBinder.cpp
----Parcel.cpp
----ProcessState.cpp
----Binder.cpp
----IInterface.cpp
----IPCThreadState.cpp
----IServiceManager.cpp
----Static.cpp
~/Android/frameworks/base/include/binder
----Binder.h
----BpBinder.h
----IInterface.h
----IPCThreadState.h
----IServiceManager.h
----IBinder.h
----Parcel.h
----ProcessState.h
驅動層代碼:
~/Android//kernel/goldfish/drivers/staging/android
----binder.c
----binder.h
二、源碼分析
1、程序首先開始從Service進程FregServer.cpp的main函數開始執行
~/Android/external/binder/server
----FregServer.cpp
class FregService : public BnFregService { ........... public: static void instantiate() { defaultServiceManager()->addService(String16(FREG_SERVICE), new FregService()); } ........... }; int main(int argc, char** argv) { FregService::instantiate(); ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool(); return 0; }main函數首先調用靜態方法instantiate,在instantiate中調用了defaultServiceManager(),defaultServiceManager()函數實現如下:
~/Android/frameworks/base/libs/binder
----IServiceManager.cpp
sp其中gDefaultServiceManagerLock,gDefaultServiceManager都定義在Static.cpp中。defaultServiceManager() { if (gDefaultServiceManager != NULL) return gDefaultServiceManager;//如果已經創建了代理對象,那麼就直接返回 { AutoMutex _l(gDefaultServiceManagerLock);//使用鎖,來實現單例模式 if (gDefaultServiceManager == NULL) { gDefaultServiceManager = interface_cast (//分三步獲取Service Manager代理對象 ProcessState::self()->getContextObject(NULL)); } } return gDefaultServiceManager; }
~/Android/frameworks/base/libs/binder
----Static.cpp
Mutex gDefaultServiceManagerLock; //鎖 sp全局變量gDefaultServiceManager是一個類型為IServiceManager的強指針,它指向進程內的一個BpServiceManager對象,即Service Manager代理對象;而全局變量gDefaultServiceManagerLock是用來保證一個進程至多只有一個Service Manager代理對象。結合鎖機制來保證對象在進程中的唯一性,這是單例設計模式的經典實現。gDefaultServiceManager; //IServiceManager的強指針
如果已經創建了代理對象,那麼就直接返回。如果沒有創建,那麼分三步創建:
(1)、調用ProcessState類的靜態成員函數self獲取進程內的一個ProcessState對象。
(2)、調用前面獲得的ProcessState對象的成員函數getContextObject創建一個Binder代理對象
(3)、調用模板函數interface_cast
2、調用ProcessState類的靜態成員函數self獲取進程內的一個ProcessState對象
~/Android/frameworks/base/libs/binder
----ProcessState.cpp
sp其中gProcess,gProcessMutex都位於Static.cpp中ProcessState::self() { if (gProcess != NULL) return gProcess;//如果已經創建了,就直接返回 AutoMutex _l(gProcessMutex); if (gProcess == NULL) gProcess = new ProcessState;//創建ProcessState對象 return gProcess; }
Mutex gProcessMutex; sp全局變量gProcess是一個類型為ProcessState的強指針,它指向進程內的一個ProcessState對象;而全局變量gProcessMutex是一個互斥鎖,是用來保證一個進程至多只有一個ProcessState對象的,同樣是一個單例模式。gProcess;
首次進入,故創建ProcessState對象。
~/Android/frameworks/base/libs/binder
----ProcessState.cpp
ProcessState::ProcessState() : mDriverFD(open_driver()) , mVMStart(MAP_FAILED) ..... { if (mDriverFD >= 0) { ........... // mmap the binder, providing a chunk of virtual address space to receive transactions. mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0); ........... }在初始化構造函數中調用了open_driver方法。
~/Android/frameworks/base/libs/binder
static int open_driver() { if (gSingleProcess) { return -1; } int fd = open("/dev/binder", O_RDWR);//又一個進程打開了設備文件,binder_procs又多了一個進程的結構體 if (fd >= 0) { fcntl(fd, F_SETFD, FD_CLOEXEC); int vers; #if defined(HAVE_ANDROID_OS) status_t result = ioctl(fd, BINDER_VERSION, &vers); #else status_t result = -1; errno = EPERM; #endif if (result == -1) { LOGE("Binder ioctl to obtain version failed: %s", strerror(errno)); close(fd); fd = -1; } if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) { LOGE("Binder driver protocol does not match user space protocol!"); close(fd); fd = -1; } #if defined(HAVE_ANDROID_OS) size_t maxThreads = 15; result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads); if (result == -1) { LOGE("Binder ioctl to set max threads failed: %s", strerror(errno)); } #endif } else { LOGW("Opening '/dev/binder' failed: %s\n", strerror(errno)); } return fd; }open_driver首先調用了open打開設備文件,在http://blog.csdn.net/jltxgcy/article/details/25797011這盤文章中已經講解了驅動層的binder_open所做的事。然後的調用ioctl傳入BINDER_VERSION參數來獲取vers。最後調用ioctl傳入BINDER_SET_MAX_THREADS參數來設備該進程所支持的最大線程數。
在初始化列表中調用mmap把設備文件/dev/binder映射到進程的地址空間,其實將/dev/binder映射到進程的地址空間實際上是請求Binder驅動程序為進程分配內核緩沖區。
3、調用前面獲得的ProcessState對象的成員函數getContextObject創建一個Binder代理對象
~/Android/frameworks/base/libs/binder
----ProcessState.cpp
spProcessState::getContextObject(const sp & caller) { if (supportsProcesses()) { return getStrongProxyForHandle(0); } else { return getContextObject(String16("default"), caller); } }
狀態欄一體化及其帶來的軟鍵盤自適應問題應項目需求才開始了解狀態欄一體化的問題,作為一個android新手,之前從未接觸過。第一反應是網上搜索,不得不說網絡確實給我帶來很大
上一篇文章對MVC框架模式做了簡要概述並且在文章的最後給出了MVC3個組件之間相互工作的邏輯圖,在本文我們將進一步對模型(model)-視圖(view)-控制器(cont
Android4.4新特性,系統狀態欄一體化。 實現的步驟主要有以下幾點: 1.android4.4 以上版本 2.設置app全屏: 方法:在AndroidManifes
本文實例講述了Android氣泡效果實現方法。分享給大家供大家參考,具體如下:最近在看以前在eoe上收藏的一些源代碼,准備將這些代碼加上一些自己的注釋,然後貼出來,方便自