原生配置、检测与更新
Pushy 提供 Android、iOS 和 HarmonyOS 原生宿主接口,支持原生配置 → 正常解析启动 bundle → 主动检查和下载更新。配置和检查均不必经过 JS Bridge:即使首次安装、JS 尚未执行,也可以由原生端准备配置,之后运行原生更新流程。
configure 只配置,不联网、不下载、不解析 bundle;checkAndUpdate 则不是仅查询版本的接口,有可执行热更新时会继续下载、校验,并按配置决定是否设置为下次启动使用的版本。两个接口都不会弹窗或立即重载正在运行的 React Native 页面。
本文的原生 configure、checkAndUpdate 接口及 JS 选项 nativeConfigSource 均从 react-native-update v10.57.0 起提供,适用于 Android、iOS 和 HarmonyOS。请使用 v10.57.0 或更高版本;旧版 SDK 即使已有原生自动检测,也不包含本文的公开宿主入口。完整变更见 v10.57.0 发布说明。
升级后必须重新编译和发布原生安装包,不能仅发布 JS 热更新。HarmonyOS 从源码集成时,还需重新构建并集成包含这些导出的 HAR。
首次启动的调用顺序
应用仍需完成安装配置和代码集成,保留原来的 Pushy bundle 加载方式和版本成功标记、回滚接入。原生配置解决的是配置来源问题,不代替整个 RN 启动流程。
- 原生调用
configure,等待成功回调或 Promise 完成。此时不要求 JS 或 RN Bridge 已启动。 - 继续应用原有的 RN 启动流程,由 Android 的
UpdateContext.getBundleUrl(...)、iOS 的RCTPushy.bundleURL或 HarmonyOS 的实际PushyFileJSBundleProvider完成本次启动的 bundle 解析。 - 解析完成后调用
checkAndUpdate,或交由已有原生冷启动检查自动执行。
不要阻塞主线程等待配置完成,也不要为了触发检查而额外调用一次 bundle 解析函数。 解析包含首次加载和回滚状态处理,并非无副作用的初始化方法。如果应用已经正常启动并完成解析,可直接配置成功后检查,无需重复解析。
配置保存在设备上,后续启动可复用;每次启动重复提交相同的原生配置也是幂等的。首次原生配置时会在缺少安装标识的情况下生成并保存设备安装标识,已有标识不会被覆盖,后续 JS 可继续复用。
配置参数
Android 使用 JSONObject,iOS 使用字典,HarmonyOS 使用导出的 NativeUpdateConfig。三端字段相同:
最小配置只需要 appKey。要让正常下载的更新在下次启动生效,还应显式设置 afterDownload: 'setNeedUpdate'。服务端 forceBoot 和已有崩溃救援规则继续生效,因此 none 不是关闭所有救援激活的开关。
configure 提交的是完整配置替换,不是局部合并。例如,只传入 appKey 会重新采用默认服务地址、afterDownload: 'none'、disabled: false,而不是沿用之前的自定义值。
SDK 会校验必填值、字段类型、策略、未知字段,以及 HTTP(S) URL;基础地址不能含账号密码、查询参数或片段。地址会去除首尾空白,基础地址会去除末尾斜杠并去重。校验失败不会覆盖已有配置;存储错误同样通过失败回调或 Promise 拒绝返回,业务不要把失败当成配置成功。生产环境应使用 HTTPS。
Android:Java / Kotlin
公开入口:
不需要 ReactContext 或原生模块实例。配置与检查均异步执行,回调都在主线程;配置回调的 error == null 表示成功。context、配置对象和回调不能为空,否则抛出 IllegalArgumentException。
Kotlin:原生配置
Kotlin:主动检查
Java
以下代码放在可以处理 JSONException 的方法或 try/catch 中。配置回调后应继续正常启动;检查示例放在实际 bundle 解析完成之后:
以下是另一个业务入口,必须在配置成功且 bundle 已正常解析后执行,不要与上面的异步配置并排立即调用:
NativeUpdateResult 是不可变对象。检查可能持续一段时间,回调更新页面前仍应检查页面是否已经销毁。
iOS:Objective-C / Swift
公开类方法不要求创建 RCTPushy 实例或获取 Bridge。配置与检查完成回调均在主队列执行。
Objective-C
本次启动的正常 bundle 解析完成后,再从业务入口主动检查:
Swift
在已有的 Objective-C bridging header 中引入 RCTPushy.h。Swift 方法名固定为 configure(_:completion:) 和 checkAndUpdate(completion:):
completion 可以传 nil,但启动需要等待配置完成时应提供回调,不要依赖延迟几秒来猜测是否成功。页面相关的回调按生命周期使用弱引用。
HarmonyOS:ArkTS
使用应用实际加载 bundle 的 PushyFileJSBundleProvider 实例。不要额外创建一个只用于检查的 provider,也不要为了初始化检查而调用一次多余的 getURL() 或 getBundle()。
configure 校验或存储失败时 Promise 会拒绝,应在你的启动逻辑中捕获错误;不要在错误后继续假定配置可用。请以项目实际配置的 HAR 依赖名称为准。开发环境使用 Metro、没有经过 Pushy bundle 解析时,检查返回 not_initialized。
JS 和原生谁管理配置?
由原生管理:推荐用于完整原生更新入口
从 JS Pushy 实例首次创建时设置 nativeConfigSource: 'native':
这样 JS 初始化及后续 setOptions 不会把原生配置覆盖掉。nativeConfigSource 只决定是否由 JS 写入原生配置,不会把原生配置自动同步到 JS,也不会自行关闭 JS 检查;若两端都检查,应保持 appKey、服务地址、版本覆盖等设置一致。
该模式下原生是否禁用、下载后是否激活,都由 configure 的 disabled 和 afterDownload 控制。JS 的 disableNativeCheck、updateStrategy 等设置不再写入原生配置;仍要保留既有的版本成功标记和回滚接入。
由 JS 管理:默认兼容方式
省略 nativeConfigSource 或设置为 'javascript' 时,JS 继续按原有行为同步原生配置。可以先由原生 configure 提供首启配置,待 JS 正常运行后接管;同一个配置存储以最后实际完成的写入为准,不做跨来源字段合并。
不要在两个来源之间反复切换。已经发出的异步 JS 配置写入不会因为随后切换选项就自动撤销;原生主导的应用应一开始就设置 'native'。既有 JS 写入未完成时,不应并行发起预期长期保留的原生配置。
返回结果和生效时机
三端检查结果字段一致:status、reason、hash、activated。hash 在本轮没有准备好更新时为空字符串;activated: true 表示本轮已选定下次启动版本,不表示当前 RN 页面已更新。
常见 reason 包括 not_initialized、not_configured、disabled、debug、invalid_config、check_failed、download_failed、commit_failed、internal_error、reset 和 config_changed。Android 等待被中断时还可能返回 interrupted。业务先按 status 分支,再用 reason 提示或诊断。
configure 不会设置热更版本或重载页面;checkAndUpdate 的普通激活受 afterDownload 控制,服务端 forceBoot 和已有救援规则继续生效。activated: false 时,下载并不意味着下次启动就一定加载这个版本,仍需后续激活处理。不要在下载完成回调中提前调用 markSuccess。
重复调用和配置变更
原生主动调用、自动冷启动检查及 Android/iOS 已有崩溃救援共用每进程至多一轮实际检查。尚未开始时主动调用立即发起;正在执行时共享任务;已经结束时复用该轮结果,包括失败结果。反复点击不会重新请求服务器,重建 RN 实例也不等于重启进程。
自动检查若因缺少或禁用配置而在开始前跳过,不会消耗实际轮次;之后原生配置成功,仍可在同一进程检查。配置更新本身不会启动新轮次,也不会把已完成的轮次重置为可再次执行。
配置替换会使旧响应缓存和进行中的原生决策失效,旧轮次不能再用旧 appKey 或旧策略提交激活;已下载文件仍可能留作后续复用。正在进行的网络传输不保证立即中断,但不会把失效结果当成更新成功。此时结果通常为 cancelled / config_changed,下一次进程启动使用新配置。
原生与 JS 检查不是同一个网络任务,原有响应缓存和“JS 已完成则跳过延迟原生检查”的规则继续保留,但不承诺把主动原生请求与进行中的 JS 请求合并。
边界与验证
原生轮次不会执行 JS 函数,包括 beforeCheckUpdate、beforeDownloadUpdate、afterDownloadUpdate、afterCheckUpdate 和 beforeReload。需要用户同意、网络条件或页面状态判断时,应在原生业务发起调用前完成。
Android/iOS 调试构建的检查返回 skipped / debug;JS 的 debug: true 不会开启原生检查。使用发布构建验证完整流程。这些接口只处理适配当前原生包的热更新,不能代替 APK、App Store 或原生模块升级。
重点验证首次安装且 JS 未执行时的配置、正常启动后的检查和下载;重复调用仅一轮;错误配置不覆盖原配置;断网返回失败;配置变更或恢复内置包使旧轮次失效;下载已激活时在下一次真实进程启动加载新版本。还应确认 JS 使用 'native' 模式时不会覆盖原生配置。