做网站 怎么赚钱吗发布软文
2026/4/18 10:23:06 网站建设 项目流程
做网站 怎么赚钱吗,发布软文,购彩网站建设,wordpress 不显示ipAndroid 系统的 Binder 通信体系中#xff0c;ServiceManager#xff08;简称 SM#xff09;是无可替代的核心枢纽 —— 它是所有 Binder 服务的 “注册表”#xff0c;负责系统 / 应用服务的注册#xff08;addService#xff09;、查询#xff08;getService#xff…Android 系统的 Binder 通信体系中ServiceManager简称 SM是无可替代的核心枢纽 —— 它是所有 Binder 服务的 “注册表”负责系统 / 应用服务的注册addService、查询getService、删除等核心操作。与普通 Android 服务不同SM 的设计极度精简且特殊摒弃了常规的 Binder 线程池仅通过单线程 Looper 的方式完成与 Binder 驱动的交互。本文将基于 Android 原生源码深度解析 SM 的核心实现逻辑并通过 SurfaceFlingerSF注册到 SM 的完整链路直观展示 Binder 通信的全过程。一、SM 的核心定位与设计特点1. 核心定位SM 是 Android 系统级的 “服务注册表”所有想要通过 Binder 提供服务的组件如 ActivityManagerService、WindowManagerService、SurfaceFlinger都必须先向 SM 注册而想要使用服务的客户端也必须先通过 SM 查询到对应的服务 Binder 对象才能发起跨进程调用。2. 关键设计特点功能单一性仅聚焦服务注册 / 查询 / 删除核心逻辑无多余业务逻辑无 Binder 线程池普通 Android 服务通过 Binder 线程池处理多客户端请求而 SM 仅用 1 个主线程Looper 驱动交互直接监听 Binder 驱动的文件描述符FD通过 Looper 事件循环处理驱动命令Binder 上下文管理器向 Binder 驱动声明自己是 “上下文管理器”成为 Binder 通信的根节点。二、SM 的启动流程main.cpp 核心逻辑SM 的入口位于native\cmds\servicemanager\main.cpp其启动流程是理解 SM 的关键核心步骤如下int main(int argc, char** argv) { // 1. 初始化Binder驱动关联禁用线程池 const char* driver /dev/binder; spProcessState ps ProcessState::initWithDriver(driver); ps-setThreadPoolMaxThreadCount(0); // 核心禁用Binder线程池 ps-setCallRestriction(ProcessState::CallRestriction::FATAL_IF_NOT_ONEWAY); // 2. 创建SM实例并自注册将自己注册为manager服务 spServiceManager manager spServiceManager::make(std::make_uniqueAccess()); if (!manager-addService(manager, manager, false, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()) { LOG(ERROR) Could not self register servicemanager; } // 3. 设置为Binder上下文管理器SM专属标识 IPCThreadState::self()-setTheContextObject(manager); ps-becomeContextManager(); // 4. 初始化Looper注册Binder驱动FD和定时器FD spLooper looper Looper::prepare(false /*allowNonCallbacks*/); BinderCallback::setupTo(looper); // 注册Binder驱动FD ClientCallbackCallback::setupTo(looper, manager); // 注册定时器FD // 5. 进入Looper无限循环监听并处理事件 while(true) { looper-pollAll(-1); } return EXIT_FAILURE; }关键步骤解析禁用 Binder 线程池setThreadPoolMaxThreadCount(0)通过ioctl告知 Binder 驱动SM 不需要线程池所有请求由主线程处理自注册SM 将自身注册为名为 “manager” 的服务确保其他组件能查询到 SM 本身成为上下文管理器becomeContextManager()通过ioctl(BINDER_SET_CONTEXT_MGR_EXT)向驱动声明身份SM 的 Binder 句柄固定为 0是 Binder 通信的根Looper 事件循环SM 的主线程通过looper-pollAll(-1)进入无限循环等待 Binder 驱动或定时器的事件触发。三、Binder 驱动事件处理BinderCallbackSM 通过BinderCallback将 Binder 驱动的 FD 注册到 Looper实现 “驱动有命令时主动回调” 的机制核心代码如下class BinderCallback : public LooperCallback { public: static spBinderCallback setupTo(const spLooper looper) { spBinderCallback cb spBinderCallback::make(); // 1. 获取Binder驱动FD并设置为轮询模式 int binder_fd -1; IPCThreadState::self()-setupPolling(binder_fd); // 2. 将FD注册到Looper监听EVENT_INPUT驱动有数据/命令时触发 int ret looper-addFd(binder_fd, Looper::POLL_CALLBACK, Looper::EVENT_INPUT, cb, nullptr); LOG_ALWAYS_FATAL_IF(ret ! 1, Failed to add binder FD to Looper); return cb; } // 3. 驱动事件回调处理Binder命令 int handleEvent(int /* fd */, int /* events */, void* /* data */) override { IPCThreadState::self()-handlePolledCommands(); // 核心处理驱动命令 return 1; // 持续监听 } };特殊逻辑SM 的 Binder 调用路由普通服务的 Binder 调用会通过tr.target.ptr找到对应的 BBinder但 SM 作为上下文管理器tr.target.ptr为 0直接调用预先设置的the_context_object即 SM 自身// IPCThreadState::executeCommand 中 BR_TRANSACTION 分支 if (tr.target.ptr) { // 普通服务通过ptr找到BBinder error reinterpret_castBBinder*(tr.cookie)-transact(...); } else { // SM专属直接调用上下文对象SM的transact error the_context_object-transact(tr.code, buffer, reply, tr.flags); }四、客户端连接状态检测ClientCallbackCallbackSM 通过 5 秒定时器周期性检测服务的客户端连接状态核心功能由ClientCallbackCallback实现class ClientCallbackCallback : public LooperCallback { public: static spClientCallbackCallback setupTo(const spLooper looper, const spServiceManager manager) { spClientCallbackCallback cb spClientCallbackCallback::make(manager); // 1. 创建定时器FD5秒周期 int fdTimer timerfd_create(CLOCK_MONOTONIC, 0); itimerspec timespec { .it_interval {5, 0}, // 周期5秒 .it_value {5, 0}, // 首次触发5秒后 }; timerfd_settime(fdTimer, 0, timespec, nullptr); // 2. 将定时器FD注册到Looper looper-addFd(fdTimer, Looper::POLL_CALLBACK, Looper::EVENT_INPUT, cb, nullptr); return cb; } // 3. 定时器回调检测客户端连接状态 int handleEvent(int fd, int /*events*/, void* /*data*/) override { uint64_t expirations; read(fd, expirations, sizeof(expirations)); // 读取定时器事件 mManager-handleClientCallbacks(); // 核心检测客户端连接状态 return 1; } };核心作用handleClientCallbacks()会遍历 SM 中注册的所有服务检测每个服务的客户端连接是否活跃若状态发生变化如客户端断开会主动通知服务端保证服务能及时清理无效连接。五、SM 的核心功能实现AIDL 与 ServiceManager 类SM 的核心功能addService/getService 等通过 AIDL 定义并由ServiceManager类实现具体逻辑。1. AIDL 生成的 BnServiceManagerIServiceManager.aidl经编译后生成BnServiceManager服务端和BpServiceManager客户端其中BnServiceManager负责将 Binder 命令转换为具体方法调用// BnServiceManager::onTransact 核心逻辑 status_t BnServiceManager::onTransact(uint32_t _aidl_code, const Parcel _aidl_data, Parcel* _aidl_reply, uint32_t _aidl_flags) { switch (_aidl_code) { case TRANSACTION_getService: // getService命令 ::std::string in_name; _aidl_data.readUtf8FromUtf16(in_name); // 调用SM的getService方法 binder::Status _aidl_status(getService(in_name, _aidl_return)); _aidl_reply-writeStrongBinder(_aidl_return); // 返回服务Binder对象 break; case TRANSACTION_addService: // addService命令 // 同理解析参数调用addService方法 break; } return OK; }2. 具体功能实现ServiceManager 类ServiceManager类是 SM 核心功能的真正执行者继承自IServiceManager实现了所有服务管理逻辑// ServiceManager::getService 核心实现 Status ServiceManager::getService(const std::string name, spIBinder* outBinder) { *outBinder tryGetService(name, true); // 查询服务注册表返回Binder对象 return Status::ok(); }六、完整 Binder 链路实例SurfaceFlinger 注册到 SM 的过程为了更直观理解 SM 的工作机制我们以SurfaceFlingerSF注册到 SM的完整流程为例梳理从客户端发起请求到 SM 完成服务注册的全 Binder 链路保留关键代码和文件路径步骤 1SF 发起注册请求客户端入口SurfaceFlinger 在启动时会调用 SM 的addService方法将自身注册到 SM// main_surfaceflinger.cpp spIServiceManager sm(defaultServiceManager()); sm-addService(String16(SurfaceFlinger::getServiceName()), flinger, false, IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO);步骤 2ServiceManagerShim 层封装适配层请求先经过ServiceManagerShim做参数适配// native\libs\binder\IServiceManager.cpp status_t ServiceManagerShim::addService(const String16 name, const spIBinder service, bool allowIsolated, int dumpsysPriority) { Status status mTheRealServiceManager-addService( String8(name).c_str(), service, allowIsolated, dumpsysPriority); return status.exceptionCode(); }步骤 3BpServiceManager 发起 Binder 跨进程调用AIDL 工具生成的BpServiceManager客户端代理会通过remote()-transact发起跨进程调用BnServiceManager 和BpServiceManager 不是在framework 源码里的 是aidl工具编译的时候生成的frameworks\native\libs\binder\aidl\android\os\IServiceManager.aidl// android/os/IServiceManager.cpp (AIDL工具生成) ::android::binder::Status BpServiceManager::addService(const ::std::string name, const ::android::sp::android::IBinder service, bool allowIsolated, int32_t dumpPriority) { _aidl_ret_status remote()-transact(BnServiceManager::TRANSACTION_addService, _aidl_data, _aidl_reply, 0); }步骤 4BpBinder 封装 Binder 调用参数BpBinder作为客户端 Binder 代理的核心会将调用参数封装并交给IPCThreadState处理代码位于native\libs\binder\BpBinder.cpp// native\libs\binder\BpBinder.cpp status_t BpBinder::transact( uint32_t code, const Parcel data, Parcel* reply, uint32_t flags) { // SM的Binder句柄固定为0驱动会根据handle转发数据到SM进程 status IPCThreadState::self()-transact(binderHandle(), code, data, reply, flags); }步骤 5IPCThreadState 与 Binder 驱动交互IPCThreadState负责将调用数据写入 Binder 驱动并等待响应代码位于native\libs\binder\IPCThreadState.cpp// native\libs\binder\IPCThreadState.cpp status_t IPCThreadState::transact(int32_t handle, uint32_t code, const Parcel data, Parcel* reply, uint32_t flags) { writeTransactionData(BC_TRANSACTION, flags, handle, code, data, nullptr); waitForResponse(reply); } status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult) { while (1) { if ((errtalkWithDriver()) NO_ERROR) break; if (mIn.dataAvail() 0) continue; cmd (uint32_t)mIn.readInt32(); switch (cmd) { case BR_REPLY: // 接收SM的响应 { binder_transaction_data tr; err mIn.read(tr, sizeof(tr)); if (reply) { if ((tr.flags TF_STATUS_CODE) 0) { reply-ipcSetDataReference( reinterpret_castconst uint8_t*(tr.data.ptr.buffer), tr.data_size, reinterpret_castconst binder_size_t*(tr.data.ptr.offsets), tr.offsets_size/sizeof(binder_size_t), freeBuffer); } } } } } status_t IPCThreadState::talkWithDriver(bool doReceive) { binder_write_read bwr; bwr.write_size outAvail; bwr.write_buffer (uintptr_t)mOut.data(); do { // 通过ioctl将数据写入Binder驱动 ioctl(mProcess-mDriverFD, BINDER_WRITE_READ, bwr); } while (err -EINTR); }步骤 6Binder 驱动转发请求到 SM 进程Binder 驱动接收到 SF 进程的BC_TRANSACTION命令后根据 handle0 识别出目标是 SM 进程唤醒 SM 的主线程并将请求数据转发给 SM。步骤 7SM 主线程处理 Binder 请求Looper 回调SM 的主线程通过 Looper 监听 Binder 驱动 FD 的EVENT_INPUT事件触发回调处理请求代码位于native\cmds\servicemanager\main.cpp// native\cmds\servicemanager\main.cpp int handleEvent(int /* fd */, int /* events */, void* /* data */) override { IPCThreadState::self()-handlePolledCommands(); // 处理驱动转发的请求 return 1; // 持续监听 }步骤 8SM 解析并执行 Binder 命令SM 的IPCThreadState读取驱动数据并执行命令最终调用 SM 自身的transact方法代码位于native\libs\binder\IPCThreadState.cpp// native\libs\binder\IPCThreadState.cpp status_t IPCThreadState::handlePolledCommands() { do { result getAndExecuteCommand(); } while (mIn.dataPosition() mIn.dataSize()); return result; } status_t IPCThreadState::getAndExecuteCommand() { talkWithDriver(); // 从Binder驱动读取SF的注册请求 cmd mIn.readInt32(); result executeCommand(cmd); // 执行ADD_SERVICE命令 } status_t IPCThreadState::executeCommand(int32_t cmd) { // 调用SM的BBinder处理ADD_SERVICE请求 the_context_object-transact(tr.code, buffer, reply, tr.flags); }步骤 9BBinder 转发到 onTransact 方法SM 的BBinder基类将请求转发到onTransact方法代码位于native\libs\binder\Binder.cpp// native\libs\binder\Binder.cpp status_t BBinder::transact( uint32_t code, const Parcel data, Parcel* reply, uint32_t flags) { onTransact(code, data, reply, flags); // 转发到AIDL生成的onTransact }步骤 10AIDL 生成的 onTransact 解析参数AIDL 工具生成的BnServiceManager::onTransact解析请求参数并调用 SM 的addService方法代码位于android/os/IServiceManager.cppAIDL 生成// android/os/IServiceManager.cpp (AIDL工具生成) BnServiceManager::onTransact(uint32_t _aidl_code, const ::android::Parcel _aidl_data, ::android::Parcel* _aidl_reply, uint32_t _aidl_flags) { switch (_aidl_code) { case BnServiceManager::TRANSACTION_addService: android::binder::Status _aidl_status(addService(in_name, in_service, in_allowIsolated, in_dumpPriority)); _aidl_ret_status _aidl_status.writeToParcel(_aidl_reply); break; } }步骤 11SM 完成 SF 服务注册最终落地SM 的addService方法将 SurfaceFlinger 写入服务注册表mNameToService完成注册代码位于native\cmds\servicemanager\ServiceManager.cpp// native\cmds\servicemanager\ServiceManager.cpp Status ServiceManager::addService(const std::string name, const spIBinder binder, bool allowIsolated, int32_t dumpPriority) { // 覆盖已有服务如果存在将SF写入SM的服务注册表 mNameToService[name] Service { .binder binder, .allowIsolated allowIsolated, .dumpPriority dumpPriority, .debugPid ctx.debugPid, }; return Status::ok(); }七、总结Android ServiceManager 作为 Binder 通信的核心枢纽其设计和实现有以下关键特点极简的线程模型摒弃 Binder 线程池仅通过单线程 Looper 监听 FD 事件保证轻量和高效Binder 上下文管理器作为 Binder 通信的根节点句柄固定为 0所有服务查询 / 注册都从 SM 开始双 FD 监听机制通过 Binder 驱动 FD 处理服务注册 / 查询命令通过定时器 FD 检测客户端连接状态AIDL 驱动的功能映射基于 AIDL 生成的 Bn/BpServiceManager将 Binder 命令转换为具体的服务管理操作完整的 Binder 链路以 SurfaceFlinger 注册为例客户端请求经 Binder 驱动转发到 SM最终落地到服务注册表形成闭环。SM 的设计充分体现了 Android 系统 “核心组件极简、高效” 的原则作为系统服务的 “注册表”它的稳定性和高效性直接决定了整个 Android 系统 Binder 通信的正常运行。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询