简短的回答是:可以。Google Play 允许对解释型 code 进行 live updates。 你可以直接向 Android 应用推送新的 JavaScript、HTML 和 CSS,而无需重新提交 Play Store 审核。但你不能下载 dex、JAR 等原生 code 或 .so 文件。
Google 在这方面比 Apple 更明确:WebView 中 JavaScript 的豁免条款已直接写入政策中。本文将引用该条款,明确界限,并解释 Google 如何执行该政策。
本文不构成法律建议。内容基于当前的政策解读以及数千款应用在生产环境中的实际应用情况。
Google Play 的政策究竟是怎么说的
该规定位于 设备和网络滥用政策中:
通过 Google Play 分发的应用,不得使用 Google Play 更新机制以外的任何方法进行自我修改、替换或更新。同样,应用不得从 Google Play 以外的来源下载可执行 code(例如 dex、JAR、.so 文件)。此限制不适用于在虚拟机或解释器中运行的 code,只要该环境能间接访问 Android API(例如 webview 或浏览器中的 JavaScript)。
紧接着规定:
对于在运行时加载解释型语言(如 JavaScript、Python、Lua 等,例如未打包在应用内)的应用或第三方 code(如 SDK),不得允许任何可能违反 Google Play 政策的行为。
因此,共有两条规则:
- Native code 只能来自 Google Play。 禁止下载 dex、JAR 或原生库。
- 解释型 code 可以来自任何地方, 但其行为仍必须遵守所有 Play 政策。
Capacitor 应用的 Web 层是运行在 Android WebView 中的 JavaScript、HTML 和 CSS,这正是 Google 给出的确切示例。它属于豁免范围。
界限在哪里
| 允许使用 live update | 不允许使用 live update |
|---|---|
| 修复 JavaScript、HTML、CSS 中的 Bug | 下载 dex、JAR、APK 或 .so 文件 |
| 现有 Web 技术栈中的 UI 变更、文案修改或新页面 | 在 Google Play 更新机制之外替换应用 |
| Web code 的 A/B 测试和分阶段发布 | 发布违反 Play 政策的 code(欺骗行为、恶意软件、违规内容) |
| 更新图片、翻译和配置 | 使 App 的实际功能与应用商店描述不符 |
| 回滚有问题的发布版本 | 绕过 Android 权限或安全机制 |
Capgo 仅推送左侧列的内容。任何原生内容,例如新的 Capacitor plugin、新的 AndroidManifest.xml权限或 Gradle 依赖,仍需通过 Google Play 发布新版本。Capgo 的 版本定向 将需要新原生 code 的 bundle 与旧二进制文件隔离开来。
Google 如何强制执行
Google 会扫描 App 是否下载了可执行 code,以及安装后是否存在行为变更。自动化检查会检测是否从 APK 外部加载 dex 或原生库。WebView 中的 JavaScript 不会触发此类检查。
真正的风险在于第二条规则:如果 live update 导致 App 做出 Play 政策禁止的行为,无论 code 如何获取,都属于违规。欺骗性行为政策同样适用于审核后功能发生变化的 App。
在实践中:
- 请针对已发布的 App 使用 Live Update 进行修复和迭代。
- 确保您的 App 与 Play Store 详情页及数据安全表单保持一致。
- 通过 Google Play 发布原生变更和重大版本更新,同时 分阶段发布 如果您希望逐步推送。
哪些技术栈可以在 Android 上实现?
您的 Android App 是否支持热更新,取决于一个问题:您的 App 逻辑是在运行时解释执行的吗?如果是 JavaScript 或其他解释型 code,则可以。如果是下载的 dex、JAR 或原生 .so 文件,则不行。像 Flutter 这样经过 AOT 编译的 framework 只有通过 VM 或解释器才能符合条件。
各技术栈对 Android live update 的兼容性
| 技术栈 | code 在 Android 上的运行机制 | 允许 Live Updates 吗? | 工具链 |
|---|---|---|---|
| Capacitor | Android WebView 中的 JavaScript、HTML、CSS | 是 | Capgo |
| Ionic (在 Capacitor 上) | 与 Capacitor 相同 | 是 | Capgo |
| Cordova | Android WebView 中的 JavaScript | 是 | 迁移到 Capacitor 后的 Capgo,旧版 Cordova 插件 |
| React Native / Expo | 运行在 Hermes 上的 JavaScript bundle | 是的,仅限 JavaScript | Expo Updates,自托管的 CodePush 替代方案 |
| NativeScript | 运行在 V8 上的 JavaScript | 是的,仅限 JavaScript | 有限,大多为自研 |
| Flutter | Dart 编译为原生库的 AOT | 仅限通过 VM 或解释器 | Shorebird |
| 原生 Kotlin / Java | ART 上的 dex 字节码 | 原生 code 不支持;WebView 中的 JavaScript 支持 | 远程配置,Play Feature Delivery |
| Kotlin / Compose Multiplatform | ART 上的 dex 字节码 | 否 | 远程配置,Play Feature Delivery |
| .NET MAUI / Xamarin | 包含在 APK 中的 .NET runtime 及原生库 | 否 | 仅限远程配置 |
| Unity / Unreal | C# 经 IL2CPP 或 C++ 编译 | 不支持 code,支持内容 | Asset bundle、Play Asset Delivery、脚本内容(Lua) |
| Web 封装 / TWA | 在 WebView 或 Chrome 中加载的网站 | 始终实时 | 无需 |
Capacitor、Ionic 和 Cordova:全面支持
您的 UI 和业务逻辑就是运行在 Android WebView 中的 JavaScript,这正是 Google 政策在说明允许使用 code 时给出的确切示例。live update 会替换 web bundle;APK、原生插件和权限仍保持您发布时的版本。
Capgo 在设计上就符合合规要求,因为它只能更改 Web 层。新增原生插件、新的权限 AndroidManifest.xml 以及 Gradle 依赖变更仍需通过 Google Play 发布。
React Native 和 Expo:JavaScript 可以,原生模块不行
React Native 在 Hermes 上运行 JavaScript bundle,这算作解释型 code。Expo Updates 和现已停用的 Microsoft CodePush 都会更新该 bundle。 正在从 CodePush 迁移的团队 需要替代方案。原生模块和 React Native 升级仍需发布新版本。
Flutter:只能通过 VM 或解释器实现
Flutter 会将 Dart AOT 编译为 libapp.so。下载新的 .so 是被明确禁止的,因此标准 Flutter 无法使用 live updates。Shorebird 增加了 code 推送,并声明其通过 Dart 虚拟机运行更新,从而符合 Play 政策。更多内容请阅读 Flutter 应用的 live updates.
原生 Kotlin、Java 和 Kotlin Multiplatform:不支持 code 更新
使用以下方式加载下载的 dex 或 JAR 文件 DexClassLoader 正是政策所禁止的行为。Google 自家的替代方案是 Play 功能交付,它会通过 Google Play 下载 code 模块。否则,原生 code 无法更改。在 WebView 中运行 JavaScript 的 Kotlin 或 Java 应用仍可更新该 code,因为该政策对解释型 code 予以豁免。其他原生逻辑仅限于远程配置、功能开关和服务端驱动 UI。
Unity 和游戏引擎:内容可以,code 不行
游戏 code 是编译好的。Asset bundles 和 Play Asset Delivery 负责处理内容,而像 Lua 这样的嵌入式脚本语言是解释执行的(code),只要结果符合 Play 政策,政策就允许这种做法。
Web 封装应用和 Trusted Web Activities:天生支持实时更新
Trusted Web Activity 或 WebView 封装会加载你的网站,因此每次部署都会更新。Google Play 接受 TWA。离线缓存和原生桥接取决于该封装的具体实现:TWA 可以使用你的 PWA service worker,而 WebView 壳程序可以暴露你自行实现的 JavaScript 桥接。打包好的 Capacitor 应用会把 web bundle 放进 APK,并为实时更新提供一致的插件层。
Android 上任何技术栈都做不到的事
无论您使用什么框架,live update 都不能:
- 下载 dex、JAR、APK 或原生
.so文件(Google Play 之外) - 添加新的 Android 权限
- 让 App 执行 Google Play 政策禁止的操作
- 使 App 的功能与 Play Store 详情页描述不符
接下来看什么
- iOS 的情况: Apple 是否允许无需经过 App Store 审核的 Live Update?
- 合规检查清单: Google Play OTA 合规检查清单
- 发布策略: Google Play 合规:关键更新策略
今天发布修复,不用等审核
Capgo 实时更新 几分钟内把 JavaScript、HTML 和 CSS 变更推送到你的 Capacitor 应用,支持通道、回滚、增量更新和端到端加密。项目开源,可自托管。
bunx @capgo/cli@latest init
请参考 快速入门 来发送你的第一个更新。