Binder通信簡(jiǎn)介:
linux
系統(tǒng)中進(jìn)程間通信的方式有:socket, named pipe,message queque, signal,share memory。
Java
系統(tǒng)中的進(jìn)程間通信方式有socket, named pipe等,
Android
應(yīng)用程序
理所當(dāng)然可以應(yīng)用JAVA的IPC機(jī)制實(shí)現(xiàn)進(jìn)程間的通信,但我查看android的源碼,在同一終端上的應(yīng)用軟件的通信幾乎看不到這些IPC通信方式,取而代之的是Binder通信。
google
為什么要采用這種方式呢,這取決于Binder通信方式的高效率。 Binder通信是通過(guò)linux的binder driver來(lái)實(shí)現(xiàn)的,Binder通信操作類(lèi)似線程遷移(thread migration),兩個(gè)進(jìn)程間IPC看起來(lái)就象是一個(gè)進(jìn)程進(jìn)入另一個(gè)進(jìn)程執(zhí)行代碼然后帶著執(zhí)行的結(jié)果返回。Binder的用戶空間為每一個(gè)進(jìn)程維護(hù)著一個(gè)可用的線程池,線程池用于處理到來(lái)的IPC以及執(zhí)行進(jìn)程本地消息,Binder通信是同步而不是異步。
Android中的Binder通信是基于Service與Client的,所有需要IBinder通信的進(jìn)程都必須創(chuàng)建一個(gè)IBinder接口,系統(tǒng)中有一個(gè)進(jìn)程管理所有的system service,Android不允許用戶添加非授權(quán)的System service,當(dāng)然現(xiàn)在源碼開(kāi)發(fā)了,我們可以修改一些代碼來(lái)實(shí)現(xiàn)添加底層system Service的目的。對(duì)用戶程序來(lái)說(shuō),我們也要?jiǎng)?chuàng)建server,或者Service用于進(jìn)程間通信,這里有一個(gè)ActivityManagerService管理JAVA應(yīng)用層所有的service創(chuàng)建與連接(connect),disconnect,所有的Activity也是通過(guò)這個(gè)service來(lái)啟動(dòng),加載的。ActivityManagerService也是加載在Systems Servcie中的。
Android虛擬機(jī)啟動(dòng)之前系統(tǒng)會(huì)先啟動(dòng)service Manager進(jìn)程,service Manager打開(kāi)binder驅(qū)動(dòng),并通知binder kernel驅(qū)動(dòng)程序這個(gè)進(jìn)程將作為System Service Manager,然后該進(jìn)程將進(jìn)入一個(gè)循環(huán),等待處理來(lái)自其他進(jìn)程的數(shù)據(jù)。用戶創(chuàng)建一個(gè)System service后,通過(guò)defaultServiceManager得到一個(gè)遠(yuǎn)程ServiceManager的接口,通過(guò)這個(gè)接口我們可以調(diào)用addService函數(shù)將System service添加到Service Manager進(jìn)程中,然后client可以通過(guò)getService獲取到需要連接的目的Service的IBinder對(duì)象,這個(gè)IBinder是Service的BBinder在binder kernel的一個(gè)參考,所以service IBinder 在binder kernel中不會(huì)存在相同的兩個(gè)IBinder對(duì)象,每一個(gè)Client進(jìn)程同樣需要打開(kāi)Binder驅(qū)動(dòng)程序。對(duì)用戶程序而言,我們獲得這個(gè)對(duì)象就可以通過(guò)binder kernel訪問(wèn)service對(duì)象中的方法。Client與Service在不同的進(jìn)程中,通過(guò)這種方式實(shí)現(xiàn)了類(lèi)似線程間的遷移的通信方式,對(duì)用戶程序而言當(dāng)調(diào)用Service返回的IBinder接口后,訪問(wèn)Service中的方法就如同調(diào)用自己的函數(shù)。
下圖為client與Service建立連接的示意圖
首先從ServiceManager注冊(cè)過(guò)程來(lái)逐步分析上述過(guò)程是如何實(shí)現(xiàn)的。
ServiceMananger進(jìn)程注冊(cè)過(guò)程源碼分析:
Service Manager Process(Service_manager.c):
Service_manager為其他進(jìn)程的Service提供管理,這個(gè)服務(wù)程序必須在Android Runtime起來(lái)之前運(yùn)行,否則Android JAVA Vm ActivityManagerService無(wú)法注冊(cè)。
int main(int argc, char **argv)
{
struct binder_state *bs;
void *svcmgr = BINDER_SERVICE_MANAGER;
bs = binder_open(128*1024); //打開(kāi)/dev/binder 驅(qū)動(dòng)
if (binder_become_context_manager(bs)) {//注冊(cè)為service manager in binder kernel
LOGE("cannot become context manager (%s)\n", strerror(errno));
return -1;
}
svcmgr_handle = svcmgr;
binder_loop(bs, svcmgr_handler);
return 0;
}
首先打開(kāi)binder的驅(qū)動(dòng)程序然后通過(guò)binder_become_context_manager函數(shù)調(diào)用ioctl告訴Binder Kernel驅(qū)動(dòng)程序這是一個(gè)服務(wù)管理進(jìn)程,然后調(diào)用binder_loop等待來(lái)自其他進(jìn)程的數(shù)據(jù)。BINDER_SERVICE_MANAGER是服務(wù)管理進(jìn)程的句柄,它的定義是:
/* the one magic object */
#define BINDER_SERVICE_MANAGER ((void*) 0)
如果客戶端進(jìn)程獲取Service時(shí)所使用的句柄與此不符,Service Manager將不接受Client的請(qǐng)求。客戶端如何設(shè)置這個(gè)句柄在下面會(huì)介紹。
CameraSerivce服務(wù)的注冊(cè)(Main_mediaservice.c)
int main(int argc, char** argv)
{
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
LOGI("ServiceManager: %p", sm.get());
AudioFlinger::instantiate(); //Audio 服務(wù)
MediaPlayerService::instantiate(); //mediaPlayer服務(wù)
CameraService::instantiate(); //Camera 服務(wù)
ProcessState::self()->startThreadPool(); //為進(jìn)程開(kāi)啟緩沖池
IPCThreadState::self()->joinThreadPool(); //將進(jìn)程加入到緩沖池
}
CameraService.cpp
void CameraService::instantiate() {
defaultServiceManager()->addService(
String16("media.camera"), new CameraService());
}
創(chuàng)建CameraService服務(wù)對(duì)象并添加到ServiceManager進(jìn)程中。
client獲取remote IServiceManager IBinder接口:
sp<IServiceManager> defaultServiceManager()
{
if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
{
AutoMutex _l(gDefaultServiceManagerLock);
if (gDefaultServiceManager == NULL) {
gDefaultServiceManager = interface_cast<IServiceManager>(
ProcessState::self()->getContextObject(NULL));
}
}
return gDefaultServiceManager;
}
任何一個(gè)進(jìn)程在第一次調(diào)用defaultServiceManager的時(shí)候gDefaultServiceManager值為Null,所以該進(jìn)程會(huì)通過(guò)ProcessState::self得到ProcessState實(shí)例。ProcessState將打開(kāi)Binder驅(qū)動(dòng)。
ProcessState.cpp
sp<ProcessState> ProcessState::self()
{
if (gProcess != NULL) return gProcess;
AutoMutex _l(gProcessMutex);
if (gProcess == NULL) gProcess = new ProcessState;
return gProcess;
}
ProcessState::ProcessState()
: mDriverFD(open_driver()) //打開(kāi)/dev/binder驅(qū)動(dòng)
...........................
{
}
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller)
{
if (supportsProcesses()) {
return getStrongProxyForHandle(0);
} else {
return getContextObject(String16("default"), caller);
}
}
Android是支持Binder驅(qū)動(dòng)的所以程序會(huì)調(diào)用getStrongProxyForHandle。這里handle為0,正好與Service_manager中的BINDER_SERVICE_MANAGER一致。
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
sp<IBinder> result;
AutoMutex _l(mLock);
handle_entry* e = lookupHandleLocked(handle);
if (e != NULL) {
// We need to create a new BpBinder if there isn't currently one, OR we
// are unable to acquire a weak reference on this current one. See comment
// in getWeakProxyForHandle() for more info about this.
IBinder* b = e->binder; //第一次調(diào)用該函數(shù)b為Null
if (b == NULL || !e->refs->attemptIncWeak(this)) {
b = new BpBinder(handle);
e->binder = b;
if (b) e->refs = b->getWeakRefs();
result = b;
} else {
// This little bit of nastyness is to allow us to add a primary
// reference to the remote proxy when this team doesn't have one
// but another team is sending the handle to us.
result.force_set(b);
e->refs->decWeak(this);
}
}
return result;
}
第一次調(diào)用的時(shí)候b為Null所以會(huì)為b生成一BpBinder對(duì)象:
BpBinder::BpBinder(int32_t handle)
: mHandle(handle)
, mAlive(1)
, mObitsSent(0)
, mObituaries(NULL)
{
LOGV("Creating BpBinder %p handle %d\n", this, mHandle);
extendObjectLifetime(OBJECT_LIFETIME_WEAK);
IPCThreadState::self()->incWeakHandle(handle);
}
void IPCThreadState::incWeakHandle(int32_t handle)
{
LOG_REMOTEREFS("IPCThreadState::incWeakHandle(%d)\n", handle);
mOut.writeInt32(BC_INCREFS);
mOut.writeInt32(handle);
}
getContextObject返回了一個(gè)BpBinder對(duì)象。
interface_cast<IServiceManager>(
ProcessState::self()->getContextObject(NULL));
template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
return INTERFACE::asInterface(obj);
}
將這個(gè)宏擴(kuò)展后最終得到的是:
sp<IServiceManager> IServiceManager::asInterface(const sp<IBinder>& obj)
{
sp<IServiceManager> intr;
if (obj != NULL) {
intr = static_cast<IServiceManager*>(
obj->queryLocalInterface(
IServiceManager::descriptor).get());
if (intr == NULL) {
intr = new BpServiceManager(obj);
}
}
return intr;
}
返回一個(gè)BpServiceManager對(duì)象,這里obj就是前面我們創(chuàng)建的BpBInder對(duì)象。
client獲取Service的遠(yuǎn)程IBinder接口
以CameraService為例(camera.cpp):
const sp<ICameraService>& Camera::getCameraService()
{
Mutex::Autolock _l(mLock);
if (mCameraService.get() == 0) {
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder;
do {
binder = sm->getService(String16("media.camera"));
if (binder != 0)
break;
LOGW("CameraService not published, waiting...");
usleep(500000); // 0.5 s
} while(true);
if (mDeathNotifier == NULL) {
mDeathNotifier = new DeathNotifier();
}
binder->linkToDeath(mDeathNotifier);
mCameraService = interface_cast<ICameraService>(binder);
}
LOGE_IF(mCameraService==0, "no CameraService!?");
return mCameraService;
}
由前面的分析可知sm是BpCameraService對(duì)象
://應(yīng)該為BpServiceManager對(duì)象
virtual sp<IBinder> getService(const String16& name) const
{
unsigned n;
for (n = 0; n < 5; n++){
sp<IBinder> svc = checkService(name);
if (svc != NULL) return svc;
LOGI("Waiting for sevice %s...\n", String8(name).string());
sleep(1);
}
return NULL;
}
virtual sp<IBinder> checkService( const String16& name) const
{
Parcel data, reply;
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
data.writeString16(name);
remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);
return reply.readStrongBinder();
}
這里的remote就是我們前面得到BpBinder對(duì)象。所以checkService將調(diào)用BpBinder中的transact函數(shù):
status_t BpBinder::transact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
// Once a binder has died, it will never come back to life.
if (mAlive) {
status_t status = IPCThreadState::self()->transact(
mHandle, code, data, reply, flags);
if (status == DEAD_OBJECT) mAlive = 0;
return status;
}
return DEAD_OBJECT;
}
mHandle為0,BpBinder繼續(xù)往下調(diào)用IPCThreadState:transact函數(shù)將數(shù)據(jù)發(fā)給與mHandle相關(guān)聯(lián)的Service Manager Process。
status_t IPCThreadState::transact(int32_t handle,
uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags)
{
............................................................
if (err == NO_ERROR) {
LOG_ONEWAY(">>>> SEND from pid %d uid %d %s", getpid(), getuid(),
(flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONE WAY");
err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
}
if (err != NO_ERROR) {
if (reply) reply->setError(err);
return (mLastError = err);
}
if ((flags & TF_ONE_WAY) == 0) {
if (reply) {
err = waitForResponse(reply);
} else {
Parcel fakeReply;
err = waitForResponse(&fakeReply);
}
..............................
return err;
}
通過(guò)writeTransactionData構(gòu)造要發(fā)送的數(shù)據(jù)
status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,
int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)
{
binder_transaction_data tr;
tr.target.handle = handle; //這個(gè)handle將傳遞到service_manager
tr.code = code;
tr.flags = bindrFlags;
。。。。。。。。。。。。。。
}
waitForResponse將調(diào)用talkWithDriver與對(duì)Binder kernel進(jìn)行讀寫(xiě)操作。當(dāng)Binder kernel接收到數(shù)據(jù)后,service_mananger線程的ThreadPool就會(huì)啟動(dòng),service_manager查找到CameraService服務(wù)后調(diào)用binder_send_reply,將返回的數(shù)據(jù)寫(xiě)入Binder kernel,Binder kernel。
status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
{
int32_t cmd;
int32_t err;
while (1) {
if ((err=talkWithDriver()) < NO_ERROR) break;
..............................................
}
status_t IPCThreadState::talkWithDriver(bool doReceive)
{
............................................
#if defined(HAVE_ANDROID_OS)
if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
err = NO_ERROR;
else
err = -errno;
#else
err = INVALID_OPERATION;
#endif
...................................................
}
通過(guò)上面的ioctl系統(tǒng)函數(shù)中BINDER_WRITE_READ對(duì)binder kernel進(jìn)行讀寫(xiě)。
Client A與Binder kernel通信:
if (binder_debug_mask & BINDER_DEBUG_OPEN_CLOSE)
proc = kzalloc(sizeof(*proc), GFP_KERNEL);
if (binder_proc_dir_entry_proc) {
/*printk(KERN_INFO "binder_ioctl: %d:%d %x %lx\n", proc->pid, current->pid, cmd, arg);*/
mutex_lock(&binder_lock);
switch (cmd) {
Int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,void __user *buffer, int size, signed long *consumed)
while (ptr < end && thread->return_error == BR_OK) {
if (copy_from_user(&tr, ptr, sizeof(tr)))
static void
............................................
for (;;) {
bio_init(&reply, rdata, sizeof(rdata), 4);
}
data.cmd_free = BC_FREE_BUFFER;
連接建立后的client連接Service的通信過(guò)程:
mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
status_t IPCThreadState::executeCommand(int32_t cmd)
將調(diào)用CameraService的onTransact函數(shù),CameraService繼承了BBinder。
@Override
總結(jié):
|
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
