XuqmGroup-Web/docs-site/docs/rn/update.md
2026-07-29 02:49:24 +08:00

5.5 KiB

版本与插件更新

@xuqm/rn-update 提供两类能力:

  • Android 整包检查、下载、安装和应用商店跳转。
  • 可选的 RN 插件检查、安装和启动。

SDK 返回更新信息和当前网络状态,是否弹窗、是否允许使用移动网络以及何时开始下载由宿主 决定。

整包更新

检查

import { UpdateSDK } from '@xuqm/rn-update'

const result = await UpdateSDK.checkAppUpdate()

switch (result.status) {
  case 'UPDATE_AVAILABLE':
    showUpdateDialog(result.update, result.network)
    break
  case 'LOGIN_REQUIRED':
  case 'SERVICE_DISABLED':
  case 'NO_UPDATE':
    // 正常跳过,不阻断应用
    break
  case 'FAILED':
    // 记录一次非阻断诊断
    console.warn(result.errorCode, result.message)
    break
}

检查状态:

状态 宿主建议
UPDATE_AVAILABLE 根据 forceUpdate 展示宿主自己的更新弹窗
NO_UPDATE 继续启动
LOGIN_REQUIRED 未登录时跳过,登录后可再次检查
SERVICE_DISABLED 服务未启用,继续运行
FAILED 记录诊断,不阻断宿主

result.network 包含连接类型、是否已连接和是否按流量计费。租户平台不替宿主配置网络 策略。

下载并安装

用户确认后调用:

await UpdateSDK.downloadAndInstallApp(result.update!, {
  destination: 'SDK_PRIVATE',
  onProgress(progress) {
    setProgress(progress.percent)
  },
})

需要把安装包保留在系统 Downloads

await UpdateSDK.downloadAndInstallApp(result.update!, {
  destination: 'PUBLIC_DOWNLOADS',
})

下载失败或应用退出后不会在下次启动时自动继续。

只下载、稍后安装

import { NativeAppUpdate, UpdateSDK } from '@xuqm/rn-update'

const downloaded = await UpdateSDK.downloadApk(result.update!, {
  destination: 'SDK_PRIVATE',
})

console.log(downloaded.localPath)

await NativeAppUpdate.installDownloaded({
  versionCode: result.update!.versionCode!,
  sha256: result.update!.sha256,
})

取消当前下载:

await NativeAppUpdate.cancel()

如果系统禁止安装未知来源应用:

await NativeAppUpdate.openInstallPermissionSettings()

跳转应用商店

宿主不传商店地址,只传检查接口返回的更新对象:

const opened = await UpdateSDK.openStore(result.update!)

Android 会优先打开当前设备对应的应用商店,不可用时使用平台提供的通用下载页。iOS 或 HarmonyOS 没有配置商店地址时返回 false,宿主应提示当前无法提供下载服务。

忽略可选版本

await UpdateSDK.ignoreAppVersion(result.update!.versionCode!)
const ignoredVersion = await UpdateSDK.getIgnoredAppVersion()
await UpdateSDK.clearIgnoredAppVersion()

强制更新不能被忽略。

不启用插件化

普通项目可以只使用上述整包更新 API,不创建 common/app/buz 模块,也不需要接入插件 运行时。后续需要插件化时再执行初始化命令即可。

启用插件化

在项目根目录执行交互式初始化:

pnpm exec xuqm-rn init
pnpm run xuqm:doctor

初始化工具会创建 xuqm.modules.json、补充必要脚本并提示宿主完成最少原生配置。不要 手工复制其他项目的模块表。

Metro 使用:

const { getDefaultConfig } = require('@react-native/metro-config')
const { withXuqmModuleConfig } = require('@xuqm/rn-update/metro')

module.exports = withXuqmModuleConfig(getDefaultConfig(__dirname))

Android 宿主应用一次构建脚本:

apply from: file("../../node_modules/@xuqm/rn-update/android/xuqm-bundles.gradle")

注册宿主运行时

import { XuqmRuntime } from '@xuqm/rn-update'

XuqmRuntime.configure({
  plugins: pluginRegistrations,
  context: {
    navigate(route, params) {
      navigationRef.navigate(route, params)
    },
    emit(event, payload) {
      hostEvents.emit(event, payload)
    },
    getHostState() {
      return appStore.getState()
    },
  },
  async loadBundle(_moduleId, bundlePath) {
    await bundleLoader.load(bundlePath)
  },
})

模块入口注册:

import { definePlugin } from '@xuqm/rn-update'

definePlugin({
  moduleId: 'orders',
  activate(context) {
    context.navigate('OrdersHome')
  },
})

检查与安装插件

自动完成检查和安装:

const plan = await UpdateSDK.checkAndInstallPlugin('orders', {
  onProgress(moduleId, progress) {
    console.log(moduleId, progress.percent)
  },
})

await XuqmRuntime.activate('orders', {
  reloadBundle: plan !== null,
})

宿主需要先展示确认弹窗时:

const plan = await UpdateSDK.checkPluginRelease('orders')

if (plan && (await showPluginUpdateDialog(plan))) {
  await UpdateSDK.installPluginRelease(plan)
}

只检查不会下载或修改本地状态。插件检查失败时,宿主应继续打开已有的本地健康版本。

启动策略

  • 启动时先检查整包更新。
  • 不需要整包更新时,再检查 App 插件。
  • 业务插件在进入前分别检查。
  • Debug 默认不自动检查;开发页可以显式使用 UpdateSDK.developer 下的测试入口。
  • 更新 SDK 不绘制业务弹窗,所有提示和确认交互由宿主实现。

打包与发布

初始化生成的脚本支持 Debug、Release、插件构建和上传。发布令牌只通过 CI 环境变量 XUQM_API_TOKEN 注入,不写入项目配置、源码或产物。

SDK 自身制品发布与应用/插件发布是不同操作。应用开发者不需要发布 SDK,也不得把 SDK 发布凭据加入宿主工程。