前面一節我們分析了Binder通信相關的兩個重要類:ProcessState 和 IPCThreadState。ProcessState負責打開Binder
驅動,每個進程只有一個。而 IPCThreadState負責提供與Binder通信相關的接口,每個線程有一個。下面我們通過具體
示例MediaPlayerService來分析我們應用程序中怎么通過Binder通信的。
frameworks/base/media/mediaserver/main_mediaserver.cpp
~~~
int main(int argc, char*argv[])
{
sp<ProcessState> proc(ProcessState)::self(); // 獲得ProcessState在構造函數中打開binder驅動
sp<IServiceManager> sm = defaultServiceManager();
MediaPlayService::instantiate();
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}
~~~
1)獲得ServiceManager的代理BpServiceManager
~~~
sp<IServiceManager> sm = defaultServiceManager();
sp<IServiceManager> defaultServiceManager()
{
if(gDefaultServiceManager != NULL) return gDefaultServiceManager;
{
AutoMutex -l(gDefaultServiceManagerLock);
if(gDefaultServiceManager == NULL)
gDefaultServiceManager = interface_cast<IServiceManager>(
ProcessState::self()->getContextObject(NULL));
}
return gDefaultServiceManager;
}
~~~
這里又是一個單例模式,每個進程只需要一個BpServiceManager代理,通過interface_cast獲得。
首先看看ProcessState::self()->getContextObject(NULL)
~~~
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_entry *e = lookupHandleLocked(handle);
if( e != NULL) {
IBinder* b = e->binder;
if(b == NULL || !e->refs->attemptIncWeak(this)) {
b = new BpBinder(handle);
e->binder = b;
if(b) e->refs = b->getWeakRefs();
result = b;
}else{
result.force_set(b);
e->refs->decWeak(this);
}
}
return result;
}
struct handle_entry{
IBinder* binder;
RefBase::weakref_type* refs;
}
~~~
ProcessState::handle_entry* ProcessState::lookupHandleLocked()從數組mHandleToObject里面根據handle索引,查找
一個handle_entry結構體。然后根據傳入的句柄handle這里為0,表示ServiceManager,new一個BpBinder
所以現在相當于:
gDefaultServiceManager = interface_cast<IServiceManager>(new BpBinder(0));
現在我們看看interface_cast是什么?
~~~
frameworks/base/include/binder/IInterface.h
template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
return INTERFACE::asInterface(obj);
}
等價于:
inline sp<IServiceManager> interface_cast(const sp<IBinder>& obj)
{
return IServiceManager::asInterface(obj);
}
繼續我們跟到IServiceManager里面去:
frameworks/base/include/binder/IServiceManager.h
class IServiceManager:public IInterface
{
public:
DECLARE_META_INTERFACE(ServiceManager);// MLGB的又是宏!!!
virtual status_t addService(const String16& name, const sp<IBinder>& service) = 0;
virtual sp<IBinder> getService(const String16& name) const = 0;
}
#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();
替換之后就是:
static const android::String16 descriptor;
static android::sp<IServiceManager> asInterface(
const android::sp<android::IBinder>& obj);
virtual const android::String16& getInterfaceDescriptor() const;
IServiceManager();
virtual !IServiceManager();
都是一些函數聲明,既然有聲明的地方,肯定有實現的地方了。
#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \
const android::String16 I##INTERFACE::descriptor(NAME); \
const android::String16& \
I##INTERFACE::getInterfaceDescriptor() const { \
return I##INTERFACE::descriptor; \
} \
android::sp<I##INTERFACE> I##INTERFACE::asInterface( \
const android::sp<android::IBinder>& obj) \
{ \
android::sp<I##INTERFACE> intr; \
if (obj != NULL) { \
intr = static_cast<I##INTERFACE*>( \
obj->queryLocalInterface( \
I##INTERFACE::descriptor).get()); \
if (intr == NULL) { \
intr = new Bp##INTERFACE(obj); \
} \
} \
return intr; \
} \
I##INTERFACE::I##INTERFACE() { } \
I##INTERFACE::~I##INTERFACE() { }
繼續替換:
{
const android::String16 IServiceManager::descriptor(NAME);
const android::String16&
IServiceManager::getInterfaceDescriptor() const {
return IServiceManager::descriptor;
}
android::sp<IServiceManager> IServiceManager::asInterface(
const android::sp<android::IBinder>& obj) // 參數為new BpBinder(0)
{
android::sp<IServiceManager> intr;
if (obj != NULL) {
intr = static_cast<IServiceManager*>(
obj->queryLocalInterface(
IServiceManager::descriptor).get());
if (intr == NULL) {
intr = new BpServiceManager(obj); // 原來在這里new 了一個BpServiceManager對象
}
}
return intr;
}
IServiceManager::IServiceManager() { }
IServiceManager::~IServiceManager() { }
}
~~~
總結:根據句柄handle 0 創建一個new BpBinder(0),根據這個BpBinder創建了一個BpServiceManager代理。
下面來看看BpServiceManager代理:
~~~
class BpServiceManager : public BpInterface<IServiceManager>
{
public:
BpServiceManager(const sp<IBinder>& impl) : BpInterface<IServiceManager>(iml)
{}
}
~~~
這里BpInterface是一個模板類,表示這里BpServiceManager同時繼承與BpInterface和IServiceManager類
~~~
template<typename INTERFACE>
class BpInterface : public INTERFACE, public BpRefBase
{
public: BpInterface(const sp<IBinder>& remote);
...
}
調用了基類BpInterface構造函數:
BpInterface<IServiceManager>::BpInterace(const sp<IBinder>& remote) : BpRefBase(remote)
{}
//這里的remote就是剛剛的new BpBinder(0)
BpRefBase::BpRefBase(const sp<IBinder>& o) : mRemote(o.get()),mRefs(NULL), mState(0)
{
}
~~~
2)添加服務 MediaPlayerService::instantiate();
~~~
frameworks/base/media/libmediaplayerservice/ibMediaPlayerService.cpp
void MediaPlayerService::instantiate()
{
defaultServiceManager()->addService(String16("media.player"), new MediaPlayerService);
}
~~~
defaultServiceManager()返回的是剛創建的BpServiceManager,調用add函數。
BpMediaPlayService作為服務代理端,那么BnMediaPlayerService一定是實現端,MediaPlayerService繼承于
BnMediaPlayerService,實現了真正的業務函數。
來看看BpServiceManager的addService()函數:
~~~
virtual status_t addService(const String16& name, const sp<IBinder>& service)
{
Parcel data, reply;
data.writeInterfaceToken(IServiceManager.getInterfaceDescriptor()); // android.os.IServiceManager
data.writeString16(name); // media.player
data.writeStrongBinder(service); // 也就是MediaPlayerService
status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
return err == NO_ERROR ? reply.readInt32() : err;
}
~~~
這里remote()就是前面創建的BpBinder(0)對象。
~~~
status_t BpBinder::transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
IPCThreadState::self()->transact(mHandle, code, data, reply, flags);
}
status_t IPCThreadState::transact(int32_t handle, uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
// 發送ADD_SERVICE_TRANSACTION請求
writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
if(reply) // 等待響應
waitForResponse(NULL, reply);
}
status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags, int32_t handle,
uint32_t code, const Parcel& data, status_t *statusBuffer)
{
// cmd BC_TRANSACTION 應用程序向BINDER發送的命令
binder_transaction_data tr;
tr.target.handle = handle; // 0
tr.code = code; // ADD_SERVICE_TRANSACTION
tr.flags = binderFlags;
// 把命令和數據一起發送到 Parcel mOut中
mOut.writeInt32(cmd);
mOut.write(&tr, sizeof(tr));
}
status_t IPCThreadState::waitForResponse(Parcel* reply, status_t *acquireResult)
{
int32_t cmd;
while(1)
talkWithDriver();
cmd = mIn.readInt32();
switch(cmd) {
case BR_TRANSACTION_COMPLETE:
...
break;
}
{
return err;
}
status_t IPCThreadState::talkWithDriver(bool doReceive)
{
binder_write_read bwr;
bwr.write_size = outAvail;
bwr.write_buf = (long unsigned int)mOut.data(); // 寫入mOut的數據
bwr.read_size = mIn.dataCapacity;
bwr.read_buffer = (long unsigned int)mIn.data();
ioctl(mProcess->mDriverFD, BINDER_WRITE_READm &bwr); // 把mOut寫到Binder,并讀取mIn數據
}
~~~
3)IPCThreadState::joinThreadPool(), ProcessState::self()->startThreadPool()
進入線程循環talkWithDriver 等待客戶端Client請求,從Binder讀取命令請求進行處理。
到現在為止MediaPlayerService的服務端已經向服務總管ServiceManager注冊了,下面我們看看客戶端是如何獲得服務的代理并和服務端通信的。
我們以MediaPlayer的業務函數decode解析播放一個URL為例
~~~
sp<IMemory> MediaPlayer::decode(const char*url, uint32_t *pSampleRate, ...)
{
sp<IMemory> p;
const sp<IMediaPlayerService>& service = getMediaPlayerService(); // 獲得BpMediaPlayerSerivce代理
if(service != 0)
p = service->decode(url, ....);
return p;
}
~~~
這里我們主要分析getMediaPlayerService,客戶端是如何向ServiceManager總管查詢服務并獲得代理的。
~~~
sp<IMediaPlayerService>& IMediaDeathNotifier::getMediaPlayerService()
{
sp<IServiceManager> sm = defaultServiceManager(); // 生成一個BpServiceManager代理對象
sp<IBinder> binder;
do {
binder = sm->getService(String16("media.player"));
if(binder != 0)
break;
usleep(500000)
} while(true);
sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);
return sMediaPlayerService;
}
~~~
1)首先獲得BpServiceManager的代理,然后調用getService()函數向服務總管ServiceManager查詢服務。
frameworks/base/libs/binder/IServiceManager.cpp
~~~
class BpServiceManager : public BpInterface<IServiceManager>
{
public:
virtual sp<IBinder> getService(const String16& name) const
{
for(n = 0; n < 5; n++) {
sp<IBinder> svc = checkService(name); // 調用checkService函數
if(svc != NULL) return svc;
sleep(1);
}
return NULL;
}
virtual sp<IBinder> checkService(const String16& name) const
{
Parcel data, reply;
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
// 首先調用data.writeInt32(IPCThreadState::self()->getStrictModePolicy())
// 然后再寫入android.os.IServiceManager
data.writeString16(name); // 寫入 media.player
remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);
return reply.readStrongBinder();
}
}
~~~
這里首先將請求打包成Parcel各式,然后調用remote()->transact()函數,前面我們分析過BpServiceManager::remote()返回
的就是前面new BpBinder(0)對應句柄為ServiceManager。繼續去BpBinder中尋找實現代碼:
frameworks/base/libs/binder/BpBinder.cpp
~~~
status_t BpBinder::transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
IPCThreadState::self()->transact(mHandle, code, data, reply, flags);
}
~~~
最后調用的IPCThreadState的transact()函數,IPCThreadState是專門提供通過Binder進程間通信的接口的。
~~~
status_t IPCTheadState::transact(int32_t handle, uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
// 填充binder_transaction_data 結構體,寫入到mOut中去
writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
// 調用talkWithDriver() 將mOut寫到Binder驅動,并從Binder驅動讀取mIn數據
waitForResponse(reply);
}
~~~
首先通過writeTransactionData函數來填充mOut結構體,mOut里面內容為:
mOut.writeInt32(BC_TRANSACTION);
mOut.write(&tr, sizeof(tr));
這里binder_transaction_data tr內容為:
tr.target.handle = 0;?// 表面是發往ServiceManager的
tr.code = CHECK_SERVICE_TRANSACTION;
tr.flags = 0;
tr.data內容為:
data.writeInt32(IPCThreadState::self()->getStrictModePolicy() | STRICT_MODE_PENALTY_GATHER);
data.writeString16("android.os.IServiceManager");
data.writeString16("media.player");
根據前面Android開發之ServiceManager一章中我們分析,svcmgr_handler處理從句柄為0的Binder的請求:
strict_policy = bio_get_string32();
s = bio_get_string16();?// 就是上面的android.os.IServiceManager
s = bio_get_string16();?// 就是上面的 media.player
根據media.player遍歷全局鏈表svclist找到相應的服務,調用bio_put_ref(reply, ptr) 返回目標Binder實體。
這個waitForResponse()函數是關鍵:
~~~
status_t IPCThreadState::waitForResponse(Parcel* reply)
{
while(1) {
talkWithDriver(); // 輸入mOut 輸出mIn
cmd = mIn.readInt32();
switch(cmd) {
case BR_REPLY:
{
binder_transaction_data tr;
mIn.read(&tr, sizeof(tr));
if(reply) {
reply->ipcSetDataReference(reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
tr.data.size, reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
tr.offsets_size/sizeof(sizt_t), freeBuffer, this);
} else {
err = *static_cast<const status_t*>(tr.data.ptr.buffer);
freeBuffer(NULL, reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
tr.data.size, reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
tr.offsets_size/sizeof(sizt_t), freeBuffer, this)
}
}
}
}
}
最后返回的是:return reply.readStrongBinder();進入到Parcel的readStrongBinder()函數
sp<IBinder> Parcel::readStrongBinder() const
{
sp<IBinder> val;
unflatten_binder(ProcessState::self(), *this, &val);
return val;
}
status_t unflatten_binder(const sp<ProcessState>& proc, const Parcel& in, sp<IBinder>* out)
{
const flat_binder_object* flat = in.readObject(false);
if(flat) {
switch(flat->type) {
case BINDER_TYPE_BINDER:
*out = static_cast<IBinder*>(flat->cookie);
return finish_unflatten_binder(NULL, *flat, in);
case BINDER_TYPE_HANDLE:
*out = proc->getStrongProxyForHandle(flat->handle);
return finish_unflatten_binder(static_cast<BpBinder*>(out->get()), *flat, in);
}
}
}
~~~
這里flat->type是BINDER_TYPE_HANDLE,所以調用ProcessState::getStrongProxyForHandle()函數
~~~
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
sp<IBinder> result;
handle_entry* e = lookupHandleLocked(handle);
if(e != NULL) {
IBinder* b = e->binder;
if(b == NULL || !e->refs->attemptIncWeak(this)) {
b = new BpBinder(handle);
e->binder = b;
if( b ) e->refs = e->getWeakRefs();
result = b;
} else {
result.force_set(b);
e->refs->decWeak(this);
}
}
return result;
}
~~~
這里的handle就是ServiceManager內維護的MediaPlayerService對應的Binder句柄,這個ProcessState根據這個句柄
new 了一個BpBinder,并將其保存起來,這樣下次需要從ServiceManager請求獲取到相同句柄的時候就可以直接返回了。
最后根據這個返回的BpBinder獲得MediaPlayerService的代理:
sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);
根據前面ServiceManager一樣,最后調用的是IMediaPlayerService的asInterface()宏函數
~~~
android::sp<IMediaPlayerService> IMediaPlayerService::asInterface(const android::sp<android::IBinder>& obj)
{
android::sp<IMediaPlayerService> intr;
if(obj != NULL ) {
intr = static_cast<IMediaPlayerService>(
obj->queryLocalInterface(IMediaPlayerService::descriptor).get);
if (intr == NULL) {
intr = new BpMediaPlayerService(obj);
}
}
return intr;
}
~~~
這樣我就獲得了一個代理BpMediaPlayerService對象,它的remote()為BpBinder(handle),這個handle就是向服務總共ServiceManager
查詢到的MediaPlayerService對應的Binder句柄。
下一章我們分析,客戶端如何通過這個BpServiceManager代理對象調用服務端MediaPlayerService的業務函數的?
- 前言
- Android開發之serviceManager分析
- Android啟動之init.c文件main函數分析
- Android開發之ProcessState和IPCThreadState類分析
- Android開發之MediaPlayerService服務詳解(一)
- Android系統五大布局詳解Layout
- Android四大組件之Content Provider
- Android四大組件之Service
- Android四大組件之BroadcastReceiver
- Android系統中的消息處理Looper、Handler、Message
- Android EditText/TextView使用SpannableString顯示復合文本
- Android關鍵資源詳解
- Android常用適配器分析(如何制作簡易Launcher)
- Android常用列表控件