> ⚠️ 回顾打磨期，项杂跨多处。**详细计划（demo 多屏全代码 + native 自渲染结构方案/spike/兜底）见 [`docs/superpowers/plans/2026-06-12-phase-3-review-polish.md`](../../../docs/superpowers/plans/2026-06-12-phase-3-review-polish.md)**——demo 与自渲染以该计划为准。
>
> 🔑 **自渲染结构决策（2026-06-13 探索定案 · 照 VVAX 模型 B 重做，见计划区块 B）**：旧方案（容器=ATNativeAdView 子类 + getChildAt + renderAdContainer re-parent + relayout 补丁）已踩遍坑作废。改照 VVAX 模型 B：**SDK 素材回传 JS → RN `<Text>`/`<Image>` 自渲染填值+布局；mediaView 等 SDK view addView 进 RN 占位；native 只 findViewById 绑 tag + 注册点击/曝光。** RN view 不被 re-parent → 无需 relayout，布局问题消失。模板(express) 走独立简单路径 `renderAdContainer(container,null)`。
> 🔑 **依赖**：A5(SdkApiScreen) 依赖 §1(ATSDK 实现) 同批；demo 用**手搓导航**(screen state+条件渲染，不引 react-navigation)，UI 参考安卓。

## 1. ATSDK 补全（§4.3 缺 22；竖切 L1→spec→原生→iOS stub）

- [x] 1.1 spec `NativeATBridge.ts` 加 22 个 Core 方法（有返回值→Promise；List/Map 入参→Object/Array）
- [x] 1.2 `src/core/ATSDK.ts` 加 22 个 L1：GDPR/隐私 7 / filter 6 / area·location 4 / debug 2 / 策略·渠道 3
- [x] 1.3 原生 `ATInitManager.java` + bridge 实现（参考现有 putFilter/GDPR 写法；复杂类型走 BridgeJsonMapUtil）
- [x] 1.4 无对应原生 API 的方法标 **N/A**（ATSDK.ts 注释 + design 记录原因，满足 G-F03）
- [x] 1.5 iOS `.mm` 补 22 个 stub + NSLog
- [x] 1.6 Const.ts 若需新 callName/key（如 checkIsEuTraffic 回调）补齐 + sync-const-check

## 2. Native 自渲染重做（照 VVAX 模型 B）+ 列表（收 phase-2e 6.1/8.2/8.3）　【源码 2.1-2.3 + demo 2.4/2.6 + 真机 2.5】

> 🔁 **重做**：旧 2.1/2.2（selfRenderView + renderAdContainer re-parent）方向作废、已回退。改照 VVAX 模型 B（详见计划区块 B B1-B4）。核心是建**素材回传通道 + AssetView 组件 + updateAssetView/renderNativeAd command**，让 RN 自渲染真显示素材 + 点击 + 曝光。

- [x] 2.1 **素材回传通道（源码·android）**：`ATNativeHelper.getAdMaterialMap()` 取 getAdMaterial() 的 title/desc/cta/iconUrl/mainImageUrl/starRating/advertiser/isMediaViewAvailable；`ATNativeManager.getAdMaterial` 去 stub 接真实 map（经 getNativeAdMaterial bridge → L1 getAdMaterial）
- [x] 2.2 **command 注册机制（源码·android）**：ViewManager 加 `updateAssetView(tag,type)` 存映射(ATNativeContainer.assetTags) + `renderNativeAd()` debounce 50ms（findViewById 收 clickViewList + getAdMediaView addView 进 mediaView 占位 + setClickViewList → mNativeAd.prepare）；删旧 getChildAt/selfRenderView/relayout 自渲染分支（NativePrepareBinder 重写为 tag→type）
- [x] 2.3 **JS AssetView + Provider（源码·JS）**：`NativeAdProvider`(Context 持素材+各 ref) + `ATNativeAssetViews`(ATNativeTitleView/DescView/CtaView/IconView/MainImageView/MediaView 从 Context 填) + `ATNativeAdView.tsx` 收 children + mount 后 getAdMaterial→setNativeAd→updateAssetView→renderNativeAd；spec 加 codegenNativeCommands；index 导出 AssetView
- [x] 2.4 example 自渲染屏：用新 AssetView 组件拼布局（开发者只摆位，素材自动从 Context 填）
- [x] 2.5 真机验：三类 offer（图文拼多多/京东、视频快手、express 模板）显示+点击+曝光全正常；混配位按 isExpress 自动分流；collapsable 收进 SDK 内部（ATNativeAdView 自动包裹，开发者无需加）；polish 合并 forceLayout + 清诊断日志
- [x] 2.6 example 列表屏：由 §6.3 的 ListScreen 实现（FlatList 内容条目间插 Banner，验滚动不串位，N-F06/F07）；真机验待用户
- [x] 2.7 模板(express) 独立路径：`ATNativeHelper.renderTemplate()` → `renderAdContainer(container,null)` 让 SDK 画模板（renderIfReady 触发），与自渲染（command）互不干扰

## 3. 参数级对齐 audit

- [x] 3.1 逐个核 reward/interstitial/splash/banner/native 的 load(ATAdRequest)/show(ATShowConfig)/setLocalExtra/entryAdScenario 入参 vs §4.x
- [x] 3.2 setAdSourcePrivacyPolicy 等入参核对；不一致则修正 + 补/改单测

## 4. debug 日志（全面联调日志，统一受 log 开关控制）

> 目标：**调用日志 + 参数日志 + 回调日志**，**RN 层 + 侨联层都要**，全部受 `setNetworkLogDebug` 开关控制，方便测试联调。
> 机制：JS 侧建 `ATLog`（enabled 由 setNetworkLogDebug 同步）；原生侧复用 MsgTools（已受 setLogEnabled 控制）。

- [x] 4.1 **JS 基础设施**：`src/utils/ATLog.ts`（enabled 标志 + d(tag,...)）；`ATSDK.setNetworkLogDebug` 同步设 `ATLog.enabled`
- [x] 4.2 **RN 层日志**：各 L1（reward/inter/splash/banner/native/ATSDK）每 API 调用打"方法+参数"；每回调分发（dispatchXxxEvent）打"callbackName+参数"
- [x] 4.3 **侨联层日志**：桥入口 `ATReactNativeBridgeModule` 每方法打"调用+参数"；各 Helper 回调 emit 处打"callbackName+参数"（Native/Banner 补齐）
- [x] 4.4 全部受开关控制：关 log → 0 输出；开 log → RN+原生双层可见

## 5. Const 清理

- [x] 5.1 **该用去用**：NativePrepareBinder 等字面量 key → `Const.PlatformViewKeys.*`；扫其他硬编码 key 替换
- [x] 5.2 **真死剔除**：0 引用且 Flutter 独有永不用的（PlatformViewName/banner 不支持方法数组/TYPE）剔除
- [x] 5.3 保留"还没接但会用"（DownloadCallCallback/MultipleLoadedKeys/CommonADCallBack 后续待定）+ 注释标预留
- [x] 5.4 Const.ts 同步 + sync-const-check 通过

## 6. demo 重做（参考安卓 china demo 简单版）　【纯 demo·example/】

> 🔁 **2026-06-13 探索定案**：废弃旧七屏繁版（Auto/SDKAPI繁/隐私/列表屏）。改照安卓对外简单版 `anythink_china_project` 的 `com.test.ad.demo`：主页入口列表 + 5 广告类型页 + FeatureScreen，每页「按钮 + 页内日志区」。详见计划区块 A。
> 范式：每页自包含（new L1 + setAdListener 里 append 日志 + 按钮），**回调与日志同一处**。manager 内联进 Screen、EventLogPanel 删（被 LogArea 取代）。只动 example/，复用 L1 + ATSDK。

- [x] 6.1 路由骨架 + 4 复用组件：`navigation/screens.ts` + `components/{TitleBar,LogArea(useLogArea 命令式 append),AdButton,Screen}.tsx`；`App.tsx` 改 screen state 路由（零依赖）
- [x] 6.2 HomeScreen：7 入口按钮 + SDK version（对应安卓 MainActivity）
- [x] 6.3 5 广告类型页（自包含 + 回调 append 日志区）：RewardScreen / InterstitialScreen / SplashScreen / BannerScreen / NativeScreen（模板+自渲染，迁现 App.tsx）+ ListScreen（FlatList 内容条目间插 Banner，收 §2.6 / N-F06-F07）
- [x] 6.4 FeatureScreen：ATSDK API 单页分 5 组（GDPR/隐私、filter、area/location、debug/渠道/策略、版本），每方法一按钮 → 调 ATSDK → 结果 append 日志
- [x] 6.5 清理旧文件：删 managers/{Reward,Interstitial,Splash}Manager.ts + components/{AdActionButton,EventLogPanel}.tsx；App.tsx 改路由器（InitManager 保留）
- [x] 6.6 tsc PASS（0 错，example 含在根 tsc）；真机过 Home→各页 待用户验

> 🔁 **6.7-6.9 = v2 迭代（2026-06-14 对齐 app-china-androidx，真机对照后升级）**：加初始化页+自绘隐私弹窗、广告页卡片风（Select Network+Auto Load）、列表页升级（多类型混插+无限滚动）。详见计划区块 A6-A8。

- [x] 6.7 InitScreen + 自绘隐私弹窗：example 装 react-native-webview + async-storage；InitManager 拆 initSdk()(setNetworkLogDebug+integrationChecking+setPersonalizedAdStatus+init+start) 手动触发；InitScreen【初始化SDK→Modal+WebView(toponad 隐私政策)+同意/不同意→initSdk】【个性化 Switch→setPersonalizedAdStatus+AsyncStorage 持久化+文案】【进 Demo gate】；App 起始 'init'
- [x] 6.8 卡片风 + Select Network + Auto Load：config 加 networks 结构（现仅 All）；AdCard(图标卡+NetworkPicker+Auto Load 复选+操作区+日志区) + NetworkPicker(Modal 下拉)；Reward/Interstitial/Splash 改卡片风英文标题，Auto Load 勾选走 ATRewardVideoAutoAd/ATInterstitialAutoAd
- [x] 6.9 广告列表升级：ListScreen 混插内容条目 + Banner + 模板Native + 自渲染Native（每3条轮换）+ onEndReached 无限滚动；事件 append 日志；tsc 0 错；真机验待用户（需重编 autolink webview/async-storage）

## 7. 覆盖率 + 异常防护（§十 G-Q01）

- [x] 7.1 `ATSDK.test.ts`：22+ 方法参数化 dispatch + init/常量/Promise 返回（ATSDK.ts 100%，40 用例）
- [x] 7.2 各 L1 主路径+异常分支+dispatch 全 callbackName：reward 98.6% / inter 100% / splash 100% / banner 100% / native 100% + AutoAd×2 100% + AssetViews 100% + NativeAd 100%（新增 ATAutoAd/ATNativeAssetViews/ATLog 测试 + augment 各 L1）
- [x] 7.3 Const.ts=100% / ATAdEvents lines=100% / ATSDK=100% / 全局 lines=98.3%（ATLog 100%、ATAdEvents 全局监听补齐）
- [x] 7.4 `coverageThreshold` 加进 package.json（全局 80/branches75 + Const100/ATAdEvents95/ATSDK80 具名门槛）；`yarn test:coverage` 绿（154 tests），tsc 0 错

## 8. 交付收口（§十 G-F/D/Q）

- [ ] 8.1 交付范围总览表（G-F01）：全局 + 五类可勾选
- [ ] 8.2 android-rn-parity 对拍文档（G-F02）：Core + 五类主路径
- [ ] 8.3 集成文档 Quick Start（G-D01）：Init 1~4 步
- [ ] 8.4 sync-const-check 扩含 iOS 三边校验（G-Q03）
- [ ] 8.5 静态扫描 0 新增 blocker（G-Q02）；ATAdInfo snake_case（G-F04）/AdError 可用（G-F05）核对
- [ ] 8.6 M6 全量冒烟 ≤15min（G-D02，7 步）；更新实施规范 §十二 Phase 3 → ✅
- [ ] 8.7 archive 前同步：proposal.md scope + design.md 补「区块 10 Native 列表多广告（adId 单→多）」技术决策小节（现 proposal 只含糊写"架构已支持"、design 未提，会与 spec 新 Requirement 脱节）。详见 docs/native-list-multi-ad-改造方案.md

> 收口待办（2026-06-15 review 后记录，用户决定后续做）：8.1/8.2/8.3 三份交付文档 + 8.7 proposal/design 补区块10 = archive 阻塞项；8.4/8.5/8.6 非阻塞。lint/tsc/jest/prettier/sync-const 当前已全绿。

## 10. Native 列表多广告（单条→多条 by adId）　【SDK 原生+JS·方案见 docs/native-list-multi-ad-改造方案.md】

> 根因：现状一 placementId 只持一条 mNativeAd/一个容器，列表多 cell 互相覆盖（只有最后一个显示）。
> 改造：对齐安卓「单 ATNative + 多 NativeAd 对象」，跨桥用 adId 代理对象引用；`<ATNativeAdView ad>` 传对象；补货归用户；补 onResume/onPause。iOS 同签名空实现。

- [x] 10.1 原生 ATNativeHelper：`mNativeAd`/`mContainer`/`isExpress` 单字段 → 按 adId 的 Map；`fetchNativeAd()`→返回 adId（弹一条+生成 adId+存 map）；getAdMaterialMap/renderSelfRender/doRenderSelfRender/renderTemplate/destroy 均带 adId；每条 NativeAd 的 emit 带自身 adId；新增 onResume/onPause/destroyAll；空 adId 回退 mLastAdId
- [x] 10.2 原生 ATNativeManager：getNativeAd resolve `{hasAd,isExpress,adId}`；getNativeAdMaterial/destroy(adId)/destroyAll/nativeAdOnResume/nativeAdOnPause 转发补 adId
- [x] 10.3 原生 ATNativeAdViewManager：ATNativeContainer 加 adId 字段；setAdId prop；renderNativeAd 用 container.adId 绑对应那条；onDropViewInstance 按 adId 销毁（不整位）；Helper↔容器按 adId 多对
- [x] 10.4 事件层 adId：ATNativeHelper.emit(adId) + ATReactNativeEventEmitter payload 透出 adId（String 白名单）；Const.java/Const.ts 加 adId callbackKey（sync-const OK）
- [x] 10.5 JS L1：ATNative.getNativeAd→带 adId 的 NativeAd、_releaseAd 回收实例订阅；NativeAd 加 adId 字段 + onResume()/onPause()（透传 adId）；ATAdEvents 加 adListeners(placementID#adId) 分流
- [x] 10.6 JS 视图：ATNativeAdView 改收 `ad: NativeAd` prop（内部取 ad.adId 下发 native）、消灭 placementID 反查；素材/命令/事件按 adId；specs 加 adId prop（codegen 随 build 重生）
- [x] 10.7 NativeScreen 改 `<ATNativeAdView ad={tplAd}>`（统一一套 API，单广告回归不破）
- [x] 10.8 demo ListScreen：共享两个 ATNative（模板/自渲染）+ 每 cell getNativeAd 取多条 + 消费即补货；P2 生命周期（AppState 前后台 + FlatList onViewableItemsChanged，前台且可见才 onResume；存活集合 useRef Map 用户维护）；banner 仍不入列表
- [x] 10.9 iOS：getNativeAdMaterial/destroyNativeAd 加 adId + nativeAdOnResume/onPause 同签名空实现 + NSLog
- [x] 10.10 测试：单广告回归（ad 用法）+ 多广告 adId 分流不串位 + onResume/onPause 断言；tsc 0 / jest 155 绿 / coverage 达标 / prettier 净 / sync-const OK
- [ ] 10.11 真机验（用户）：列表多个 native 各显不同广告、点击/曝光不串、切后台暂停

## 9. 验证

- [ ] 9.1 Android 编译绿 + M6 冒烟走通；iOS 编译过 + NSLog 路由可见
- [ ] 9.2 tsc/prettier/sync-const-check/coverage 全绿
- [ ] 9.3 对照 §十 G-F01~F05 / Q01~Q03 / D01~D02 逐条
- [ ] 9.4 区块 10：列表多广告不串位 + adId 全透明 + onResume/onPause 双端同签名
