# 变更记录
## [1.0.0.64-SNAPSHOT] - 2026-09-22
> 📌 **双端发布**:Android Maven `1.0.0.64-SNAPSHOT` + iOS xcframework 均源码重建。`supersimples` Android 模板 `sdk.androidVersion` 切到 `1.0.0.64-SNAPSHOT`。
### WebView 麦克风授权(容器能力)
H5 `navigator.mediaDevices.getUserMedia({ audio: true })` 由 SuperSDK 容器接管,宿主不必再包 `WebChromeClient` / `WKUIDelegate`。
- **Android**
- 容器处理纯 `AUDIO_CAPTURE`;含 `VIDEO_CAPTURE` 或其它非音频资源的请求整次 deny。
- 使用 `SuperPageActivity` / `IPageController.open()`:**不用写 Java**,自动注入公开 `com.supersdk.api.page.IFileChooserHost`。
- 自包装:Activity 实现该接口(含 `launchMicrophonePermission`),在 `onCreate` 注册 launcher,禁止替换 `WebChromeClient`。
- **宿主必须自行声明 `RECORD_AUDIO`(SDK 不 merge)**。`CAMERA` 仍由 SDK merge(`` 拍照)。
- **iOS 15+**
- `SuperWebView` 实现 `WKUIDelegate.requestMediaCapturePermissionFor`:microphone 无/空 `NSMicrophoneUsageDescription` → Deny,否则 Prompt;camera 恒 Prompt;cameraAndMicrophone 无 mic 说明 → Deny,否则 Prompt。不读 `AVCaptureDevice`。
- iOS 14 无该 API,保持系统默认。`createPageView` / `createPageViewController` 无需再包 UIDelegate。
- **宿主 Info.plist 必填 `NSMicrophoneUsageDescription`**;缺说明时容器 Deny、不启动采集。
- Demo / `supersimples` iOS 模板已带麦克风用途说明;fe-main 测试页增加 getUserMedia 音频按钮(需 https 安全源)。
## [1.0.0.63-SNAPSHOT] - 2026-09-16
> 📌 **本次仅发布 Android(Maven)**:`1.0.0.63-SNAPSHOT` 已发 Maven Central Snapshots(api / base / impl / supersdk / auth-google / pay-google / ad-admob 同批)。iOS xcframework **未重建**,`release_doc/supersdk/1.0.0-SNAPSHOT/iOS/` 保持既有产物;本批发版环境为 Linux,无 Xcode,iOS 源码(`SFeedback` + JSB)待 macOS 上 `xcodegen generate && xcodebuild … test` 验证后补发。
>
> 同批切换:`supersimples` Android 模板 `sdk.androidVersion` 从 `1.0.0.62-SNAPSHOT` 切到 `1.0.0.63-SNAPSHOT`。
### 用户反馈(Android / iOS / JSSDK 2.3.0 / Super Server / Console)
- **SDK 三端新增反馈提交 API**:JSSDK `SuperSDK.submitFeedback({ scene, subScene?, title, content, userId?, extra? }) → { feedbackId }`(端内走新共享 JSB `submitFeedback(callbackId, paramsJson)`,web 直连 `/v2/feedback`);Android `SFeedback.submit(FeedbackRequest, Callback)`(`com.supersdk.base.feedback`);iOS `SFeedback.submit(FeedbackRequest, completion:)`。SDK 自动补齐 `spid / env / device_id / platform / app_version / sdk_version / os_version / device_model`;`userId` 由调用方按次传入。
- **服务端**:Super Server 新增 `POST /superapi/v2/feedback`(+ `/api/v2/feedback`)代理到 console-main 公开入库 `POST /api/public/v2/feedback`(spid/env 语法 clamp → fail-closed 限流:每 IP 10 次/分钟、每项目 600 次/分钟 → 项目/环境解析 → 校验 → 入库 `console_user_feedback`,记录提交时间与用户 IP)。字段规则:scene ≤64、title ≤200、content ≤5000、sub_scene ≤64、user_id/device_id ≤128、extra JSON object ≤4KB。
- **控制台**:「业务运营」新增首项「用户反馈」(`/feedback`,同时成为业务运营落地页):按项目 × 环境列出 scene / sub_scene / user_id / device_id / title / 反馈时间 / 状态,支持标题/内容关键字、scene、状态筛选与服务端分页;点击行弹出详情(内容、用户 IP、平台/版本/机型、extra)并可「标记已处理 / 重新打开」。
- JSB 协议清单增至 53 个方法;`BridgeProtocol` 双端由 `protocol/v1.json` 重新生成。
## [1.0.0.62-SNAPSHOT] - 2026-09-02
> 📌 **本次仅发布 Android(Maven)**:`1.0.0.62-SNAPSHOT` 已在 Maven Central Snapshots(含 `querySubscriptionOffers`)。iOS xcframework **未重建**,`release_doc/supersdk/1.0.0-SNAPSHOT/iOS/` 保持 1.0.0.60 产物(`source_commit=40635ffd`)。本批发版环境为 Linux,无 Xcode。
>
> 同批切换:`supersimples` Android 模板 `sdk.androidVersion` 从 `1.0.0.60-SNAPSHOT` 切到 `1.0.0.62-SNAPSHOT`。
### Google Play eligible subscription offers(Android + JSSDK 2.2.0)
- 新增 `SuperSDK.pay.querySubscriptionOffers({ provider, productIds })`,只返回 `queryProductDetailsAsync()` 为当前 Play 账号给出的 eligible offers;结构包含 product/base plan/nullable offer ID/tags/title/description/pricing phases,**不含 `offerToken`**。
- 新增 Android 公共 DTO `SubscriptionOfferInfo` / `SubscriptionPricingPhase`,并贯通 `PayProvider → PayService → SDKPayService → PayBridge → AppBridge`;旧 provider/宿主通过默认 `NOT_SUPPORTED` 保持兼容。iOS 共享 JSB 仅返回 `NOT_SUPPORTED`。
- 订阅购买不再复用历史 `ProductDetails`:每次购买前重新查询 `ProductType.SUBS`,用 `productId + basePlanId + nullable offerId` 精确匹配最新 eligible offer,再把其 token 交给 `setOfferToken()`;资格变化返回 `OFFER_UNAVAILABLE`,不静默换价。
- 删除错误的 `new JSONObject(productDetails.toString())`;商品和 offer DTO 全部通过 BillingClient 公共 getter 构造,不依赖内部 JSON、反射或 `toString()`。
- 新增/收敛错误契约:`PRODUCT_NOT_FOUND`、`OFFER_UNAVAILABLE`、`BILLING_UNAVAILABLE`、`QUERY_FAILED`、`USER_CANCELLED`、`PURCHASE_FAILED`。错误与日志均不包含 offer token。
- `queryProducts()`、INAPP 购买和非 Google provider 的公开行为保持不变;Settings、UI 排序、Play Console 完整目录、业务创单/权益和服务端验单仍不在 SDK 范围。
## [1.0.0.61-SNAPSHOT] - 2026-08-31
### Google Play 订阅(`supersdk-pay-google` 外挂包)
- `google_play` provider 输入新增 `productType: "subs"`、必填 `basePlanId` 和可选 `offerId`;未传 `productType` 时继续按 `inapp` 处理,既有一次性商品购买兼容。
- 订阅商品改用 `ProductType.SUBS` 查询,并从 Google 返回的用户可用 `SubscriptionOfferDetails` 中精确匹配 `basePlanId + offerId`;省略 `offerId` 时选择该 base plan 自身的 offer。
- 匹配成功后向 `BillingFlowParams.ProductDetailsParams` 写入对应 `offerToken`;无匹配返回 `OFFER_UNAVAILABLE`,不拉起 Billing UI。
- `ITEM_ALREADY_OWNED` 的既有购买补偿查询跟随当前购买的 `productType`,订阅不再先查 `INAPP`。
- `google_play` 的 `restorePurchases` 仅查询订阅,不再合并一次性商品。
- 新增订阅查询、base plan/offer 选择、缺参/无匹配错误及恢复购买测试。
> 本版本仅变更 Android 外挂包与参数文档;SuperSDK 核心、`PayBridge` 和 JSSDK 运行逻辑未改。Maven 同批发布未修改的 `supersdk-api` / `supersdk-base`,仅用于满足 `supersdk-pay-google:1.0.0.61-SNAPSHOT` 的同版本传递依赖。
## [1.0.0.60-SNAPSHOT] - 2026-08-30
### 新增:统一 suenc 响应混淆能力(Android / iOS / JSSDK / Super Server 四端)
轻量响应混淆协议 `suenc`:客户端显式请求(`?suenc=1`)时,服务端用自定义 Base64 表编码 JSON 响应体并回 `X-Su-Enc: b64t1`,客户端在统一网络层透明解码。
> ⚠️ **只用于降低通用关键字扫描与规则匹配的有效性,不是加密**:不提供机密性、防篡改、防重放,也挡不住已取得客户端代码的攻击者还原编码表。
- **codec 单一数据源**:`packages/jssdk/protocol/suenc-v1.json` + 跨语言稳定向量 `suenc-v1-golden.json`,由 `scripts/generate-suenc-contract.mjs` 生成 JS / TS / Android / iOS 四端常量(`--check` 可校验生成物漂移)。编码表经 fail-closed 校验必须是标准 Base64 64 字符的合法全排列。**`b64t1` 发布后编码表永不可改,新表必须使用新的 codec key**。
- **SDK 内部请求自动解码**:settings / reportEvent / 归因 / 短链等全部覆盖;**非 2xx 响应同样先解码**再构造错误;同一响应最多解码一次。响应无 `X-Su-Enc` 时行为与此前完全一致。
- **SDK 自身不默认追加 `suenc=1`**:是否启用属于宿主与目标服务端之间的发布决策。宿主经新增的 `HostNetworkExtensionService`(双端,全部可选、默认不生效)为 SDK 内部请求注入扩展 query / header;**与 SDK 自有参数冲突时 SDK 值恒胜**(header 名大小写不敏感比较),宿主实现抛异常或返回非法值一律跳过并输出脱敏日志,绝不阻断主流程。
- **防明文降级**:本次请求带了 `suenc=1` 却收到无 `X-Su-Enc` 的响应时判定该线路失败(`SUENC_DOWNGRADE`),复用既有多 baseUrl 轮转切换下一条线路,**绝不把明文响应交给业务**。
- **对外 API**:JSSDK `SuperSDK.getSuEncCapabilities()` / `SuperSDK.decodeSuEnc(encodedData, codec)`(同步纯函数,不经 JSBridge);Android `SuperSDK.decodeSuEnc/getSuEncCapabilities`;iOS `SuperSDKManager.decodeSuEnc(_:codec:)/getSuEncCapabilities()`。错误码:`UNSUPPORTED_SUENC_CODEC` / `SUENC_DECODE_FAILED` / `SUENC_INVALID_UTF8` / `SUENC_DOWNGRADE` / `SUENC_RESPONSE_TOO_LARGE` / `SUENC_PROTOCOL_ERROR`。
- **Super Server**:新增响应编码中间件,仅对 `application/json` 与 `*+json` 生效,保留原状态码,非 JSON(attr.js / healthy / 短链跳转等)原样透传;`suenc` 参数在进入业务 handler 与转发上游前被剥离。
**兼容性**:不带 `suenc=1` 的请求与老客户端行为完全不变;新增宿主接口均为可选默认实现,既有接入方零改动。
## [1.0.0.59-SNAPSHOT] - 2026-08-30
> 📌 **双端发布**(版本号双端统一):本版本功能改动为 **iOS 侧**离线包加载机制;Android 为随版本重建(内容无功能变化)。
### 变更(iOS · 离线包请求级拦截)
- **离线包加载从 `loadFileURL` 改为自定义 scheme(`super-offline://`)请求级拦截**,对齐 Android `shouldInterceptRequest` 语义。此前离线命中走 `loadFileURL` 只映射主文档,用 `base:'/'`(绝对路径)+ History 路由构建的离线包(子资源落到文件系统根 → 404)会白屏;改造后页面跑在稳定的 `super-offline://{host}` origin 上,`/` 映射到包目录,每个子资源经 `OfflineSchemeHandler` 逐请求映射到本地文件,`base:'/'` 与 History 路由均成立。
- 命中响应对齐 Android:`200` + `Content-Type`(文本类型带 `charset=utf-8`)+ `Access-Control-Allow-Origin: *`;含 **SPA fallback**(无扩展名且不存在 → `index.html`)与**目录穿越守门**(解析后路径必须仍在包目录内);MIME 表对齐 Android 33 项。
- **顺带修复**:此前 `file://` 加载下 `getEnv()` 的 `wappVersion` 恒空的隐患(现 `webView.url` 为 scheme,`getPackageForUrl` 直接命中)。
- ⚠️ **iOS 离线页 origin 变为 `super-offline://{host}`(非真实域名、非 secure context)**:接入方注意——① 若离线页依赖 Service Worker / WebCrypto,本 scheme 不支持(`super-offline://` 非安全上下文);② 离线页打自家后端 API 为跨域,需后端返回 CORS 头(带 cookie 凭据时不能用 `*`,需回显 origin + `Allow-Credentials`);③ 经 fetch/XHR 发往本 scheme 的 POST/PUT body 会被 WebKit 丢弃,API 应走绝对 https URL。
## [1.0.0.58-SNAPSHOT] - 2026-08-30
> 📌 **双端发布**:本版本在 macOS 上重建并发布 iOS xcframework(1.0.0.54 起累计欠付的 iOS 产物在本版收口,包含 1.0.0.55~57 的全部 iOS 侧源码变更)+ Android Maven。
> iOS 相对 Android 的 JSBridge 功能缺口自本版清零。
### 新增(iOS)
- **`showRewardedInterstitialAd` JSB**:补齐 iOS 实现(此前仅 Android 支持)。宿主注入模式:`AdService` 协议新增 `loadRewardedInterstitialAd`(带默认实现,老宿主 provider 零改动兼容),未注入时回 `NOT_IMPLEMENTED`。行为与 Android 对齐:全屏广告互斥(`AD_ALREADY_SHOWING`)、`{dismissed, rewarded}` 回调。
- **`ShareController` 原生短链 API**:`SuperSDKManager.getShareController()` 提供 `requestShortUrl` / `requestShortUrlWithHtml`(支持自定义 `baseUrl` 前缀),与 Android `SuperSDK.getShareController()` 对齐;`ShareBridge` 短链 JSB 改为委托同一实现(与 Android 架构一致)。H5 系统分享(`UIActivityViewController`)本就内置,无需宿主注入。
### 修复(iOS)
- **`SReporter` 重复 `asyncFlush()` 编译错误**:1.0.0.55(Android-only 发版、无 macOS 编译验证)误增 internal 重复声明,导致 iOS 源码此后无法编译。移除重复版,保留与 Android 语义一致的 `asyncFlush() → flush()`(先落盘再上传)。
- **`SuperSDKTests` 目标补 `GENERATE_INFOPLIST_FILE: YES`**(`apps/ios/project.yml`):新版 Xcode 下 `xcodebuild test` 可直接运行。
### 文档
- `JSSDK.md` 的 `showRewardedInterstitialAd` 移除「当前仅 Android 原生桥支持」注记(双端已对齐)。
- iOS README 新增 `ShareController - 短链生成` 章节。
## [1.0.0.57-SNAPSHOT] - 2026-08-17
> 合并发布:`feat/sdk-api-environment`(项目环境运行时化)合入 staging
>
> 本版本 = **1.0.0.55 的项目环境运行时化** + **1.0.0.56 的 deviceId 隐私合规整改**,
> 两者此前分别只发在各自分支上,从未同时存在于一个产物中。接入方请直接用本版本,
> 不要再用 1.0.0.55 / 1.0.0.56(各缺一半)。
>
> 📌 **本次仅发布 Android(Maven)**:iOS 侧源码与文档均已就绪,但未重建 xcframework,
> `release_doc/supersdk/1.0.0-SNAPSHOT/iOS/` 保持既有产物不变。iOS 需在 macOS 上另行
> 执行 `bash scripts/publish.sh --platform ios` 出包(1.0.0.54 起累计欠 iOS 产物)。
### 同批切换
- `supersimples` Android 模板与相关断言从 `1.0.0.55-SNAPSHOT` 切到 `1.0.0.57-SNAPSHOT`(`test_sdk_identity_contract` 守卫钉死「模板版本 == VERSION_CODE 推导值」)。iOS 模板/mock 仍 pin 1.0.0.54 旧签名、锚点保持临时分裂,待 iOS 产物补发后同批收口。
### 本版本包含
- 1.0.0.55-SNAPSHOT 的全部内容(init 移除 `environment` 参数 · `setAPIEnvironment`/`getAPIEnvironment` · JSSDK 2.1.0 · `getNetEnv`/`ApiEnv` 废弃)——详见下方 1.0.0.55 条目,**破坏性变更与迁移示例同样适用于本版本**。
- 1.0.0.56-SNAPSHOT 的全部内容(移除 `ANDROID_ID` 读取 · `HostConfigService.generateDeviceId()`)——详见下方 1.0.0.56 条目。
## [1.0.0.56-SNAPSHOT] - 2026-08-17
> 设备标识隐私合规整改(Android)+ 宿主接管 deviceId 生成(双端 API)
>
> 📌 **本次仅发布 Android(Maven)**:iOS 侧 `generateDeviceId` 源码与文档已就绪,但未重建
> xcframework,`release_doc/supersdk/1.0.0-SNAPSHOT/iOS/` 保持既有产物不变。iOS 需在 macOS 上
> 另行执行 `bash scripts/publish.sh --platform ios` 出包。
### 隐私合规(Android · 设备标识)
- **移除 `Settings.Secure.ANDROID_ID` 读取**:应监管「未见明示,APP 存在收集 AndroidID 的行为 / 请求携带 AndroidID」通报整改。`SDevice.getOrCreateDeviceId` 不再读取 ANDROID_ID,deviceId 默认**自生成随机 UUID 并持久化到 SP**。
- deviceId 降级链变更为:**内存缓存 → SP 持久化值 → 宿主 `generateDeviceId()` → SDK 自生成 UUID**。全链路不读取 ANDROID_ID / IMEI / MAC / OAID 等系统设备标识。
- **存量老用户不受影响**:旧版本写入 SP 的 16-hex 值继续沿用(`isValidAndroidId` 改名 `isLegacyHexDeviceId`,仅作存量沿用判定),避免设备标识断层造成归因/留存断点;BUG-SDK-B001 的退化值拦截(全零 / 全同字符 / Froyo 碰撞值 / 非 hex / 长度异常)原样保留。
- iOS 不涉及:`identifierForVendor` 是 Apple 官方厂商标识,不在通报条款内,行为不变。
### 新增(双端 · 宿主接管 deviceId)
- `HostConfigService` 新增可选方法 `generateDeviceId()`(Android `@Nullable String` / iOS `String?`,均有默认实现,**不破坏既有宿主接入**)。
- 仅在 SDK 需要**生成新 deviceId** 时调用(首装或本地旧值失效),已持久化的 deviceId 继续沿用;返回非空字符串即被采用并持久化(Android 落 SP,iOS 落 Keychain),返回 `null`/`nil`/空串走 SDK 默认逻辑。
- 宿主来源的 ID 允许自定义格式,仅拒绝空白值(不套用 SDK 侧形态校验,避免自定义格式被误判退化丢弃)。
- 实现要求:**同步快速返回**(可能在网络请求/事件上报路径早期调用)、多次调用返回稳定值;宿主实现抛异常时 SDK 捕获并回退默认逻辑。
## [1.0.0.55-SNAPSHOT] - 2026-08-15
> 📌 **本版本 Android Maven 已发布;iOS xcframework/SPM 包需在 macOS 上另行
> `bash scripts/publish.sh --platform ios` 构建发布**(本批发布环境无 Xcode,与 1.0.0.54 先例一致)。
> supersimples **Android** 模板已同批切换到本版本与新 API;**iOS** 模板与 MockSuperSDKPackage
> 仍镜像 1.0.0.54 旧签名(`test_ios_spm_template.py` 中锚点临时分裂),待 iOS 产物发布后同批切换并统一锚点。
> 发布文档版本目录(`release_doc/supersdk/1.0.0-SNAPSHOT/`)刷新同样留待 iOS 产物就绪后执行,避免复制旧二进制。
### 破坏性变更
- **init 移除 environment 参数**:Android 删除 `init(context, spid, environment, provider)` 重载,只保留 `init(context, spid, provider)`;iOS `initialize` 同步移除 `environment:` 参数。项目环境改为独立的运行时状态,init 不再触碰它。
### 新增
- **`setAPIEnvironment(environment)` / `getAPIEnvironment()`**(Android `SuperSDK` 静态方法 / iOS `SuperSDKManager` 实例方法):对应控制台顶栏 env,运行时可随时切换(init 前后均可)。SDK 不持久化,进程启动默认 `prod`,宿主自行持久化并在启动后 set。切换副作用:冲刷旧环境存量上报事件 → 换值 → settings 清缓存并按新环境重拉 → 刷新存活 WebView UA。settings 拉取(`env` 参数)、上报(`basic_data.env` + `X-Super-API-ENV` 头)、UA `ProjectEnv/`、JSB `getEnv()` 全链路动态跟随。
- **JSSDK 2.1.0**:同名 Promise 接口。web 降级模式生效(切换前冲刷待发事件,settings 请求缓存按环境天然隔离);端内 set reject `UNSUPPORTED`(环境由原生宿主控制)、get 透传原生值。
### 废弃
- `HostConfigService.getNetEnv()` 与 `ApiEnv`(Android `@Deprecated` / iOS 文档标注):该「API 网络环境」维度从未被 SDK 消费。项目环境用 `setAPIEnvironment`,API 域名用 `getSdkApiBaseUrls()`。
### 迁移示例
- Android:`SuperSDK.init(context, "ab12cd34", "prod", provider)` → `SuperSDK.setAPIEnvironment("prod"); SuperSDK.init(context, "ab12cd34", provider)`
- iOS:`initialize(spid:environment:provider:)` → `try setAPIEnvironment("prod"); try initialize(spid: "ab12cd34", provider: provider)`
- JSSDK web:`initFallback({ spid, environment })` 不变(作为初始值);运行时切换用 `await SuperSDK.setAPIEnvironment('staging')`
## [1.0.0.54-SNAPSHOT] - 2026-07-30
> BREAKING: 三端项目身份统一为 `spid + environment`
>
> 📌 **Android 产物实际补发于 2026-08-09**:2026-07-30 完成的是代码与文档,`vars.properties`
> 的 `VERSION_CODE` 当时停在 1000053、Maven 发布未执行,因此 `1.0.0.54-SNAPSHOT` 长期不存在,
> 而 SIMP 模板已 pin 到它 —— 生成的工程 android 端依赖解析 404、开箱即挂。现已补发,并新增
> 离线守卫(`supersimples/tests/test_sdk_identity_contract.py`)钉死「模板版本 == VERSION_CODE
> 推导值」,防止再次漂移。iOS xcframework 需在 macOS 上另行 `bash scripts/publish.sh --platform ios`。
### 破坏性变更
- Android 初始化由 `init(context, aid, provider)` 改为 `init(context, spid, environment, provider)`;iOS 由 `initialize(aid:provider:)` 改为 `initialize(spid:environment:provider:)`。`spid` 必须是控制台签发的 8 位小写字母/数字,显式 `environment` 必须是 1–10 位小写字母/数字,省略环境时默认为 `prod`。
- JSSDK 浏览器兜底改为 `initFallback({ spid: 'ab12cd34', environment: 'prod' })`,不再接受旧 `aid`。初始化先完整校验候选配置,再一次性提交;失败不会污染既有配置。
- JSB `getEnv()` 从 `aid` 切换到 `spid + environment`;UA 字段从 `HostAid` 切换到 `HostSpid + ProjectEnv`;settings 查询参数从 `aid` 切换到 `spid + env`。
- Web 上报体使用 `basic_data.host_spid` 与 `basic_data.env`,不再伪造原生语义的 `basic_data.app_id`,也不再发送 `host_aid`。兼容请求头名仍为 `X-Aid`,但值为 `spid`,并新增 `X-Super-API-ENV`;不新增 `X-Spid`。
- SIMP 根配置从 `app_id` 迁移为 `spid + environment`,并由同一根值投影到 Android `BuildConfig`、iOS `SimpleConfig` 与 Web `initFallback`。
### 迁移示例
- Android:`SuperSDK.init(context, "ab12cd34", "prod", provider)`
- iOS:`try SuperSDKManager.shared.initialize(spid: "ab12cd34", environment: "prod", provider: provider)`
- JSSDK:`SuperSDK.initFallback({ spid: 'ab12cd34', environment: 'prod' })`
示例中的 `ab12cd34` 仅展示合法形态,接入时必须替换为控制台签发的真实 `spid`。原生事件中的 `basic_data.app_id` 与 AdMob App ID 是各自独立概念,不得机械改名。`release_doc/**/1.0.0-SNAPSHOT/**` 为历史发布快照,本次迁移不回写。
## [1.0.0.53-SNAPSHOT] - 2026-07-25
> Android AdMob 可选 Provider 与 Rewarded Interstitial H5 桥接
### 新增
- **独立 AdMob Provider**:新增 `com.supersdk:supersdk-ad-admob`,传递 Google Mobile Ads `25.4.0`,完整实现 Rewarded、Interstitial、Banner、Native、Rewarded Interstitial 五类原生 `AdService`,核心 `supersdk` 不携带广告依赖。
- **Rewarded Interstitial JSBridge**:Android 新增 `showRewardedInterstitialAd(config, callbackId)`,JSSDK 新增 `SuperSDK.showRewardedInterstitialAd(options)`;返回 `{ dismissed, rewarded }`,沿用全屏广告并发与唯一终态保护。
### 接入要求
- H5/宿主调用 Rewarded Interstitial 前必须先展示奖励内容说明和可跳过的 intro;旧 Android 桥或不支持平台由 JSSDK 立即返回 `NOT_SUPPORTED`。
- 补充宿主 App ID、五类 Ad Unit ID、隐私同意、Provider 注册、资源生命周期及真机验收清单。
## [1.0.0.52-SNAPSHOT] - 2026-07-24
> Google Play Billing 9 合规升级与离线包远程更新(Android / iOS / JSSDK)
### 新增
- **离线包远程清单 v1**:Android / iOS 打开页面时可在后台探测站点根路径的 `super_meta.json`,按版本、大小、MD5、同源路径及包内清单完成安全下载与安装;失败不影响当前页面,成功后在下次加载时生效。
- **显式预加载接口**:双端提供 `preloadPackage` / `preloadAllPackages`,支持宿主主动检查并安装离线包;同步补充 `OFFLINE_PKG_SPEC.md` 与打包脚本产物。
### 变更
- **Google Play Billing Library 升级到 9.1.0**:更新 `supersdk-pay-google` 的 Billing 依赖及一次性商品 offer 兼容逻辑,满足 Google Play Billing Library 8.0.0+ 要求;购买、恢复购买及错误回调契约保持不变。
- **离线包接口语义统一**:Android / iOS 的 `updatePackage*` 更名为 `preloadPackage*`,与“预先下载安装、下次加载生效”的行为一致。
## [1.0.0.51-SNAPSHOT] - 2026-06-22
> WebView 底部沉浸开关(Android / iOS)
### 新增
- **`setImmersiveBottom` 底部沉浸开关**:Android / iOS 的 `SuperPageView` 新增底部沉浸控制,默认 `true` 保持现有行为;置 `false` 时 WebView 内容缩短到底部安全区/系统导航栏之上,同时页面 `env(safe-area-inset-bottom)` 与 UA `SafeAreaBottom` 归零,适合 YouTube 等第三方站点底栏贴合系统栏、避免遮挡或多余白边。仅作用底部,顶部仍保持沉浸。
## [1.0.0.50-SNAPSHOT] - 2026-06-21
> 三端事件上报迁移到自有事件管道 v2 端点(Android / iOS / JSSDK)
### 变更
- **事件上报端点迁 v2**:Android / iOS / JSSDK 三端事件上报由 `/superapi/rptEvent` 切换到 `/superapi/v2/reportEvent`,激活 SuperSDK 自有事件管道(服务端按上报体 `host_aid` 的 `app_` 前缀内容路由:`app_` 应用进自建 collector / 其余仍降级 legacy,零现网影响)。
- **JSSDK `event_param` 改为对象上报**:`reportEvent(name, params)` 的 `params` 由 JSON 字符串改为 JSON 对象上报(与 Android / iOS 对齐,满足自建 collector 严格校验;非对象入参一律规整为 `{}`)。
## [1.0.0.49-SNAPSHOT] - 2026-06-21
> SDK 自身 settings 去耦(Android / iOS / JSSDK)
### 变更(⚠️ Breaking)
- **移除 JSSDK `getSDKSettings()` / `getSDKSettingsByKey()`**:SDK 自身动态能力不再复用宿主业务 settings 通道,后续如需 SDK 专有动态能力走专有接口。
- **移除端上 `getSDKSettingsAsync` / `getSDKSettingsByKeyAsync` JSB**:Android / iOS 不再向 H5 暴露 SDK 自身 settings。
- **离线包不再从 settings 读取 `offline_pkg` 自动同步**:保留已缓存离线包加载与显式下载/安装能力,移除通过宿主/SDK settings 驱动离线包更新的耦合路径。
- **`/v2/settings` 数据形态与历史 settings 对齐**:服务端 v2 成功响应包回 `{code:"SUCCESS",msg:"",data:<配置>}`;Android / iOS 对 raw v2 响应也会本地归一化为该 envelope,按 key 读取兼容 `data[key]`。
- **`SSettings.createSettings(namespace)` 不再推导远端 `configName`**:namespace 仅用于本地缓存 / 内置配置隔离,避免历史用法 `createSettings(SEnv.getAid())` 生成 `configName=`;显式远端配置名请使用 Android `createSettingsWithConfigName(configName)` / iOS `createSettings(configName:)`。
## [1.0.0.48-SNAPSHOT] - 2026-06-21
> 宿主云控配置 configName 修复(Android / iOS / JSSDK)
### 修复
- **宿主配置不再把 `aid` 当作 `configName`**:`getHostSettings()` / `getHostSettingsByKey()` 无参请求不带 `configName`,`aid` 仅作为应用标识参数。
- **JSSDK 支持显式配置名**:新增可选参数 `getHostSettings(configName?)`、`getHostSettingsByKey(key, configName?)`,端上优先走新增 JSB 方法并透传配置名称。
- **兼容旧 JSB**:保留原 `getHostSettingsAsync` / `getHostSettingsByKeyAsync`,旧调用路径也不再带 `configName`,避免生成 `configName=`。
## [1.0.0.46-SNAPSHOT] - 2026-06-21
> openPage 对外接口调整:容器托管 → URL 路由(双端 · ⚠️ Breaking)
### 变更(容器导航 · 双端一致 · ⚠️ Breaking)
- **`NavigationService` 接口由「SDK 给容器」改为「给 URL,宿主决定怎么打开」**:宿主拿到 `url + PageConfig`,返回 `true`=已自行处理 / `false`=交回 SDK 默认容器打开(选择性拦截 + SDK 兜底,类似 `shouldOverrideUrlLoading`)
- Android:`boolean openPage(Context, String url, PageConfig)`
- iOS:`func openPage(url: String, config: PageConfig) -> Bool`
- 宿主若仍想用 SDK 的 WebView 容器,自取 `getPageController().createPageView()` 后 `load(url)` 再自行展示(可设 `setOnClosePageListener` / `onClosePageListener` 响应 H5 `closePage`)
- **移除 `PageControlHandler`(两端)**:契约不再返回控制句柄;SDK 默认页(`SuperPageActivity` / `SuperPageViewController`)关闭改为页面自接管(`OnClosePageListener → 关闭自身`),前端 `appbridge.closePage()` 行为不变
- **移除 `DefaultNavigationService`(两端)**:默认打开逻辑内联回承载页
- **前端 `appbridge.openPage(url, config)` / `SuperSDK.openPage` 调用方式不变**;无新增 JSB
### 迁移指引
- 旧实现 `openPage(context, container, config) → PageControlHandler`:改为 `openPage(context/url, config) → boolean/Bool`;原先「摆放 container」的逻辑改为自取 `createPageView()` 并 `return true`,不接管则 `return false`
## [1.0.0.45-SNAPSHOT] - 2026-06-20
> WebView 视频全屏 + 底层 WebView 透出 + 返回键修复(Android)
### 新增(容器能力 · Android)
- **WebView 内 HTML5 视频支持全屏播放**:`SuperWebview` 的 `WebChromeClient` 实现 `onShowCustomView`/`onHideCustomView`,通过 `SViewUtils.findActivity` 从视图树回溯宿主 Activity(兼容用 application context 创建的 WebView),将视频挂到 Activity `decorView` 全屏 + 沉浸式隐藏系统栏
- **自适应横屏**:仅当宿主 Activity 在 manifest 声明 `configChanges=orientation|screenSize` 时才强制横屏(`SuperPageActivity` 满足;否则维持当前朝向,避免 Activity 重建中断播放)
- 返回键全屏中优先退出全屏;`onDetachedFromWindow` 清理残留全屏视图防泄漏
- iOS 原生已支持视频全屏(`allowsInlineMediaPlayback`),本次为 **Android 独有平台差异**
- **`AbsSuperPageView.getWebView()`**:透出底层 `WebView` 实例,供宿主直调 `evaluateJavascript` / `settings` 等原生能力(对齐 iOS `pageView.webView`)
- ⚠️ 勿替换 `WebViewClient`/`WebChromeClient` 或重置 `settings`,否则会破坏内置 JSBridge 与离线包拦截
### 修复(返回键 · Android)
- **Demo `MainActivity` 返回键改走 `handleBackPressed`**:此前裸用 `canGoBack`/`goBack` 会绕过前端拦截(`JSBridge.onBackPressed`),现与官方文档示例一致(优先级:前端拦截 > 页面历史回退 > 退出)
## [1.0.0.44-SNAPSHOT] - 2026-06-20
> WebView 识别 `target="_blank"` / `window.open` 统一走 openPage(双端)
### 新增(容器导航 · 双端一致)
- **H5 的 `` 链接与 `window.open(url)` 现会被容器自动识别,统一通过 `openPage` 在端上以新页打开**(等价 `appbridge.openPage`,并走宿主自定义 `NavigationService`);H5 无需额外适配
- Android:开启 `setSupportMultipleWindows` + `setJavaScriptCanOpenWindowsAutomatically`;`WebChromeClient.onCreateWindow` 用临时 WebView 截获目标 URL 后转发 `NavigationBridge.openPage`
- iOS:设置 `uiDelegate`,`WKUIDelegate.createWebViewWith` 在 `targetFrame == nil` 时转发 `openPage` 并返回 `nil`(不创建新 WKWebView)
- 边界:极少数 `window.open()` 先开空白页再 `document.write` 的写法拿不到 URL(忽略),与「跳转到新页」语义不冲突
- **无对外 API 签名变更**(无新增 JSB);Demo `fe-main` 页面导航组新增 `_blank` / `window.open` 回归测试项
## [1.0.0.43-SNAPSHOT] - 2026-06-06
> deviceId 退化值修复(Android)
### 修复(设备标识 · Android · SDK-B001-deviceId-000)
- **修复线上部分用户 `deviceId` 返回退化值("000" / 全零类)且永久不变**:`SDevice.getOrCreateDeviceId` 原本仅过滤单个已知坏 `ANDROID_ID`(`9774d56d682e549c`),未拦其它退化值,叠加缓存优先导致永久固化
- ANDROID_ID 校验由黑名单单值升级为**规则集** `isValidAndroidId`(16 位 hex + 非已知坏值集 + 非全同字符 + 全 hex)
- 新增 `isDegenerateDeviceId`:读缓存时检出退化值(既非合法 ANDROID_ID 也非 UUID)→ 丢弃重生成,**让历史中招用户自愈**
- 退化 ANDROID_ID 命中时埋点(脱敏 · 仅长度)确认线上分布
- iOS 不受影响(`identifierForVendor` 系统 UUID)· 知识沉淀 KNOWLEDGE G-deviceId-001
- ⚠️ 中招用户 deviceId 由退化值变为新 UUID(一次性归因断点 · 纠正优先)
## [1.0.0.42-SNAPSHOT] - 2026-06-05
> Google 登录修复(Android)
### 修复(Google Sign-In · Android)
- **修复首次登录/新 client 直接抛 `NoCredentialException("No credentials available")`、连账号选择器都不弹**:`GoogleAuthProvider` 由 `GetGoogleIdOption`(One Tap 静默资格检查)改用 `GetSignInWithGoogleOption`(显式 "Sign in with Google" 按钮流,强制弹账号选择器)
- **提升登录失败可观测性(SDK-B001)**:`GoogleAuthProvider.onError` 不再吞掉 `GetCredentialException` 的结构化类型,回传 `type= class=<子类> msg=`;`LoginBridge` 失败回调补 `SLogger.e` 落 logcat(此前失败仅有 AndroidX 框架的泛化日志,无法定位精确原因)
### 说明
- 本次改动均为 **Android 平台特有**(Credential Manager API);仓内无 iOS Google 登录 provider,iOS `xcframework` 无对等改动,沿用上版二进制。
- 无对外 API 签名变更(JSSDK / Android README 接口不变)。
## [1.0.0.41-SNAPSHOT] - 2026-06-01
> SDK-F038 · 统一支付契约(SDK 退回哑管道)
### ⚠️ 破坏性变更(SDK-F038)
- **支付契约统一为 provider 两方法 + SDK 哑管道**:provider = `{ createOrder(payParams)→json, pay(json)→三态 }`,参数对 SDK 传输层**不透明**,SDK 仅按 `provider` 名路由 + 透传 JSON(不再解析 productId/accountId/profileId)
- `pay.purchase({provider, payParams})` 内部聚合 `createOrder→pay`;不新增 `createAndPay`
- **返回由 `PurchaseResult` 改为三态** `PayResult3State`:`{ status: finished|cancelled|error, orderToken?, phase?, code?, message? }`;`finished ≠ 成功`(去业务查单);**凭证不出 Native**
- **JSB 由位置参数改为通用管道** `nativePay(provider, jsonString, callbackId)`;老 SDK 无 `nativePay` → `pay.purchase` reject `SDK_TOO_OLD`
- 现网 H5 必须配套升级(不留旧返回 alias);`restorePurchases` 契约保持 F036 不变
- **IAP**:业务只实现 `createOrder`,`pay` 由 SDK 内置 `google_play`/`apple` provider(原生扣款·自读 json);**三方**业务自写 `createOrder + pay` 两方法
- **凭证守门**:`provider.pay` 把凭证返回 PayBridge → PayBridge 投宿主配置回执端点 + 白名单剥离三态给 H5;后端独立验签;Google RTDN / Apple ASSN 兜底
- **IAP 双端订单槽**:Android `obfuscatedAccountId`(accountId) + `obfuscatedProfileId`(orderToken) / iOS `appAccountToken`(orderToken);**orderToken 必须 UUID**(内置 google provider 校验,非 UUID → `INVALID_ORDER_TOKEN`)
### 说明
- iOS:本 snapshot iOS `xcframework` **暂未重建**(仍为上一版二进制 · 未含 F038 iOS 改动)· 待独立 iOS 出包流程重建后补齐;Android AAR / JSSDK 已含 F038。
## [1.0.0.40-SNAPSHOT] - 2026-06-01
> 累积 .39 之后的所有 SDK 改动(Pay namespace 重构 + JSSDK 文档与封装补全)
### ⚠️ 破坏性变更(SDK-F036)
- **JS SDK 支付能力重构为 `SuperSDK.pay` 命名空间**,删除 7 个顶层支付 API
- 新增 `SuperSDK.pay` 命名空间:`purchase` / `getProviders` / `registerProvider` / `restorePurchases`
- `purchase` 入参签名由 `productId` 改为 `payParams`(嵌套结构)
- 新增 `_webInlineInProgress` 守门,避免 Web inline 购买并发
- 详见 `JSSDK.md` § 支付 的「迁移指南」与错误码说明
### 新增(SDK-F037)
- JSSDK 新增 3 个 JSB 前端封装:`addEventCommonParam` / `setStatusBarDarkMode` / `showKeyboard`
- `onJSBridgeReady` 内部注释标注
### 文档(SDK-F037 / SDK-M001)
- `pay.purchase` / `restorePurchases` 返回值 10 字段表 + `purchaseState` 枚举 + Native/Web inline 两路径差异说明
- Settings 返回结构与降级说明;3 个新方法文档 + API 概览登记
- 修正 JSSDK 文档与代码 6 处误差:
- IAP 推荐架构示例改用嵌套 `payParams`(原扁平结构会触发 `INVALID_PARAMS`)
- `pay.purchase` 超时 120s → 190s(与 Native IAP 实际值对齐)
- 清理超时清单中已删 API、修正老命名为 `pay.*`、补全 `requestLogin` 与广告四件套
- `initFallback` baseUrl 说明澄清 `/superapi` 自动补全
## [1.0.0.39-SNAPSHOT] - 2026-05-24
> 累积 .36 之后的所有改动(.37/.38 未单独 cut)
### 新增
- **Pay Bridge**:新增多 provider 购买能力 · Android + iOS + JS 三端
- `SuperSDK.purchase(...)` 支持 GooglePayProvider 等多 provider
- 新增 `onProgress` 回调 · 支持轮询进度 UI
- JS 端购买超时与原生对齐(190s)· `GooglePayProvider.purchase` 串行化避免并发
- **SDK-F034**:`SNetwork` commonHeaders 自动注入 `X-Aid` + `X-Device-Id` 用于归因关联
- **SDK-F001**:Android WebView 容器补 `` 支持
- 补 `onShowFileChooser` override + Activity Result API 通路
- 支持 `accept` / `multiple` / `capture` 属性透传 + 取消 / 拒权降级
- 拍照路径走 FileProvider(子类 `SuperSdkFileProvider` 避免与宿主 manifest 合并冲突 · authority `${applicationId}.supersdk.fileprovider`)
- 接入 0 成本:`SuperPageActivity` 自动注入 `IFileChooserHost`
- 宿主自包装路径:`IFileChooserHost` action API(3 方法)
- iOS WKWebView 默认支持 · 本次不改 iOS 代码
### 变更
- Android SDK 依赖升级:`appcompat` 1.1.0 → 1.6.1 · 新增 `androidx.activity` 1.6.1 + `androidx.core` 1.9.0(解锁 Activity Result API)
### 文档
- JSSDK 文档同步 Pay Bridge `purchase` / `onProgress` 接口
- 新增 `IFileChooserHost` 接入文档(Android SDK 宿主自包装路径)
## [1.0.0.36-SNAPSHOT] - 2026-05-01
### 新增
- 新增 `downloadWithCache(fileUrl, fileMd5, cacheTts, fileCacheKey?)` JSB/JSSDK API,支持下载并缓存文件,缓存命中时直接返回本地文件路径
- Android/iOS 双端实现缓存命中、TTL 过期、MD5 校验、临时文件清理与元数据安全校验
- 缓存 key 优先使用 `fileCacheKey`;未传或为空时使用去掉 query 的 URL
### 文档
- JSSDK/JSBridge 文档补充 `downloadWithCache` 参数、返回值、缓存策略与异常行为
## [1.0.0.35-SNAPSHOT] - 2026-04-21
### 变更
- 埋点上报支持多 base URL fallback:服务端 5xx 或网络失败时自动切换到下一个 base URL,提高上报稳定性
- 埋点事件新增 `new_user_today_utc8` 公参:按 UTC+8 判断是否为当天新增用户,今日新增为 `1`,否则为 `0`
## [1.0.0.34-SNAPSHOT] - 2026-04-09
### 修复
- Android 10 以下系统导航栏高度适配:`getSafeAreaInfo` 在低版本设备正确返回虚拟导航栏高度,不再固定返回 0
## [1.0.0.33-SNAPSHOT] - 2026-04-08
### 新增
- Debug 模式下 WebView 允许远程调试(Android: Chrome DevTools, iOS: Safari Web Inspector)
- 双端同步:Android `WebView.setWebContentsDebuggingEnabled(true)`,iOS `isInspectable = true`(iOS 16.4+)
## [1.0.0.32-SNAPSHOT] - 2026-04-06
### 修复
- 离线包 SPA 路由 fallback:前端路由(如 `/home`)在刷新时未命中离线包,现在无扩展名路径自动 fallback 到 `index.html`
- 双端(Android + iOS)同步修复
## [1.0.0.31-SNAPSHOT] - 2026-04-06
### 变更
- 双端 SDK API 路径从 `/api/` 迁移到 `/superapi/`,与服务端路由演进方向一致(F030)
- 涉及:事件上报、云控配置、归因获取、短链生成/HTML 直出,共 8 文件 12 处
## [1.0.0.30-SNAPSHOT] - 2026-04-06
### 新增
- Debug 模式:双端 `HostConfigService` 新增 `isDebugMode` 接口,宿主可选开启 debug 模式
- Debug 模式:开启后网络请求失败时打印完整请求信息(URL、body、header、响应内容)
- Android `SEnv.setDebug(boolean)` 支持手动覆盖 debug 开关
- Android `SEnv.isDebug()` 优先级:setDebug > HostConfigService.isDebugMode > false
- iOS `SEnv.isDebug` 优先级:#if DEBUG > HostConfigService.isDebugMode > envType
## [1.0.0.29-SNAPSHOT] - 2026-04-03
### 新增
- JSSDK 非端环境降级支持:新增 `initFallback(config)` 初始化降级配置,使前端项目在浏览器中也能正常运行和调试(F-JSSDK-001)
- 新增 `isFallbackMode()` API,判断当前是否处于降级模式
- 页面导航类 API 降级为浏览器原生行为(window.open/close)
- UI 反馈类降级为 console.log 输出
- 环境配置类 API 在非端环境返回默认空值(不再 reject)
- reportEvent 降级为 fetch 直接 HTTP 上报(含 source: web_fallback 标记)
- 不可降级 API 统一错误信息为 "Not in app environment"
- deviceId 自动生成并持久化到 localStorage
## [1.0.0.27-SNAPSHOT] - 2026-02-25
### 新增
- JSB 短链生成支持自定义 base_url:`requestShortUrl(url, baseUrl?)` 和 `requestShortUrlWithHtml(html, baseUrl?)` 新增可选 `baseUrl` 参数,支持自定义短链前缀(如 `https://s.a.com/`),不传保持默认行为(F021)
- Android/iOS/前端 SDK 全链路支持,向后兼容
## [1.0.0.26-SNAPSHOT] - 2026-02-23
### 变更
- JSSDK 文档审计修正:`callHostMethod` 补充无超时说明,注意事项中的超时说明改为各方法分类列表(5s/10s/30s/60s/无超时)
## [1.0.0.25-SNAPSHOT] - 2026-02-23
### 新增
- 离线包构建时间:`OfflinePackageState` 新增 `buildTime` 字段(秒级时间戳),`getEnv` 返回 `wappBuildTime`
- 前端打包工具 `super_package.sh` 自动写入 `build_time` 到 `__super_meta.json`
### 变更
- Demo App 简化为单页面 SuperSDK 集成示例,移除更新检查、宿主 Settings、多 Tab、分享等逻辑
## [1.0.0.24-SNAPSHOT] - 2026-02-22
### 新增
- 短链 HTML 直出:`requestShortUrlWithHtml(html)` 通过 HTML 内容生成短链,访问短链直接渲染 HTML 页面(不做 302 跳转)
- 服务端新增 `POST /api/shorturl/html` 接口,支持 HTML 内容存储与直出
- Android/iOS/前端 SDK 全链路支持
## [1.0.0.23-SNAPSHOT] - 2026-02-19
### 修复
- JSBridge Ready 可靠性:onPageFinished 时检测 JSBridge 是否 ready,未 ready 则主动重试触发
- JSBridge Ready 可靠性:消息被 buffer 时延迟 500ms 重试触发 JSBridge ready,防止回调永久卡死
- JSBridge Ready 可靠性:AppBridge.onJSBridgeReady 中 webview 引用为 null 时增加错误日志
## [1.0.0.22-SNAPSHOT] - 2026-02-15
### 新增
- getEnv 新增 wappVersion 字段,返回当前 WApp(离线包)版本号,非离线包页面返回空字符串
## [1.0.0.21-SNAPSHOT] - 2026-02-15
### 变更
- OfflinePackageState 精简:移除 status、remoteVersion、updateAvailable 字段,仅保留 host、localVersion、source
- OfflinePackageState 精简:移除 Status 枚举(Android)/ OfflinePackageStatus 枚举(iOS)
- OfflinePackageState 精简:getAllPackages/getPackage/getPackageForUrl 仅返回状态正常的离线包
- OfflinePackageState 精简:Source 枚举新增 MANUAL,区分外部手动安装的包
## [1.0.0.20-SNAPSHOT] - 2026-02-15
### 修复
- 离线包并发安全:临时文件名加 UUID 防冲突,避免多个下载任务写同一文件
- 离线包并发安全:MD5 计算前增加文件存在性检查,避免 FileNotFoundException
- 离线包并发安全:Android status 状态修改移入 per-host 锁,修复防重入失效问题
- 离线包并发安全:iOS 新增初始化等待机制(NSCondition,10s 超时),与 Android 对齐
- 离线包并发安全:下载安装前增加版本比较,防止云控旧版本覆盖已安装的新版本(版本降级)
- 离线包并发安全:目录替换改为原子 rename 交换,避免 WebView 加载时文件被删除导致 FileNotFoundException
## [1.0.0.19-SNAPSHOT] - 2026-02-14
### 变更
- 移除 Google Play Install Referrer 库直接依赖,改为反射方式获取 install_referrer,减少 SDK 外部依赖
## [1.0.0.18-SNAPSHOT] - 2026-02-13
### 修复
- 离线包初始化:拆分为独立线程,不再被 Settings 初始化阻塞,解决 `initialized=false` 导致离线包不命中的问题
- 离线包等待逻辑:URL 拦截时正确等待初始化完成(500ms 轮询,最长 10s),不再 2s 超时后直接放弃
## [1.0.0.17-SNAPSHOT] - 2026-02-13
### 变更
- 埋点上报:`SReporter` 上报接口统一使用 `ApiHelper`/`SApiHelper` 的 baseURL 拼接,支持宿主自定义域名
## [1.0.0.16-SNAPSHOT] - 2026-02-09
### 修复
- 发布文档同步:`release_doc/supersdk/dev/JSSDK/supersdk.js` 同步为最新版本
## [1.0.0.15-SNAPSHOT] - 2026-02-09
### 变更
- JSBridge 优化:`reportEvent` 改为直接 JSBridge 方法(不再通过 `callHostMethod` 中转)
- JSBridge 优化:`showToast` 改为 SDK 内置实现(Android 使用系统 Toast,iOS 使用自定义浮层)
- JSBridge 优化:`openBrowser` 改为 SDK 内置实现(使用系统浏览器打开)
## [1.0.0.14-SNAPSHOT] - 2026-02-08
### 变更
- 架构优化:`SuperPageActivity` 解耦 `SuperWebview`,统一通过 `AbsSuperPageView` API 交互
- 架构优化:`NavigationService.openPage()` 参数从 `View` 收窄为 `AbsSuperPageView`
- 架构优化:`NavigationBridge.openPage()` 改用 `SuperPageView` 代替裸 `SuperWebview`
- API 优化:`handleBackPressed(exitAction)` 内部封装 `canGoBack/goBack`,调用方只需传退出动作
- API 优化:`AbsSuperPageView.fitSystemWindows(Activity)` 一行代码适配沉浸式安全区域
- API 优化:`AbsSuperPageView.setOnClosePageListener(Runnable)` 提升到 API 层
- 内部简化:移除 `SuperPageControlHandler` 类,handler 改为匿名实现
- 内部简化:移除 `dispatchActivityResume/Pause`,`SuperWebview` 通过 `onWindowVisibilityChanged` 自动感知
## [1.0.0.13-SNAPSHOT] - 2026-02-08
### 新增
- 客户端广播:`sendBroadcast(eventKey, jsonData)` 向前端发送广播,前端通过 `SuperSDK.subscribe()` 接收
- 客户端广播:`SuperSDK.broadcastToAll(eventKey, jsonData)` 向所有 WebView 广播
- 返回键拦截:前端通过 `SuperSDK.onBackPressed(callback)` 监听返回键,`callback` 返回 `true` 拦截
- 安全区域设置:`AbsSuperPageView.setSafeArea(statusBarHeight, navigationBarHeight)` 统一设置安全区域
- 云控配置拆分:`getSettings` 拆分为 `getSDKSettings`(configName=supersdk,已在 1.0.0.49-SNAPSHOT 移除)和 `getHostSettings()`(不带 configName)
- 应用信息获取:`SuperSDK.getAppName()` 获取宿主 App 名称
- 应用信息获取:`SuperSDK.getAppIcon()` 获取宿主 App 图标(Base64 格式)
## [1.0.0.12-SNAPSHOT] - 2026-02-07
### 新增
- Android SDK 初始化与核心容器能力
- iOS SDK 初始化与核心容器能力
- JS SDK 前端交互能力
- JSBridge:环境信息、页面导航、分享、生命周期、WebView 通信
- 文件操作:下载、读写、ZIP 压缩解压
- 归因系统
- Native Block(原生组件嵌入)
- 离线包管理(查询、更新)
- 云控配置
- SLogger 日志 tag 添加 `ss-` 前缀,便于过滤 SDK 日志
---