Commercialization.topon 维护规范
1. 仓库定位
本仓库是 Topon 平台商业化实现层的 Unity 源码工程,不是业务项目。
它承担两类职责:
- 作为
com.commercialization.topon的源码发布仓库。 - 作为本地联调和验证工程,用来测试该实现层与商业化抽象层的组合效果。
当前设计是:
com.foldcc.cc-framework.commercialization提供抽象层。com.commercialization.topon提供Topon/AnyThink的具体实现层。- 业务项目通过
商业化抽象层 + 平台实现层的组合快速接入广告能力。
2. 发布规范
2.1 发布源
真正发布到 UPM 的内容只有 Assets 子树。
- 包定义文件:
Assets/package.json - 发布脚本:
Update Upm.bat
发布脚本做的事情:
- 从
Assets子树切出upm分支。 - 强推
upm分支。 - 按
Assets/package.json里的version创建 tag。
也就是说:
- 根目录的
Packages、ProjectSettings、Library都不是包内容。 - 维护包时,必须把所有真正要发布的代码和资源都放在
Assets下。
2.2 版本约定
- 包版本号以
Assets/package.json为准。 - 业务项目引用的也是
Assets/package.json对应 tag。 - 本地工程里的
Packages/manifest.json只用于当前源码工程联调,不参与发布。
2.3 发布前检查
发布前至少确认以下事项:
Assets/package.json的版本号已更新。Assets/package.json里的核心依赖版本与本地验证环境一致。- 所有本次升级需要发布的内容都在
Assets下。 Update Upm.bat执行前,工作区已整理干净。
3. 目录职责
3.1 Assets/Topon_Adapter
本目录是平台具体实现层,负责把抽象广告接口绑定到 Topon。
Runtime/ScriptsToponAdController.cs:实现IAdControllerAwardVideoPlayer.cs:激励视频实现InteractionPlayer.cs:插屏实现ADListenerAggregator.cs:新版 SDK 回调桥接
EditorAD_BuildAndroidProcess.cs:Android 导出后处理WXDependencies.xml:微信 Android 依赖ToponTestDependencies.xml:调试依赖alex_tt_file_path.xml/anythink_bk_tt_file_path.xml:文件路径配置
3.2 Assets/AnyThinkPlugin
本目录是官方 AnyThink Unity 插件及其二次适配层。
AnyThinkAds- 官方运行时 API、平台桥、AAR、iOS 桥代码
Script/IntegrationManager- SDK 管理器
- 本地安装状态记录
- 版本下载和热修复
Script/Editor- Android/iOS 构建期后处理
3.3 Assets/Plugins/Android
本目录保存额外 Android 资源和补充模块。
gromoreRes.androidlib:额外 Android 资源载体- 多个
*.DISABLED模板文件:当前不作为主流程依赖,保留给手工切换或历史兼容
3.4 Assets/ExternalDependencyManager
EDM4U 依赖解析器,负责消费 Dependencies.xml 并拉取 Android/iOS 依赖。
4. 运行时架构
运行时链路如下:
业务项目 -> 商业化抽象层 -> Topon_Adapter -> AnyThink 官方 SDK -> Android/iOS 原生桥
职责划分如下:
- 抽象层
ADManager:统一初始化、异步播放、超时、遮罩、事件流IAdController:平台实现层入口ADPlayer:广告位抽象AsyncAdPlayer:广告加载与播放调度器
- Topon 实现层
ToponAdController:初始化 Topon SDK,创建各广告位 PlayerAwardVideoPlayer/InteractionPlayer:广告位具体实现
- 官方 SDK
ATSDKAPI:统一 SDK 能力入口ATAdsClientFactory:按平台创建实际 ClientPlatform/Android和Platform/iOS:桥接到原生层
当前已明确实现的广告类型:
AwardVideoInteraction
当前保留但未落地完整实现的类型:
Splash
5. 升级 SDK 时不能丢的本地改造
这是本仓库最重要的部分。升级官方 SDK 时,不能直接全量覆盖,否则会把包管理能力和构建补丁一起冲掉。
5.1 动态路径读取规范
本仓库已经把关键文件路径从固定 Assets/... 改为动态定位。
必须保留以下思路:
- 通过
AssetDatabase.FindAssets找到脚本自身位置。 - 基于脚本位置反推插件根目录。
- 所有插件配置、资源、构建拷贝都从动态根目录计算。
当前核心实现点:
ATConfig.RootPathATConfig.GetScriptsPath(...)ATPostProcessBuildAndroid.GetScriptsPath(...)AD_BuildAndroidProcess.GetScriptsPath(...)
这样做的目的:
- 不依赖固定
Assets/AnyThinkPlugin/...绝对相对路径。 - 为后续包管理器接入保留空间。
- 允许实现层以非侵入方式挂接到其他项目。
结论:
- 后续升级 AnyThink SDK 时,不允许重新引入硬编码
Assets/...路径作为主逻辑。 - 如果官方新版本新增了读取配置文件、复制模板文件、写本地状态文件的逻辑,必须按当前动态定位方式重新改造。
5.2 本地安装状态与配置落盘
本仓库通过 ATConfig 在插件目录下维护本地状态:
plugin_setting_data.jsonplugin_hot_fix_data.json- 各 network 的
network_data.json
这些文件用于:
- 记录当前国家区服选择
- 记录 Android/iOS 已安装 core 版本
- 记录各 mediation network 当前安装版本
- 记录 AdMob app id
- 记录 AndroidX 选择
- 记录热修复版本
升级时不要删除这套机制。
5.3 新版回调桥接规范
Topon_Adapter 里新增了 ADListenerAggregator,作用是把新版 event 风格回调重新桥接回旧 listener 逻辑。
背景:
- 老代码依赖
listener风格回调。 - 新版 SDK 已不再适合直接
client.setListener(this)。
因此:
AwardVideoPlayer必须通过ADListenerAggregator.BindAwardVideoListener(...)绑定。InteractionPlayer必须通过ADListenerAggregator.BindInterstitialAdListener(...)绑定。- 奖励视频链路的旧 listener 回调必须继续完整桥接到 Unity 主线程,不能直接在 SDK 子线程里触发业务逻辑。
如果升级后官方再次调整回调模型,优先延续这层桥接,不要直接把抽象层改成强耦合官方回调。
5.4 ToponAdController 配置入口规范
ToponAdController 现在支持两类初始化输入:
- 兼容旧参数:
args[0]:channelargs[1]:debug
- 推荐新参数:
- 通过
ADConfig.CommonKeyValues - 或额外传入
ToponControllerOptions - 或额外传入
IDictionary
- 通过
当前已支持的配置 key:
topon.channeltopon.sub_channeltopon.debugtopon.debugger_keytopon.sdk_areatopon.longitudetopon.latitudetopon.exclude_bundle_idstopon.rewarded_exclude_ad_source_idstopon.query_area_on_inittopon.custom_map.<name>topon.rewarded_custom_data.<name>
说明:
topon.exclude_bundle_ids- 用于全局排除指定广告主 bundle id
topon.rewarded_exclude_ad_source_ids- 用于当前激励视频广告位排除指定广告源
topon.query_area_on_init- 初始化后主动查询 SDK 当前区域
- 结果会回写到
ToponAdController.LastDetectedArea
topon.custom_map.<name>- 对应
ATSDKAPI.initCustomMap(...) - 注意先设置 custom map,再设置 channel/sub_channel
- 对应
topon.rewarded_custom_data.<name>- 对应
ATSDKAPI.setCustomDataForPlacementID(...) - 当前默认应用到激励视频广告位
- 对应
维护约束:
- 当前 IAA 业务主链路以激励视频为主,新功能配置优先围绕
AwardVideo广告位设计。 - 如果后续要补插屏、开屏、原生等广告位的同类配置,优先扩展
ToponControllerOptions,不要把 SDK 细节直接散落到业务层。
5.5 AnyThinkSDKEditor 编辑器开关规范
AnyThinkPlugin/Script/IntegrationManager/Editor 这套“SDK Manager / 远端版本检查 / hotfix 检查 / 远端 unitypackage 导入”能力,当前应视为维护工具,而不是业务项目默认能力。
当前约定:
- 只有在定义了
AnyThinkSDKEditor宏时,才允许显示AnyThink菜单并启用联网检查。 - 未定义
AnyThinkSDKEditor时:- 不显示
AnyThink/SDK Manager - 不执行 SDK 版本拉取
- 不执行 hotfix 检查
- 不执行远端 unitypackage 下载与导入
- 不显示
这样做的目的:
- 避免业务项目通过包管理接入后,仍然保留官方集成管理器的远端更新入口。
- 降低编辑器侧供应链风险。
- 把 SDK 升级动作收敛到维护工程,而不是下游接入工程。
6. Android 构建期自定义规范
Android 的构建后处理分为两层:
Topon_Adapter平台专项后处理AnyThinkPlugin通用 SDK 后处理
6.1 Topon_Adapter/Editor/AD_BuildAndroidProcess.cs
主要职责:
- 将
alex_tt_file_path.xml和anythink_bk_tt_file_path.xml复制到导出的 Gradle 工程 - 将
UnityPlayerActivity的launchMode改为singleTop - 在
manifest中增加微信queries/package - 重建
.wxapi.WXEntryActivity - 注入
com.bytedance.sdk.openadsdk.TTFileProvider - 在
launcherapplication 节点设置android:allowBackup="false"tools:replace="android:allowBackup"
升级时这些点必须逐项核对。
6.2 AnyThinkPlugin/Script/Editor/ATPostProcessBuildAndroid.cs
主要职责:
- 处理
gradle.propertiesandroid.useAndroidXandroid.enableJetifierandroid.enableDexingArtifactTransform=false
- 按 AdMob 是否安装,动态补
com.google.android.gms.ads.APPLICATION_ID - 中国区时补
android:networkSecurityConfig - 增加
org.apache.http.legacy - 调用
ATProcessBuildGradleAndroid.processBuildGradle(path)
6.3 AnyThinkPlugin/Script/Editor/ATProcessBuildGradleAndroid.cs
当前生效职责:
- 海外模式下注入
packagingOptionsmerge 'META-INF/com.android.tools/proguard/coroutines.pro'exclude 'META-INF/*.kotlin_module'
当前文件里还有历史保留逻辑:
handleNetworkResMerge(...)callGradleTask(...)
其中存在旧的固定路径残留,不是当前主流程依赖。若后续重新启用,必须先改造成动态路径。
6.4 Android 依赖补充
除了官方插件自带依赖,本仓库还额外声明了:
- 微信依赖:
WXDependencies.xml - Topon 调试依赖:
ToponTestDependencies.xml
升级后如果官方依赖结构变化,需要同步确认这些补充依赖是否仍然必要。
7. iOS 构建期自定义规范
AnyThinkPlugin/Script/Editor/ATPostProcessBuildiOS.cs 负责 iOS 导出后的补丁。
当前关键职责:
- 嵌入特定动态 framework
- 添加 bundle 资源
- 关闭 bitcode
- 开启 Objective-C exceptions
- 按 AdMob 是否安装补充 iOS 侧 Google app id
升级 iOS SDK 时,至少要检查:
- 需要 embed 的 framework 路径是否变化。
- 需要附带的 bundle 是否变化。
- plist 补丁是否仍然适用。
8. 升级官方 SDK 的推荐流程
建议按以下顺序执行,不要直接整目录替换后发布。
8.1 准备阶段
- 记录当前包版本和 core 依赖版本。
- 备份当前
Assets/AnyThinkPlugin和Assets/Topon_Adapter。 - 确认本次升级目标是
- 仅升级官方 SDK
- 还是同时升级商业化 core 抽象层接口
8.2 合并阶段
- 先更新官方运行时目录
Assets/AnyThinkPlugin/AnyThinkAds
- 再检查编辑器目录
Assets/AnyThinkPlugin/Script/IntegrationManagerAssets/AnyThinkPlugin/Script/Editor
- 最后回填本仓库本地改造
- 动态路径改造
- listener 桥接
- Android/iOS 构建补丁
Topon_Adapter运行时绑定
不建议做法:
- 直接拿官方新版覆盖整个
Assets/AnyThinkPlugin - 直接覆盖
Topon_Adapter - 在没核对构建脚本的情况下直接发布 tag
8.3 验证阶段
升级后至少验证以下内容:
- Unity 工程可编译。
Topon_Adapter仍能正确引用 core 抽象层。- 激励视频和插屏能正常加载、展示、回调。
- Android 导出工程中:
WXEntryActivity存在TTFileProvider存在queries/com.tencent.mm存在allowBackup=false生效networkSecurityConfig在中国区按预期生效packagingOptions注入正常
- iOS 导出工程中:
- framework embed 正常
- bundle 正常
- plist 补丁正常
- EDM4U 依赖解析后无明显冲突。
8.4 发布阶段
- 更新
Assets/package.json版本。 - 必要时同步更新
Assets/package.json中的 core 依赖版本。 - 本地工程验证无误后执行
Update Upm.bat。 - 在业务项目按 tag 验证最终接入结果。
9. 当前已识别的维护注意项
9.1 版本声明可能漂移
当前仓库内存在两处 core 版本信息:
Assets/package.jsonPackages/manifest.json
前者决定发布包依赖,后者仅影响当前源码工程联调。
升级或发版时,要确认二者是否需要同步,不要出现“发布出去的依赖版本”和“本地验证时的依赖版本”长期漂移。
9.2 不要依赖根目录工程文件
根目录这些文件只是 Unity 本地工程产物:
*.csproj*.slnLibraryTemp
包发布和业务项目接入都不应依赖它们。
9.3 当前实现范围
本仓库当前本质上是:
Topon平台广告实现层- 面向
商业化抽象层的适配包
不是:
- 通用业务 Demo
- 完整多平台商业化总仓
- 所有广告位都已完全实现的全量样板
10. 一句话原则
后续升级 Topon/AnyThink SDK 时,优先保护这四件事:
Assets子树可独立发布为 UPM 包。- 动态路径定位不能回退成固定
Assets/...读取。 Topon_Adapter对 core 抽象层的接口契约不能被官方 SDK 反向污染。- Android/iOS 构建期补丁必须逐项保留并重新验证。