client获取Service的远程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对象: ??? 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对象。所以checkService将调用BpBinder中的transact函数: 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继续往下调用IPCThreadState:transact函数将数据发给与mHandle相关联的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; } 通过writeTransactionData构造要发送的数据 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; //这个handle将传递到service_manager ??? tr.code = code; ??? tr.flags = bindrFlags; 。。。。。。。。。。。。。。 } waitForResponse将调用talkWithDriver与对Binder kernel进行读写操作。当Binder kernel接收到数据后,service_mananger线程的ThreadPool就会启动,service_manager查找到 CameraService服务后调用binder_send_reply,将返回的数据写入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 ................................................... } 通过上面的ioctl系统函数中BINDER_WRITE_READ对binder kernel进行读写。
详细解决方案
Android IPC 通讯机制源码分析【上】
热度:322 发布时间:2016-05-01 16:23:25.0
相关解决方案
- android 读取byte[]中的元素解决方案
- android 标题栏兑现方式
- android 中Activity向BroadcastReceiver发送数据,该怎么解决
- Android 4.0 为什么模拟器老是提示小弟我谷歌拼音输入法已停止
- android:getSharedPreferences() 这是哪个类的方法解决思路
- android 怎么判断一个程序是否联网
- android 大量数据按周分组,该如何解决
- android RadioButton如何设置默认选中
- ksoap2-android-这个包,连接webService怎么设置超时
- android 怎么重新设置锚点
- android UI界面设计解决方案
- android 图片对象获取的有关问题
- android 怎么调用淘宝支付宝接口
- Android 沿袭InputMethodService自定义输入法
- android 关于服务连接的疑义
- android 两个activity如何通信
- android 怎么实现对view的放大和缩小
- android 教程解决方法
- android ID,该如何处理
- 准备复习2-3个月,看java+android,请问有经验者,怎么看效果最好》
- android UI线程与AsyncTask的有关问题
- android(java)中的java.net能不能和c#的system.net.sockets进行tcp通信,该如何解决
- android ListView 中的onItemClick Intent 没法跳转
- android(java) 中文乱码的有关问题
- c#c++,android,ios(iphone),php,java视屏课程 散分
- android Post文件到ASP.NET的有关问题,能收到参数收不到文件
- RIM 替 Android 开发者提供免费的 PlayBook!2月13日前
- android 动态设立控件高度
- Android test project 编译方法
- android -相机使用教程(1)解决方法