Android ServiceManager的啟動和工作原理
所有的系統(tǒng)服務(wù)都是需要在ServiceManager中進行注冊的,而ServiceManager作為一個起始的服務(wù),是通過init.rc來啟動的。
//systemcorerootdirinit.rc//啟動的服務(wù),這里是用的服務(wù)名稱。服務(wù)名稱是在對應(yīng)的rc文件中注冊并啟動的 start servicemanager
具體的服務(wù)信息是在servicemanger.rc命名并定義的
//frameworksnativecmdsservicemanagerservicemanager.rcservice servicemanager /system/bin/servicemanager class core animation user system //說明以用戶system身份運行 group system readproc //說明servicemanager是系統(tǒng)中的關(guān)鍵服務(wù), //關(guān)鍵服務(wù)是不會退出的,如果退出了,系統(tǒng)就會重啟,當系統(tǒng)重啟時就會啟動用onrestart關(guān)鍵字修飾的進程, //比如zygote、media、surfaceflinger等等。 critical onrestart restart healthd onrestart restart zygote onrestart restart audioserver onrestart restart media onrestart restart surfaceflinger onrestart restart inputflinger onrestart restart drm onrestart restart cameraserver onrestart restart keystore onrestart restart gatekeeperd onrestart restart thermalservice ..
servicemanager的入口函數(shù)在service_manager.c中
//frameworksnativelibsbinderndkservice_manager.cppint main(int argc, char** argv){//binder_state結(jié)構(gòu)體,用來存儲binder的三個信息 struct binder_state *bs;//打開binder驅(qū)動,并申請125k字節(jié)的內(nèi)存空間 bs = binder_open(driver, 128*1024); ...//將自己注冊為Binder機制的管理者 if (binder_become_context_manager(bs)) { ALOGE('cannot become context manager (%s)n', strerror(errno)); return -1; } ...//啟動循環(huán),等待并處理client端發(fā)來的請求 binder_loop(bs, svcmgr_handler); return 0;}
在main函數(shù)中主要做了3件事情。
打開驅(qū)動,并申請了128k字節(jié)大小的內(nèi)存空間 將自己注冊為Binder機制的管理者 啟動循環(huán),等待并處理Client端發(fā)來的請求 binder_open//frameworksnativecmdsservicemanagerbinder.cstruct binder_state *binder_open(const char* driver, size_t mapsize){ struct binder_state *bs; struct binder_version vers; //申請對應(yīng)的內(nèi)存空間 bs = malloc(sizeof(*bs));//打開binder設(shè)備文件,這種屬于設(shè)備驅(qū)動的操作方法 bs->fd = open(driver, O_RDWR | O_CLOEXEC);//通過ioctl獲取binder的版本號 if ((ioctl(bs->fd, BINDER_VERSION, &vers) == -1) || (vers.protocol_version != BINDER_CURRENT_PROTOCOL_VERSION)) { fprintf(stderr,'binder: kernel driver version (%d) differs from user space version (%d)n',vers.protocol_version, BINDER_CURRENT_PROTOCOL_VERSION); goto fail_open; } bs->mapsize = mapsize;//mmap進行內(nèi)存映射,將Binder設(shè)備文件映射到進程的對應(yīng)地址空間,地址空間大小為128k//映射之后,會將地址空間的起始地址和大小保存到結(jié)構(gòu)體中, bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0); return bs;}
binder_opende的主要功能是打開了Binder的驅(qū)動文件,并將文件進行了mmap映射,并將對應(yīng)的地址空間保存到了結(jié)構(gòu)體中。
binder_become_context_manager//frameworksnativecmdsservicemanagerbinder.cint binder_become_context_manager(struct binder_state *bs){ return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);}
ioctl會調(diào)用Binder驅(qū)動的binder_ioctl函數(shù),去注冊成為管理者。
binder_loop將servicemanger注冊為Binder的上下文管理者后,它就是Binder機制的“大總管”了,它會在系統(tǒng)運行期間處理Client端的請求,因為請求的時間不確定性,這里采用了無限循環(huán)來實現(xiàn)。也就是binder_loop
//frameworksnativecmdsservicemanagerbinder.cvoid binder_loop(struct binder_state *bs, binder_handler func){ int res; struct binder_write_read bwr; uint32_t readbuf[32]; bwr.write_size = 0; bwr.write_consumed = 0; bwr.write_buffer = 0;//當前線程注冊為Binder的指令 readbuf[0] = BC_ENTER_LOOPER;//將BC_ENTER_LOOPER指令寫入到Binder驅(qū)動,//將當前的ServiceManager線程注冊為了一個Binder線程(注意ServiceManager本身也是一個Binder線程)。//注冊為Binder線程之后,就可以處理進程間的請求了 binder_write(bs, readbuf, sizeof(uint32_t));//不斷的循環(huán)遍歷 for (;;) { bwr.read_size = sizeof(readbuf); bwr.read_consumed = 0; bwr.read_buffer = (uintptr_t) readbuf;//使用BINDER_WRITE_READ指令查詢Binder驅(qū)動中是否有請求。//如果有請求,就走到下面的binder_parse部分處理,如果沒有,當前的ServiceManager線程就會在Binder驅(qū)動中水命,等待新的進程間請求 res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);//走到這里說明有請求信息。將請求的信息用binder_parse來處理,處理方法是func res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func); }}
servicemanager會先將自己注冊為一個Binder線程。因為只有注冊成為Binder服務(wù)之后才能接收進程間的請求。而注冊為Binder服務(wù)的指令是BC_ENTER_LOOPER。然后通過**binder_write()**方法寫入到binder驅(qū)動。
//frameworksnativecmdsservicemanagerbinder.cint binder_write(struct binder_state *bs, void *data, size_t len){ struct binder_write_read bwr; int res; bwr.write_size = len; bwr.write_consumed = 0; bwr.write_buffer = (uintptr_t) data; bwr.read_size = 0; bwr.read_consumed = 0; bwr.read_buffer = 0;//BINDER_WRITE_READ既可以讀也可以寫。關(guān)鍵在于read_size和write_size。//如果write_size>0。則是寫。如果read_size>0則是讀。//如果都大于0,則先寫,再讀 res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr); if (res < 0) { fprintf(stderr,'binder_write: ioctl failed (%s)n',strerror(errno)); } return res;}系統(tǒng)服務(wù)注冊
在Android中,每個進程獲取系統(tǒng)提供的各種系統(tǒng)服務(wù)(AMS,PMS,WMS等)都是需要通過ServiceManager才可以。而這些系統(tǒng)服務(wù)進行Binder注冊,也需要獲取ServiceManager服務(wù)才可以。在剛才我們講過,ServiceManager會將自己也注冊成為一個Binder服務(wù)。
這里我們以SurfaceFling獲取ServiceManager服務(wù)為例來看一下是如何獲取的。
//frameworksnativeservicessurfaceflingermain_surfaceflinger.cpp#include <binder/IServiceManager.h>int main(int, char**) { .... //獲取一個SM對象,相當于是new BpServiceManager(new BpBinder(0)) sp<IServiceManager> sm(defaultServiceManager());//向ServiceManager注冊SurfaceFling服務(wù) sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false, IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO);//在SurfaceFlinger調(diào)用init方法的時候,會初始化Display的相關(guān)信息 startDisplayService(); // dependency on SF getting registered above ... return 0;}
系統(tǒng)服務(wù)的注冊過程主要有2點
獲取ServiceManager所對應(yīng)的Binder對象。 通過addService注冊為系統(tǒng)服務(wù)。 ServiceManager的Binder對象獲取**defaultServiceManager()**方法就是用來獲取ServiceManager服務(wù)的Binder對象。
defaultServiceManager
//frameworksnativelibsbinderIServiceManager.cppsp<IServiceManager> defaultServiceManager(){ if (gDefaultServiceManager != nullptr) return gDefaultServiceManager; { AutoMutex _l(gDefaultServiceManagerLock);/* * 1. ProcessState::self()->getContextObject(NULL): 返回的是一個 BpBinder. ServiceManager 的 desc 默認為0. * 2. interface_cast 就是將 BpBinder 封裝為 IServiceManager,這樣可以直接調(diào)用 IServiceManager 的接口.*//* * 這里,有一個設(shè)計思想. * 1. defaultServiceManager 首先實例化 BpBinder. * 2. interface_cast 就是 實例化 BpXXX,并將 BpBinder 交給其管理. * * Proxy 端的用戶無法直接看到 BpBinder , BpBinder 由 BpXXX 持有.用戶本身不關(guān)心 BpBinder 的能力,只關(guān)心 IXXX 定義的 接口. * 所以這里很好的進行了封裝.*/ while (gDefaultServiceManager == nullptr) {//如果不為空,表示設(shè)置過了,直接返回 //嘗試不斷的獲取ServiceManager對象,如果獲取不到,就sleep(1), //這里之所以會獲取不到,是因為ServiceManager和一些通過init.rc啟動的服務(wù)是同時啟動的,不能保證ServiceManager能夠優(yōu)先啟動完成。 //所以會存在獲取ServiceManager的時候獲取不到。 gDefaultServiceManager = interface_cast<IServiceManager>(ProcessState::self()->getContextObject(nullptr)); if (gDefaultServiceManager == nullptr)sleep(1); } } return gDefaultServiceManager;}
這里會直接調(diào)用**ProcessState::self()->getContextObject(nullptr)**來獲取對應(yīng)的服務(wù)。
ProcessState::self()->getContextObject(NULL): 返回的是一個 BpHwBinder。ServiceManager 的 desc 默認為0。 interface_cast 就是將 BpBinder 封裝為 IServiceManagerProcessState::self()
//systemlibhwbinderProcessState.cpp//返回一個ProcessStatesp<ProcessState> ProcessState::self(){ Mutex::Autolock _l(gProcessMutex); if (gProcess != nullptr) { return gProcess; } gProcess = new ProcessState(kDefaultDriver); return gProcess;}
這里會返回一個ProcessState對象。
getContextObject
//systemlibhwbinderProcessState.cppsp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/){ //傳入的參數(shù)是handle。0, return getStrongProxyForHandle(0);}sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle){ handle_entry* e = lookupHandleLocked(handle); if (e != nullptr) { IBinder* b = e->binder; if (b == nullptr || !e->refs->attemptIncWeak(this)) {//如果b為空,那么創(chuàng)建一個BpHwBinder b = new BpHwBinder(handle); e->binder = b; if (b) e->refs = b->getWeakRefs(); result = b; } else { result.force_set(b); e->refs->decWeak(this); } } return result;}
當不存在的時候,這里會創(chuàng)建一個BpHwBinder對象。所以可以理解為最后我們返回的是一個BpBinder對象
這里,有一個設(shè)計思想:
defaultServiceManager 首先實例化 BpBinder。 interface_cast 就是 實例化 BpXXX,并將 BpBinder交給其管理。Proxy 端的用戶無法直接看到 BpBinder, BpBinder 由 BpXXX 持有.用戶本身不關(guān)心 BpBinder的能力,只關(guān)心 IXXX 定義的 接口。所以這里很好的進行了封裝。
回到前文的defaultServiceManger方法中,將返回值帶入,可以得到
//注意,方法中傳入的handle為0,所以BpBinder參數(shù)為0gDefaultServiceManager = interface_cast<IServiceManager>(new BpBinder(0));
interface_cast
//frameworksnativeincludebinderIInterface.hinline sp<INTERFACE> interface_cast(const sp<IBinder>& obj){ return INTERFACE::asInterface(obj);}//INTERFACE帶入為IServiceManager之后,得到的代碼為inline sp<IServiceManager> interface_cast(const sp<IBinder>& obj){ return IServiceManager::asInterface(obj);//靜態(tài)方法所以直接調(diào)用}
調(diào)用IServiceManager接口的成員函數(shù)asInterface,將一個句柄值為0的Binder代理對象封裝為一個ServiceManger代理對象。將一個句柄值為0的Binder代理對象封裝為一個ServiceManger代理對象。
這里 IServiceManager接口的成員函數(shù)asInterface是通過宏IMPLEMENT_META_INTERFACE實現(xiàn),如下所示:
#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE(INTERFACE, NAME) #endif#define DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE(INTERFACE, NAME) ::android::sp<I##INTERFACE> I##INTERFACE::asInterface( const ::android::sp<::android::IBinder>& obj) { android::sp<I##INTERFACE> intr; if (obj != nullptr) { intr = static_cast<I##INTERFACE*>( obj->queryLocalInterface( I##INTERFACE::descriptor).get()); if (intr == nullptr) { intr = new Bp##INTERFACE(obj); } } return intr; }
帶入IServiceManager之后的代碼為:
android::sp<IServiceManager> IIServiceManager::asInterface(const android::sp<android::IBinder>& obj) { android::sp<IServiceManager> intr; if (obj != NULL) { intr = static_cast<IIServiceManager*>( obj->queryLocalInterface(IServiceManager::descriptor).get());//返回NULLif (intr == NULL) {intr = new BpServiceManager(obj); //創(chuàng)建了ServiceManager代理對象 } }return intr; }
到這里為止,我們創(chuàng)建了一個BpIServiceManager對象,并將他的接口IServiceManager返回給了調(diào)用者。
整體的邏輯可以理解為:new BpServiceManager(new BpBinder())。當然了,這只是簡化之后的代碼,其內(nèi)部復(fù)雜的邏輯現(xiàn)在可以暫不考慮。整體流程如下:
客戶端請求
當獲取到ServiceManager服務(wù)之后,就可以使用addService方法來進行服務(wù)的注冊了。在獲取服務(wù)的時候,最終返回的是BpServiceManager對象,所以這里我們可以直接找到對應(yīng)的添加服務(wù)方法
virtual status_t addService(const String16& name, const sp<IBinder>& service,bool allowIsolated, int dumpsysPriority) { Parcel data, reply; data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor()); data.writeString16(name); data.writeStrongBinder(service); data.writeInt32(allowIsolated ? 1 : 0); data.writeInt32(dumpsysPriority); status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply); return err == NO_ERROR ? reply.readExceptionCode() : err; }
BpServiceManager的構(gòu)造函數(shù)傳入的了BpBinder對象,這里的remote()方法其實就是BpBinder對象。
status_t BpBinder::transact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){ //如果binder已經(jīng)died,則不會返回數(shù)據(jù) if (mAlive) { ...//調(diào)用IPCThreadState的transact方法。 status_t status = IPCThreadState::self()->transact( mHandle, code, data, reply, flags); if (status == DEAD_OBJECT) mAlive = 0; return status; } return DEAD_OBJECT;}
這里調(diào)用了IPCThreadState的transact方法將對應(yīng)的數(shù)據(jù)寫入到了Binder驅(qū)動了。當Binder驅(qū)動接收到注冊服務(wù)的信息的時候,就會將對應(yīng)的服務(wù)注冊到ServiceManager中。我們可以看下傳遞的參數(shù):
mHandle:0,表示要處理該請求的進程號,ServiceManager在注冊的時候,其對應(yīng)的進程號是0。所以處理請求的也就是ServiceManager進程。 code:參數(shù)是ADD_SERVICE_TRANSACTION。 data:包含了要添加的進程相關(guān)信息:包括名稱、是否單獨運行等等相關(guān)信息ServiceManager處理請求
當客戶端發(fā)送請求之后,我們的ServiceManger就可以接收到消息,并且進行消息的處理了。在ServiceManager的啟動中我們了解到,當ServiceManger啟動之后,會調(diào)用binder_looper來不斷的循環(huán),檢測是否接收到對應(yīng)的數(shù)據(jù)信息。
這個功能是在binder_loop()方法的入?yún)⒅械膕vcmgr_handler來實現(xiàn)的。
//frameworksnativelibsbinderndkservice_manager.cppint main(int argc, char** argv){...//啟動循環(huán),等待并處理client端發(fā)來的請求 binder_loop(bs, svcmgr_handler); ...}
svcmgr_handler就是我們具體的請求處理方法。
//frameworksnativecmdsservicemanagerservice_manager.cint svcmgr_handler(struct binder_state *bs, struct binder_transaction_data_secctx *txn_secctx, struct binder_io *msg, struct binder_io *reply){ ... struct binder_transaction_data *txn = &txn_secctx->transaction_data; ...//根據(jù)傳輸?shù)牟煌愋蛠磉M行處理。 switch(txn->code) { case SVC_MGR_ADD_SERVICE://添加服務(wù) //進行服務(wù)的添加 do_add_service(bs, s, len, handle, txn->sender_euid, allow_isolated, dumpsys_priority,txn->sender_pid, (const char*) txn_secctx->secctx) ... } int do_add_service(struct binder_state *bs, const uint16_t *s, size_t len, uint32_t handle, uid_t uid, int allow_isolated, uint32_t dumpsys_priority, pid_t spid, const char* sid) { struct svcinfo *si; //ALOGI('add_service(’%s’,%x,%s) uid=%dn', str8(s, len), handle, // allow_isolated ? 'allow_isolated' : '!allow_isolated', uid); //服務(wù)的名稱長度不能超過127字節(jié) if (!handle || (len == 0) || (len > 127)) return -1;//最終調(diào)用selinux_check_access方法,會進行權(quán)限的檢測,檢查服務(wù)是否有進行服務(wù)注冊 if (!svc_can_register(s, len, spid, sid, uid)) { ALOGE('add_service(’%s’,%x) uid=%d - PERMISSION DENIEDn', str8(s, len), handle, uid); return -1; }//查詢是否已經(jīng)有包含了name的svcinfo si = find_svc(s, len); if (si) { if (si->handle) { ALOGE('add_service(’%s’,%x) uid=%d - ALREADY REGISTERED, OVERRIDEn', str8(s, len), handle, uid);//已經(jīng)注冊了,釋放相應(yīng)的服務(wù) svcinfo_death(bs, si); }//更新服務(wù)的handle si->handle = handle; } else {//申請內(nèi)存 si = malloc(sizeof(*si) + (len + 1) * sizeof(uint16_t)); si->handle = handle; si->len = len; memcpy(si->name, s, (len + 1) * sizeof(uint16_t)); si->name[len] = ’0’; si->death.func = (void*) svcinfo_death; si->death.ptr = si; si->allow_isolated = allow_isolated; si->dumpsys_priority = dumpsys_priority;//將其注冊到服務(wù)列表svclist中,這里使用的鏈表來保存數(shù)據(jù) si->next = svclist; svclist = si; }//以handle為目標,發(fā)送BC_ACQUIRE指令。 binder_acquire(bs, handle);//以handle為目標,發(fā)送BC_REQUEST_DEATH_NOTIFICATION指令。 binder_link_to_death(bs, handle, &si->death); return 0;}
當拿到請求信息之后,ServiceManager會生成對應(yīng)的svcinfo對象,將其保存到服務(wù)列表svclist中。
整體流程如下:
我們也可以從另一個維度去看看Binder的具體
系統(tǒng)服務(wù)獲取對于Servie服務(wù)的獲取,其實也是答題思路也是相同的。顯示獲取ServiceManager的Binder對象,然后服務(wù)端發(fā)送獲取某項服務(wù)的請求,ServiceManager來進行處理。
這里我們只看一下ServiceManager接收到服務(wù)獲取的處理機制。也是在**svcmgr_handler()**中。
//frameworksnativecmdsservicemanagerservice_manager.cint svcmgr_handler(struct binder_state *bs, struct binder_transaction_data_secctx *txn_secctx, struct binder_io *msg, struct binder_io *reply){ ... struct binder_transaction_data *txn = &txn_secctx->transaction_data; ...//根據(jù)傳輸?shù)牟煌愋蛠磉M行處理。 switch(txn->code) { case SVC_MGR_GET_SERVICE://獲取服務(wù) case SVC_MGR_CHECK_SERVICE: s = bio_get_string16(msg, &len); if (s == NULL) {return -1; } //根據(jù)pid,uid來獲取服務(wù)對應(yīng)的handle值 handle = do_find_service(s, len, txn->sender_euid, txn->sender_pid, (const char*) txn_secctx->secctx); if (!handle)break; //返回服務(wù)對應(yīng)的handle bio_put_ref(reply, handle); return 0;}
這里主要做了2個操作:
從服務(wù)列表中獲取到對應(yīng)的服務(wù)的handle 將handle寫入到要返回的reply數(shù)據(jù)中。 do_find_service//frameworksnativecmdsservicemanagerservice_manager.c //獲取對應(yīng)的服務(wù)uint32_t do_find_service(const uint16_t *s, size_t len, uid_t uid, pid_t spid, const char* sid){//獲取對應(yīng)的服務(wù) struct svcinfo *si = find_svc(s, len); if (!si || !si->handle) { return 0; } if (!si->allow_isolated) { // If this service doesn’t allow access from isolated processes, // then check the uid to see if it is isolated. uid_t appid = uid % AID_USER;//檢查服務(wù)是否是允許孤立于進程而單獨存在的 if (appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END) { return 0; } }//檢測是否有selinx權(quán)限。 if (!svc_can_find(s, len, spid, sid, uid)) { return 0; }//返回服務(wù)的handle return si->handle;}bio_put_ref
當獲取到服務(wù)之后handle之后,會調(diào)用**bio_put_ref()**方法將服務(wù)對應(yīng)的handle寫入到返回的數(shù)據(jù)中。
//frameworksnativecmdsservicemanagerservice_manager.cvoid bio_put_ref(struct binder_io *bio, uint32_t handle){ struct flat_binder_object *obj;//申請對應(yīng)的地址空間 if (handle) obj = bio_alloc_obj(bio); else obj = bio_alloc(bio, sizeof(*obj)); if (!obj) return; obj->flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;//類型是BINDER_TYPE_HANDLE obj->hdr.type = BINDER_TYPE_HANDLE;//記錄handle obj->handle = handle; obj->cookie = 0;}
對于服務(wù)的獲取,肯定是需要將reply的數(shù)據(jù)寫回到請求服務(wù)的進程的。這時候就需要回到我們在binder_loop()函數(shù)了。在該函數(shù)中,存在一個binder_parse(),在這個方法里面會處理請求信息,并將reply信息通過binder驅(qū)動發(fā)送給客戶端。
binder_parse//frameworksnativecmdsservicemanagerbinder.cint binder_parse(struct binder_state *bs, struct binder_io *bio, uintptr_t ptr, size_t size, binder_handler func){ ... case BR_TRANSACTION: { ...//調(diào)用func函數(shù)res = func(bs, txn, &msg, &reply);if (txn->flags & TF_ONE_WAY) { binder_free_buffer(bs, txn->data.ptr.buffer);} else {//發(fā)送協(xié)議指令給Binder驅(qū)動,向Client端發(fā)送reply binder_send_reply(bs, &reply, txn->data.ptr.buffer, res);} ... return r;}
當調(diào)用了func函數(shù),有對應(yīng)返回信息之后,會通過binder_send_reply()方法,將reply數(shù)據(jù)信息發(fā)送給client端。
void binder_send_reply(struct binder_state *bs, struct binder_io *reply, binder_uintptr_t buffer_to_free, int status){ struct { uint32_t cmd_free; binder_uintptr_t buffer; uint32_t cmd_reply; struct binder_transaction_data txn; } __attribute__((packed)) data; data.cmd_free = BC_FREE_BUFFER; data.buffer = buffer_to_free;//返回指令 data.cmd_reply = BC_REPLY; data.txn.target.ptr = 0; data.txn.cookie = 0; data.txn.code = 0; if (status) { data.txn.flags = TF_STATUS_CODE; data.txn.data_size = sizeof(int); data.txn.offsets_size = 0; data.txn.data.ptr.buffer = (uintptr_t)&status; data.txn.data.ptr.offsets = 0; } else {//svcmgr_handler執(zhí)行成功,將reply數(shù)據(jù)組裝到txn中 data.txn.flags = 0; data.txn.data_size = reply->data - reply->data0; data.txn.offsets_size = ((char*) reply->offs) - ((char*) reply->offs0); data.txn.data.ptr.buffer = (uintptr_t)reply->data0; data.txn.data.ptr.offsets = (uintptr_t)reply->offs0; }//發(fā)送數(shù)據(jù) binder_write(bs, &data, sizeof(data));}總結(jié)
ServiceManager是一個守護進程,負責(zé)管理系統(tǒng)中的所有服務(wù)信息。通過一個鏈表來保存了所有注冊過的信息。而且其本身也是一個服務(wù),在通過Binder驅(qū)動將其注冊為守護進程之后,會將自己也注冊為一個服務(wù),供其他服務(wù)調(diào)用。
以上就是Android ServiceManager的啟動和工作原理的詳細內(nèi)容,更多關(guān)于Android ServiceManager的資料請關(guān)注好吧啦網(wǎng)其它相關(guān)文章!
相關(guān)文章:
1. CSS Hack大全-教你如何區(qū)分出IE6-IE10、FireFox、Chrome、Opera2. jsp+mysql實現(xiàn)網(wǎng)頁的分頁查詢3. React優(yōu)雅的封裝SvgIcon組件示例4. ASP基礎(chǔ)知識Command對象講解5. ASP中格式化時間短日期補0變兩位長日期的方法6. jsp文件下載功能實現(xiàn)代碼7. ASP動態(tài)網(wǎng)頁制作技術(shù)經(jīng)驗分享8. XML入門精解之結(jié)構(gòu)與語法9. ASP腳本組件實現(xiàn)服務(wù)器重啟10. jsp+servlet實現(xiàn)猜數(shù)字游戲
