Android Binder基本概念流程学习
一 Media Service進(jìn)程啟動
Init.rc中描述的service對應(yīng)linux 的進(jìn)程:
Media進(jìn)程定義:
service media /system/bin/mediaserverclass mainuser mediagroup audio camera inet net_bt net_bt_admin net_bw_acct drmrpcioprio rt 4servicemanager 進(jìn)程定義:
service servicemanager /system/bin/servicemanagerclass coreuser systemgroup system?
Media中有很多Native Service(AudioFlinger MediaPlayerService CameraService?
AudioPolicyService等),整個Android(native或者framework)的Service都需要加入
servicemanager中進(jìn)行統(tǒng)一管理。
那么Media Process 與ServiceManager Process是如何進(jìn)行通信的呢——Binder.
通過Media Process中使用binder進(jìn)行完成IPC過程,學(xué)習(xí)Binder的概念和使用方法。
\frameworks\av\media\mediaserver\ main_mediaserver.cpp:
int main(int argc, char** argv) {//創(chuàng)建ProcessState 當(dāng)前進(jìn)程屬性sp<ProcessState> proc(ProcessState::self());//IServiceManager對象sp<IServiceManager> sm = defaultServiceManager();//初始化MediaPlayerService服務(wù)對象 MediaPlayerService::instantiate();……//啟動進(jìn)程的線程池ProcessState::self()->startThreadPool();//執(zhí)行線程消息循環(huán)IPCThreadState::self()->joinThreadPool(); }Sp:指針運(yùn)算符和普通運(yùn)算符的重載 StrongPointer。
二 Media Process執(zhí)行過程
1 ProcessState對象創(chuàng)建
當(dāng)前進(jìn)程的狀態(tài)屬性,對象創(chuàng)建:
sp<ProcessState> ProcessState::self() {Mutex::Autolock _l(gProcessMutex);if (gProcess != NULL) {return gProcess;}gProcess = new ProcessState;return gProcess; }ProcessState構(gòu)造函數(shù):
ProcessState::ProcessState(): mDriverFD(open_driver()) //打開binder驅(qū)動設(shè)備 , mVMStart(MAP_FAILED), mManagesContexts(false), mBinderContextCheckFunc(NULL), mBinderContextUserData(NULL), mThreadPoolStarted(false), mThreadPoolSeq(1) {if (mDriverFD >= 0) {//將binder的fd映射到當(dāng)前進(jìn)程虛擬空間地址中 與binder進(jìn)行交互mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);} }打開binder設(shè)備:
static int open_driver() {//打開binder設(shè)備驅(qū)動int fd = open("/dev/binder", O_RDWR);if (fd >= 0) {//bidner最大支持線程數(shù)size_t maxThreads = 15;result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);}return fd; } ProcessState對象創(chuàng)建過程所做的事:
打開/dev/binder設(shè)備,得到binder設(shè)備的fd;
將bidner設(shè)備fd映射到當(dāng)前進(jìn)程虛擬地址空間建立交互的通道;
2 IServiceManager對象創(chuàng)建
sp<IServiceManager> sm = defaultServiceManager();
為什么需要一個IServiceManager對象呢,這個類是個抽象提供接口
通過IServiceManager派生對象操作將Service加入到ServiceManager中.
defaultServiceManager()函數(shù):
sp<IServiceManager> defaultServiceManager() {//單例對象if (gDefaultServiceManager != NULL) return gDefaultServiceManager;AutoMutex _l(gDefaultServiceManagerLock);if (gDefaultServiceManager == NULL) {//創(chuàng)建對象gDefaultServiceManager = interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL));}return gDefaultServiceManager; }?ProcessState::self()->getContextObject(NULL):得到一個IBinder對象
ProcessState::self()剛才所創(chuàng)建的ProcessState對象。
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller) {return getStrongProxyForHandle(0); }sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle) {sp<IBinder> result;AutoMutex _l(mLock);//從表中查詢一個handle對應(yīng)的handle_entry //若沒有則創(chuàng)建一個 handle == 0handle_entry* e = lookupHandleLocked(handle);if (e != NULL) {IBinder* b = e->binder;if (b == NULL || !e->refs->attemptIncWeak(this)) {//handle_entry對象成員初始化 創(chuàng)建handle=0的BpBinder b = new BpBinder(handle); e->binder = b;if (b) e->refs = b->getWeakRefs();result = b;}}return result; }handle_entry是什么呢?
struct handle_entry {IBinder* binder;RefBase::weakref_type* refs;};也就是說ProcessState 有一個表Vector<handle_entry>mHandleToObject;
表里面的每一項(xiàng)存儲了一個binder,每一個binder對應(yīng)一個handle。
Handle = 0是什么,句柄? 代表誰的句柄——ServiceManager在binder中的資源。
從ProcessState::self()->getContextObject(NULL)得到一個 IBinder——BpBinder(0);
于是得到:
gDefaultServiceManager = interface_cast<IServiceManager>(BpBinder(0));
使用interface_cast將IBinder實(shí)例轉(zhuǎn)化成IServiceManager實(shí)例。
3 interface_cast函數(shù)
\frameworks\native\include\binder\IInterface.h:
interface_cast是個內(nèi)聯(lián)模板函數(shù):
template<typename INTERFACE> inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj) {return INTERFACE::asInterface(obj); }結(jié)合前面就是:
inline sp<IServiceManager> interface_cast(const sp<IBinder>& obj) {return IServiceManager::asInterface(obj); }?
所以需要到IServiceManager里面去看看是如何實(shí)現(xiàn)的
4 IServiceManager類
\frameworks\native\include\binder\IServiceManager.h:
IServiceManager是一個抽象類:
class IServiceManager : public IInterface {public://宏聲明 DECLARE_META_INTERFACE(ServiceManager);virtual sp<IBinder> getService( const String16& name) const = 0;virtual status_t addService( const String16& name,const sp<IBinder>& service,bool allowIsolated = false) = 0;…… }DECLARE_META_INTERFACE聲明:
#define DECLARE_META_INTERFACE(INTERFACE) \static const android::String16 descriptor; \static android::sp<I##INTERFACE> asInterface( \const android::sp<android::IBinder>& obj); \virtual const android::String16& getInterfaceDescriptor() const; \I##INTERFACE(); \virtual ~I##INTERFACE(); \?替換成IServiceManager:
//實(shí)現(xiàn)時傳入:android.os.IServiceManager static const android::String16 descriptor; static android::sp<IServiceManager> asInterface( const android::sp<android::IBinder>& obj); virtual const android::String16& getInterfaceDescriptor() const; //構(gòu)造析構(gòu)函數(shù) IServiceManager(); virtual ~IServiceManager();實(shí)現(xiàn)\frameworks\native\include\binder\IServiceManager.cpp:
IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");
IMPLEMENT_META_INTERFACE實(shí)現(xiàn):
看一下asInterface接口:
替換成IServiceManager:
android::sp<IServiceManager> IServiceManager::asInterface( const android::sp<android::IBinder>& obj) { //obj BpBinder實(shí)例 android::sp<IServiceManager> intr; if (obj != NULL) {//返回NULL intr = static_cast<IServiceManager*>( obj->queryLocalInterface( IServiceManager::descriptor).get()); if (intr == NULL) { intr = new BpServiceManager(obj); } } return intr; }這里得到IServiceManager 實(shí)例:
BpServiceManager:new BpServiceManager(new BpBinder(0));
5 BpServiceManager 和 BpInterface類
\frameworks\native\libs\binder\ IServiceManager.cpp:BpServiceManager
class BpServiceManager : public BpInterface<IServiceManager> { public://impl就是 new BpBinder(0)BpServiceManager(const sp<IBinder>& impl): BpInterface<IServiceManager>(impl){}virtual sp<IBinder> checkService(const String16& name) const{……remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);}virtual status_t addService(const String16& name, const sp<IBinder>& service,bool allowIsolated){……remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);} }\frameworks\native\include\binder\ IInterface.h:模板類BpInterface
template<typename INTERFACE> class BpInterface : public INTERFACE, public BpRefBase // INTERFACE IServiceManager {public:BpInterface(const sp<IBinder>& remote);protected: virtual IBinder* onAsBinder(); };BpInterface構(gòu)造函數(shù):
template<typename INTERFACE> inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote) : BpRefBase(remote) {}
BpRefBase構(gòu)造函數(shù):
BpRefBase::BpRefBase(const sp<IBinder>& o) : mRemote(o.get()), mRefs(NULL), mState(0) {// IBinder mRemote 指向 o.get() :new BpBinder(0) } gDefaultServiceManager = interface_cast<IServiceManager>(BpBinder(0));
實(shí)際為:
gDefaultServiceManager = new BpServiceManager(new BpBinder(0));
Bn代表Binder Native Bp代表Binder Proxy
BpServiceManager代理的BpBinder實(shí)例 BpBinder代理的handle(0)
這個關(guān)系有些復(fù)雜,看一下類繼承結(jié)構(gòu)圖:
上面這個結(jié)構(gòu)看起來感覺很熟悉——Bridge模式。將Binder數(shù)據(jù)交互和功能處理橋接起來。
在Media Process 的main函數(shù)中通過:
sp<IServiceManager> sm = defaultServiceManager();
我們得到了sm:是BpServiceManager對象。
三 MediaPlayerService加入到ServiceManager中
回到main函數(shù)中:
int main(int argc, char** argv) {//創(chuàng)建ProcessState 當(dāng)前進(jìn)程屬性sp<ProcessState> proc(ProcessState::self());//IServiceManager對象sp<IServiceManager> sm = defaultServiceManager();//初始化MediaPlayerService服務(wù)對象MediaPlayerService::instantiate(); //執(zhí)行到這里 ……//啟動進(jìn)程的線程池ProcessState::self()->startThreadPool();//執(zhí)行線程消息循環(huán)IPCThreadState::self()->joinThreadPool(); }1 MediaPlayerService初始化過程
void MediaPlayerService::instantiate() {// defaultServiceManager就是上面所述得到的BpServiceManager對象defaultServiceManager()->addService(String16("media.player"), new MediaPlayerService()); }BpServiceManager添加Service:
virtual status_t addService(const String16& name, const sp<IBinder>& service,bool allowIsolated) {//生成數(shù)據(jù)包Parcel Parcel data, reply;// Write RPC headers 寫入Interface名字 得到“android.os.IServiceManager” data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());//寫入Service名字 “media.player” data.writeString16(name);//寫入服務(wù) data.writeStrongBinder(service);data.writeInt32(allowIsolated ? 1 : 0);// remote()返回BpBinder對象status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);return err == NO_ERROR ? reply.readExceptionCode() : err; }remote()->transact 到BpBinder中:
status_t BpBinder::transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { if (mAlive) {//到當(dāng)前進(jìn)程IPCThreadState中 mHandle=0status_t status = IPCThreadState::self()->transact(mHandle, code, data, reply, flags);if (status == DEAD_OBJECT) mAlive = 0;return status;}return DEAD_OBJECT; }?
2 IPCThreadState中寫入數(shù)據(jù)到Binder設(shè)備過程
IPCThreadState::self()->transact過程:
status_t IPCThreadState::transact(int32_t handle,uint32_t code, const Parcel& data,Parcel* reply, uint32_t flags) {status_t err = data.errorCheck();flags |= TF_ACCEPT_FDS;//將數(shù)據(jù)轉(zhuǎn)化成binder_transaction_data 寫入到Parcel實(shí)例mOut中err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);//寫入數(shù)據(jù)err = waitForResponse(reply);return err; } status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult) {while (1) {//將數(shù)據(jù)寫入到Binder設(shè)備中 talkWithDriver();……}return err; }status_t IPCThreadState::talkWithDriver(bool doReceive) {//將數(shù)據(jù)封裝成binder_write_read結(jié)構(gòu) binder_write_read bwr;do {//將數(shù)據(jù)寫入到所打開的Binder設(shè)備中ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr)……} while (err == -EINTR);return NO_ERROR; }將MediaPlayerService加入到ServiceManager中,
這里就通過BpServiceManager的AddService將數(shù)據(jù)寫入到Binder設(shè)備傳遞給ServiceManager。
繼續(xù)Media Process過程
四 Media Process消息循環(huán)
int main(int argc, char** argv) {//啟動進(jìn)程的線程池 ProcessState::self()->startThreadPool(); //走到了這里//執(zhí)行線程消息循環(huán)IPCThreadState::self()->joinThreadPool(); }
1 創(chuàng)建工作者線程
startThreadPool:\frameworks\native\libs\binder\ ProcessState.cpp:
void ProcessState::startThreadPool() {spawnPooledThread(true); }void ProcessState::spawnPooledThread(bool isMain) {//創(chuàng)建PoolThread對象 并run ,非線程sp<Thread> t = new PoolThread(isMain);t->run(buf); }PoolThread繼承Thread
執(zhí)行Thread的run函數(shù):
status_t Thread::run(const char* name, int32_t priority, size_t stack) {//創(chuàng)建線程mThread _threadLoopbool res;res = createThreadEtc(_threadLoop,this, name, priority, stack, &mThread);return NO_ERROR; }現(xiàn)在有兩個線程:主線程和mThread線程
mThread線程執(zhí)行:_threadLoop
int Thread::_threadLoop(void* user) {Thread* const self = static_cast<Thread*>(user);do {//調(diào)用子類的threadLoopresult = self->threadLoop();……} while(strong != 0);return 0; }class PoolThread : public Thread { protected:virtual bool threadLoop(){IPCThreadState::self()->joinThreadPool(mIsMain);return false;} };2 進(jìn)程間通信消息循環(huán)過程
消息循環(huán):
void IPCThreadState::joinThreadPool(bool isMain) {mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);status_t result; //消息循環(huán)do {int32_t cmd;//從binder設(shè)備中讀取命令result = talkWithDriver();if (result >= NO_ERROR) {cmd = mIn.readInt32();//執(zhí)行命令result = executeCommand(cmd);}……} while (result != -ECONNREFUSED && result != -EBADF);mOut.writeInt32(BC_EXIT_LOOPER);talkWithDriver(false); }命令執(zhí)行:
status_t IPCThreadState::executeCommand(int32_t cmd) {BBinder* obj;RefBase::weakref_type* refs;switch (cmd) {case BR_DECREFS:break;case BR_ATTEMPT_ACQUIRE:break; case BR_TRANSACTION:binder_transaction_data tr;result = mIn.read(&tr, sizeof(tr));if (tr.target.ptr) {//將目標(biāo)對象轉(zhuǎn)化成BBindersp<BBinder> b((BBinder*)tr.cookie);//調(diào)用BBinder的transact 函數(shù)const status_t error = b->transact(tr.code, buffer, &reply, tr.flags);}break;……default:}return result; }binder_transaction_data.cookie:target object cookie目標(biāo)對象,這個target object是指那個呢?
在Media Process里面有幾個Service:AudioFlinger、MediaPlayerService、CameraService等。
這個目標(biāo)是這其中Service中的一個,假設(shè)目標(biāo)對象為為MediaPlayerService,那為何要轉(zhuǎn)化成BBinder呢?
3 Service對命令的處理
線程從binder接收到消息命令,將命令傳遞給Service處理。將目標(biāo)對象轉(zhuǎn)化成BBinder,然后調(diào)度此命令;
命令從遠(yuǎn)端傳遞到本地端進(jìn)行處理,每個Service都對應(yīng)BnXXX對象來處理遠(yuǎn)端BpXXX傳來的命令。
sp<BBinder> b((BBinder*)tr.cookie);
const status_t error = b->transact(tr.code, buffer, &reply, tr.flags);
這里b代表某個Service:假設(shè)為MediaPlayerService;弄清楚執(zhí)行過程,要弄清楚類繼承關(guān)系。
本地端BnMediaPlayerService消息處理過程:真正的對象是MediaPlayerService實(shí)例。
從BBinder ->transact開始傳遞:
?
可以看看Client類繼承關(guān)系結(jié)構(gòu)圖:
看到這個跟上面的MediaPlayerService繼承關(guān)系非常的相似,
這個結(jié)構(gòu)也非常的熟悉——Adapter模式;將binder消息交互和命令處理適配到一起。
五 Client端與Service端交互
Client對Service進(jìn)行使用Binder通信,是得到一個Service BnXXX端對象的代理,在Client 為BpXXX代理,
然后使用此代理進(jìn)行相關(guān)的操作. 前面在使用ServiceManager就是此種方式進(jìn)行。
實(shí)際上通信的基礎(chǔ)是Binder,Proxy不過是在Binder上進(jìn)行了一層封裝,封裝了對binder驅(qū)動的底層操作,使具有面向?qū)ο蟮奶匦浴?/span>
任意兩個進(jìn)程通過Binder進(jìn)行通信,就是先得到另一個進(jìn)程的binder標(biāo)識,通過此binder進(jìn)行數(shù)據(jù)交換。
1 新增加一個服務(wù)?
看下面media Palyer類繼承結(jié)構(gòu)。
實(shí)現(xiàn)Bn端類繼承結(jié)構(gòu):
實(shí)現(xiàn)Bp端類繼承結(jié)構(gòu):
?
可以看到 :
- 需要定義服務(wù)公共接口IMediaPlayerService;
- 實(shí)現(xiàn)服務(wù)Bn端 派發(fā)消息BnMediaPlayerService;
- 實(shí)現(xiàn)服務(wù)的命令處理MediaPlayerService;
- 實(shí)現(xiàn)服務(wù)代理BpMediaPlayerService;
2 Client獲取Service服務(wù)
Native Service以及framework Service都是加入到ServiceManger中,
不管native端還是Framework端得Service 其實(shí)都是要滿足上面遠(yuǎn)程對象代理結(jié)構(gòu)。
native端獲取service:
//獲取ServiceManager的代理對象 sp<IServiceManager> sm = defaultServiceManager(); //通過ServiceManager獲取media Service binder binder = sm->getService(String16("media.player")); //將binder封裝 構(gòu)造media Service代理對象 BpMediaPlayerService sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);framework層的service,借助AIDL文件,實(shí)現(xiàn)跨進(jìn)程的通信:
所有framework端service想要作為公共的服務(wù),被別的應(yīng)用程序調(diào)用,都要實(shí)現(xiàn)AIDL文件,服務(wù)要繼承該AIDL文件內(nèi)部類Stub。
其實(shí)AIDL文件是對Framework中service作為進(jìn)程通信的框架的封裝,系統(tǒng)自動生成中間需要的代碼和步驟,統(tǒng)一結(jié)構(gòu):還是binder代理,服務(wù)代理。
下面看看PowerManagerService實(shí)現(xiàn)。
PowerManagerService服務(wù):
\frameworks\base\services\java\com\android\server\PowerManagerService.java
public class PowerManagerService extends IPowerManager.Stub…… {public void goToSleep(long time){……} };AIDL文件:\frameworks\base\core\java\android\os\IPowerManager.aidl interface IPowerManager {void goToSleep(long time);…… } AIDL對應(yīng)的Java文件:
AIDL會自動生成一個對應(yīng)的Java的interface文件,看看這個接口文件。
AIDL自動生成對應(yīng)java文件位置:\out\target\common\obj\JAVA_LIBRARIES\framework_intermediates\src\core\java\android\os
看下其中類結(jié)構(gòu):
AIDL自動生成對應(yīng)的java文件,將結(jié)構(gòu)過程進(jìn)行了統(tǒng)一,自動生成中間代碼。
Application獲取用Service:
IPowerManager m mPowerManagerService; //獲取service的bingder IBinder binder = ServiceManager.getService("power"); //創(chuàng)建service代理對象 mPowerManagerService = IPowerManager.Stub.asInterface(binder); //調(diào)用接口 mPowerManagerService.goToSleep();Native Service和 Framework Service結(jié)構(gòu)方式基本一致的。
?
進(jìn)程間通信Linux系統(tǒng)已經(jīng)提供了很多方式,比如Socket,為什么Android非要另辟蹊徑,設(shè)計了Binder呢?
可以閱讀一下:http://www.cnblogs.com/bastard/archive/2012/10/17/2728155.html
Game Over !
參考文檔:
http://www.cnblogs.com/innost/archive/2011/01/09/1931456.html
http://blog.csdn.net/maxleng/article/details/5490770
注:
?
“我們其實(shí)還一部分沒有研究,就是同一個進(jìn)程之間的對象傳遞與遠(yuǎn)程傳遞是區(qū)別的。同一個進(jìn)程間專遞服務(wù)地和對象,
就沒有代理BpBinder產(chǎn)生,而只是對象的直接應(yīng)用了。應(yīng)用程序并不知道數(shù)據(jù)是在同一進(jìn)程間傳遞還是不同進(jìn)程間傳遞,
這個只有內(nèi)核中的Binder知道,所以內(nèi)核Binder驅(qū)動可以將Binder對象數(shù)據(jù)類型從BINDER_TYPE_BINDER修改為
BINDER_TYPE_HANDLE或者BINDER_TYPE_WEAK_HANDLE作為引用傳遞?!??——來自上述地址
這個可以看到在SystemServer運(yùn)行的Service之間使用時,直接轉(zhuǎn)化成了對應(yīng)的對象,而不是通過代理。
原文地址:http://www.cnblogs.com/bastard/archive/2012/11/13/2766611.html
總結(jié)
以上是生活随笔為你收集整理的Android Binder基本概念流程学习的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android的IPC机制Binder
- 下一篇: Framework中网络定位服务简介