Server获得了Service Manager远程接口之后,就要把自己的Service添加到Service Manager中去,然后把自己启动起来,等待Client的请求。
MediaPlayerService 继承了 --> BnMediaPlayerService类(一个Binder Native类,用来处理Client请求) --> BnInterface<IMediaPlayerService>类
BnInterface是一个模板类,它定义在frameworks/base/include/binder/IInterface.h文件中: ------------------------------------------------------------------------------------------------------------------------- template<typename INTERFACE> class BnInterface : public INTERFACE, public BBinder { public: virtual sp<IInterface> queryLocalInterface(const String16& _descriptor); virtual const String16& getInterfaceDescriptor() const; protected: virtual IBinder* onAsBinder(); }; -------------------------------------------------------------------------------------------------------------------------
这里可以看出,BnMediaPlayerService实际是继承了 --> IMediaPlayerService和BBinder类。 IMediaPlayerService和BBinder类又分别继承了IInterface和IBinder类,IInterface和IBinder类又同时继承了RefBase类。
BnMediaPlayerService使用了IPCThreadState接收Client处发送过来的请求, 而IPCThreadState又借助了ProcessState类来与Binder驱动程序交互。
IPCThreadState接收到了Client处的请求后,就会调用BBinder类的transact函数,并传入相关参数, BBinder类的transact函数 最终调用BnMediaPlayerService类的onTransact函数,于是,就开始真正地处理Client的请求了。 ----------------------------------------------------------------------------------------------------------------------------------------------------------
int main(int argc, char** argv) { sp<ProcessState> proc(ProcessState::self()); sp<IServiceManager> sm = defaultServiceManager(); LOGI("ServiceManager: %p", sm.get());
AudioFlinger::instantiate(); MediaPlayerService::instantiate(); // 该函数内部调用addService,把MediaPlayerService信息 add到ServiceManager中 CameraService::instantiate(); AudioPolicyService::instantiate(); ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool(); }
进入到MediaPlayerService::instantiate函数把MediaPlayerService添加到Service Manger中去。这个函数定义在frameworks/base/media/libmediaplayerservice/MediaPlayerService.cpp文件中: void MediaPlayerService::instantiate() { defaultServiceManager()->addService( String16("media.player"), new MediaPlayerService()); } defaultServiceManager返回的实际是一个BpServiceManger类实例, 即: BpServiceManger()->addService( )
-------------------------------------------------------------------------------------------------------------- addService是调用的BpServiceManager的函数。 virtual status_t addService (const String16& name, const sp<IBinder>& service) { Parcel data, reply; // data是发送到BnServiceManager的命令包
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor()); // 再把新service的名字写进去 叫media.player data.writeString16(name);
// 把新服务service (MediaPlayerService) 写到命令中 data.writeStrongBinder(service); //调用remote的transact函数 status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply); return err == NO_ERROR ? reply.readInt32() : err; } -------------------------------------------------------------------------------------------------------------- 这里的Parcel类是用来于序列化进程间通信数据用的。 data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor()); IServiceManager::getInterfaceDescriptor()返回来的是一个字符串,即"android.os.IServiceManager"。
我们看一下Parcel::writeInterfaceToken的实现,位于frameworks/base/libs/binder/Parcel.cpp文件中: status_t Parcel::writeInterfaceToken(const String16& interface) { writeInt32(IPCThreadState::self()->getStrictModePolicy() | STRICT_MODE_PENALTY_GATHER); return writeString16(interface); // 它的作用是写入一个整数和一个字符串到Parcel中去 } ------------------------------------------------------ data.writeString16(name); 这里又是写入一个字符串到Parcel中去,这里的name即是上面传进来的“media.player”字符串。 ------------------------------------------------------ data.writeStrongBinder(service); 这里定义一个Binder对象到Parcel去。 我们重点看一下这个函数的实现,因为它涉及到 进程间传输Binder实体的问题 ,比较复杂,需要重点关注,同时,也是理解Binder机制的一个重点所在。 注意,这里的service参数是一个MediaPlayerService对象。 status_t Parcel::writeStrongBinder(const sp<IBinder>& val) { return flatten_binder(ProcessState::self(), val, this); }
status_t flatten_binder(const sp<ProcessState>& proc, const sp<IBinder>& binder, Parcel* out) { flat_binder_object obj;
obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS; 0x7f 表示处理本Binder实体请求数据包的线程的最低优先级, FLAT_BINDER_FLAG_ACCEPTS_FDS 表示这个Binder实体可以接受文件描述符,Binder实体在收到文件描述符时,就会在本进程中打开这个文件。 传进来的binder即为MediaPlayerService::instantiate函数中new出来的MediaPlayerService实例,因此,不为空。 又由于MediaPlayerService继承自BBinder类,它是一个本地Binder实体,因此binder->localBinder返回一个BBinder指针,而且肯定不为空,于是执行下面语句: if(binder != NULL) { IBinder *local = binder->localBinder(); if (!local) { BpBinder *proxy = binder->remoteBinder(); if (proxy == NULL) { LOGE("null proxy"); } const int32_t handle = proxy ? proxy->handle() : 0; obj.type = BINDER_TYPE_HANDLE; obj.handle = handle; obj.cookie = NULL; } else { obj.type = BINDER_TYPE_BINDER; obj.binder = local->getWeakRefs(); obj.cookie = local; } } else { obj.type = BINDER_TYPE_BINDER; obj.binder = NULL; obj.cookie = NULL; } return finish_flatten_binder(binder, obj, out); }
后记: 有关binder机制的分析已整理为pdf文档: http://wenku.baidu.com/view/4e9a5763f5335a8102d220bf.html
|