第 00 章:阅读路线与研究方法
这是一份“源码解剖”而不是 API 手册。每章先建立概念模型,再把模型落到文件、类型、函数和时序,最后说明这个设计解决了什么工程问题。
1. 研究对象与边界
研究对象是 app-monorepo-codex-native-home-container.zip(文件时间 2026-07-31)的源码快照,主线是 Mobile Native Home 和 @onekeyhq/native-components 中的 HomeContainer。它位于一个完整钱包 monorepo 中,因此会遇到真实工程里的复杂性:多端入口、状态分区、账户切换、原生 codegen、构建矩阵和向后兼容。
本文不尝试解释 OneKey 的每条链、每个钱包页面或所有交易业务,而只解释这些业务如何被压缩成 HomeContainer 能消费的通用展示模型。
2. 建议阅读顺序
前 7 章是“数据和控制流主线”;第 8–10 章是“原生实现”;第 11–14 章是“可靠性与工程判断”。如果只想知道组件怎么被调用,读到第 06 章即可;如果要修改滚动、首屏或账户切换,必须继续读 10–13 章。
3. 我采用的拆解问题
每个模块都用下面五个问题检查:
| 问题 | 在本项目中的对应物 |
|---|---|
| 它拥有哪种状态? | Home Store 语义状态、native snapshot、原生 viewport 状态、slot owner |
| 它接受什么输入? | React props、JSON state、Nitro method、用户手势、Store intent |
| 它输出什么事件? | onIntent、onRenderError、slot layout change、refresh completion |
| 哪些边界必须拒绝? | 无效 tab topology、错误 owner、handoff 携带 sections、陈旧请求 |
| 为什么不直接复用另一层? | Native engine 只负责高频布局;React slot 保留复杂业务和交互语义 |
4. 先记住三个核心对象
IHomeContainerState
它是跨语言的“当前 owner + 可渲染 payload”:
type IHomeContainerState = {
owner: { scopeKey: string; sessionId: string };
payload: {
selectedTabId: 'portfolio' | 'perps' | 'defi' | 'nft' | 'history';
header: IHomeContainerHeader;
tabs: IHomeContainerTab[];
theme: IHomeContainerTheme;
};
};IHomeContainerSlots
它是“复杂 React 内容的插槽集合”。账号选择器、余额、WalletActions、空状态、筛选器等仍由 React 渲染,原生容器只提供这些内容的物理 host。
IHomeContainerIntent
它是原生到 JS 的控制面协议,只有四类:action、handoff、refresh、selectTab。业务层收到后还要用 owner 和 command revision 再验证一次,不能把 JSON 解析成功当成“业务授权成功”。
5. 源码定位规则
正文中的文件路径都相对于上游 app-monorepo 根目录。行号按快照生成时的文件版本记录,推荐用“路径 + 符号名”双重定位,因为后续上游提交可能改变行号。
关键入口:
- JS 协议:
packages/native-components/src/HomeContainer.types.ts - JS 原生 wrapper:
packages/native-components/src/HomeContainer.native.tsx - Mobile 组装器:
apps/mobile/src/home/MobileNativeHomeRenderer.tsx - ViewModel:
apps/mobile/src/home/mobileNativeHomeViewModelAdapter.ts - Android 引擎:
packages/native-components/android/.../HomeContainerView.kt - iOS 引擎:
packages/native-components/ios/HomeContainerView.swift - 快照缓存:
packages/kit/src/views/Home/model/cache/
6. 一句话结论
这套实现的本质是:把“高频、结构稳定、适合原生滚动的 Home 壳”下沉到 native,把“业务语义、授权、复杂 React 内容”留在 JS,并用显式 owner/session 和可验证协议把两者锁在一起。