服务的注册
来源:互联网 发布:乐乎 爱唐晶的小海胆 编辑:程序博客网 时间:2024/05/18 01:23
Server获得了Service Manager远程接口之后,就要把自己的Service添加到Service Manager中去,然后把自己启动起来,等待Client的请求。本文将通过分析说明Server的启动过程是怎么样的。我们通过Android Binder实列篇中的实列来说明下服务启动的整个过程。
类的继承关系图:
从上图可以明显看出BnShareBuffer实际是继承了IShareBuffer和BBinder类。IShareBuffer和BBinder类又分别继承了IInterface和IBinder类,IInterface和IBinder类又同时继承了RefBase类。
实际上,BnShareBuffer并不是直接接收到Client处发送过来的请求,而是使用了IPCThreadState接收Client处发送过来的请求,而IPCThreadState又借助了ProcessState类来与Binder驱动程序交互。IPCThreadState接收到了Client处的请求后,就会调用BBinder类的transact函数,并传入相关参数,BBinder类的transact函数最终调用BnShareBuffer类的onTransact函数,于是,就开始真正地处理Client的请求了。
源码中通过:
SharedBufferService::instantiate();//add to the systemServerstatic void instantiate() { defaultServiceManager()->addService(String16(SHARED_BUFFER), new SharedBufferService()); }
前面分析过defaultServiceManager()是如何获取systemServices远程代理的。本文主要分析addService这个过程是如何一步一步在系统中添加服务的。
BpServiceManger::addService的实现在framworks/native/libs/binder/IServiceManager.cpp中。
class BpServiceManager : public BpInterface<IServiceManager>{public: BpServiceManager(const sp<IBinder>& impl) : BpInterface<IServiceManager>(impl) { } .... virtual status_t addService(const String16& name, const sp<IBinder>& service, bool allowIsolated) { Parcel data, reply; unsigned n; status_t err; /* *写入数据到parcel中,序列化数据 */ data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor()); data.writeString16(name); //写入一个binder引用 data.writeStrongBinder(service); data.writeInt32(allowIsolated ? 1 : 0); for (n = 1; n <= 5; n++) { err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply); if (err == -EPIPE) { ALOGI("%s is waiting for serviceManager... (retry %d)\n", String8(name).string(), n); sleep(1); } else { break; } } return err == NO_ERROR ? reply.readExceptionCode() : err; } ....};
下面我们看看data.writeStrongBinder(service); 这个是服务注册的关键之所在!
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; //内核中传输binder的结构 /* *0x7f表示处理本Binder实体请求数据包的线程的最低优先级,FLAT_BINDER_FLAG_ACCEPTS_FDS *表示这个Binder实体可以接受文件描述符,Binder实体在收到文件描述符时,就会在本进程中打开这个文件。 */ obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS; if (binder != NULL) { //binder为 新建立的SharedBufferService一定不为空 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写入Parcel中}
inline static status_t finish_flatten_binder( const sp<IBinder>& binder, const flat_binder_object& flat, Parcel* out) { return out->writeObject(flat, false); //最终调用writeObject写入一个对像}
接下来status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
这里的remote成员函数来自于BpRefBase类,它返回一个BpBinder指针。
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; }
最终调用IPCThreadState::transact进执行实际的操作。这里的mHandle一定为0,因为这里表示的是Service Manager远程接口,它的句柄值一定是0,code为ADD_SERVICE_TRANSACTION。
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; IF_LOG_TRANSACTIONS() { TextOutput::Bundle _b(alog); alog << "BC_TRANSACTION thr " << (void*)pthread_self() << " / hand " << handle << " / code " << TypeCode(code) << ": " << indent << data << dedent << endl; } 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 0 if (code == 4) { // relayout LOGI(">>>>>> CALLING transaction 4"); } else { LOGI(">>>>>> CALLING transaction %d", code); } #endif if (reply) { err = waitForResponse(reply); } else { Parcel fakeReply; err = waitForResponse(&fakeReply); } #if 0 if (code == 4) { // relayout LOGI("<<<<<< RETURNING transaction 4"); } else { LOGI("<<<<<< RETURNING transaction %d", code); } #endif IF_LOG_TRANSACTIONS() { TextOutput::Bundle _b(alog); alog << "BR_REPLY thr " << (void*)pthread_self() << " / hand " << handle << ": "; if (reply) alog << indent << *reply << dedent << endl; else alog << "(none requested)" << endl; } } else { err = waitForResponse(NULL, NULL); } return err; }
最终通过waitForResponse ==>talkWithDriver将注册信息写入驱动。最终会唤醒在等待数据的serviceManager线程,serviceManager线程接收到数据后,会对其进行解析并添加服务到管理的服务列表中!整个过程比较复杂,在老罗的博客中有较详细的讲述!
Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析
- 服务的注册
- Spark的注册服务
- 获取注册的服务
- 注册管理服务的设计
- 重新注册sqlserver2008的服务
- ATL 服务注册的具体操作
- 注册服务、删除服务的cmd命令
- linux的chkconfig服务注册(服务注册脚本说明)
- 注册服务
- 注册服务
- 注册服务
- 想要好的域名注册服务?来google注册吧
- 如何删除系统已注册的服务
- 注册带参数的memcache服务
- delphi注册服务(别人的)
- 将一个服务程序注册的代码
- 在注册表里删除没用的服务
- windows 服务的注册与缷载
- 实用小技巧之-textView内容高度的获取
- 欢迎使用CSDN-markdown编辑器
- centos6 nginx 安装PHP
- 利用Struts标签开发jsp页面表单提示java.lang.NullPointerException: Module 'null' not found.
- 项目编译后dll文件调用出错
- 服务的注册
- 存储过程中的select语句赋值错误原因
- Java多线程概念总结
- C++显式实例化
- 设置Tomcat控制台日志打印的级别?如何设置?
- PHP 插入时间戳进mysql数据库问题
- 有线无线深度融合,极致简化管理
- Fedora如何实现自动登录
- 类重定义错误 error C2011: “complex”:“class”类型重定义