简短回答:是的,Google Play 允许对解释型 code 进行 Live Update。 您可以向 Android 应用推送新的 JavaScript、HTML 和 CSS,而无需新的 Play Store 审核。您不能下载原生 code,例如 dex、JAR 或 .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(欺骗行为、恶意软件、违规内容) |
| 更新图片、翻译、配置 | 把应用变成商店描述之外的东西 |
| 回滚有问题的发布版本 | 绕过 Android 权限或安全机制 |
Capgo 只下发左列的内容。任何原生内容,例如新的 Capacitor 插件、新的权限 AndroidManifest.xml或 Gradle 依赖项,仍需通过 Google Play 发布新版本。Capgo 的 版本定向 让需要新原生 code 的 bundle 不会落到旧二进制上。
Google 如何执行
Google 会扫描应用中下载的可执行 code,以及安装后行为发生改变的情况。自动化检查会寻找从 APK 外部加载 dex 或原生库的行为。WebView 中的 JavaScript 不会触发这些检查。
真正的风险在于第二条规则:如果 live update 让应用做了 Play 政策禁止的事,无论 code 是怎么来的,都算违规。欺骗性行为政策同样适用于审核后功能发生变化的应用。
实际情况中:
- 用 Live Updates 对已发布的应用做修复和迭代。
- 确保应用与 Play Store 详情页及数据安全表单保持一致。
- 通过 Google Play 发布原生变更和重大版本,同时配合 分阶段发布 如果你希望逐步放量。
哪些技术栈可以在 Android 上实现?
你的应用能否在 Android 上进行热更新,取决于一个问题:应用逻辑是否在运行时解释执行?JavaScript 和其他解释型 code 可以,下载的 dex、JAR 和原生 .so 文件则不行。像 Flutter 这类 AOT 编译的框架只能借助 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 编译为原生库 | 只能通过虚拟机或解释器 | Shorebird |
| 原生 Kotlin / Java | ART 上的 dex 字节码 | 原生 code:不支持;WebView 中的 JavaScript:支持 | 远程配置、Play Feature Delivery |
| Kotlin / Compose Multiplatform | ART 上的 dex 字节码 | 否 | 远程配置、Play Feature Delivery |
| .NET MAUI / Xamarin | 随 APK 打包的 .NET 运行时和原生库 | 否 | 仅限远程配置 |
| Unity / Unreal | C# 经 IL2CPP 或 C++ 编译 | 对 code 不行,对内容可以 | Asset bundles、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 打包的 App 会把 web bundle 打包进 APK,并为 Live Updates 提供一致的插件层。
任何技术栈在 Android 上都做不到的事
不管用什么框架,live update 都不能:
- 从 Google Play 之外
.so下载 dex、JAR、APK 或原生文件 - 添加新的 Android 权限
- 让 App 执行 Google Play 政策禁止的操作
- 使 App 的功能与 Play Store 详情页描述不符
下一步该怎么做
- iOS 的回答: Apple 是否允许无需 App Store 审核的 Live Updates?
- 合规检查清单: Google Play OTA 合规检查清单
- 发布策略: Google Play 合规:密钥更新策略
即时发布修复,无需等待审核
Capgo 实时更新 借助渠道、回滚、增量更新和端到端加密,几分钟内就能把 JavaScript、HTML 和 CSS 变更推送到你的 Capacitor 应用。它开源且支持自托管。
bunx @capgo/cli@latest init
按照 快速入门 来发送你的第一个更新。