> For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt.

# API参考

### JavaScript 方法

原生端主动配置、检测与下载的接口和完整首启顺序，参见[原生配置、检测与更新](/docs/native-api.md)。原生主导配置时，请在 JS 实例首次创建时设置 `nativeConfigSource: "native"`，避免 JS 初始化覆盖原生配置。

#### new Pushy(options: PushyOptions)

创建 Pushy 热更新服务实例，其构造参数如下：

```ts
interface PushyOptions {
  // 必填，通过pushy createApp或selectApp命令，或在网页管理端获取
  appKey: string;

  // 自定义日志输出，也可用于上报统计数据
  logger?: ({ type, data }: { type: EventType; data: EventData }) => void;

  // 触发自动检查更新的策略
  checkStrategy?:
    | "onAppStart" // 仅在app启动时
    | "onAppResume" // 仅在app从后台切换到前台时
    | "both"; // 默认值，同时包含前两个场景
    | null; // 不自动检查更新，必须手动调用checkUpdate方法，此选项需 v10.4.2+ 版本

  // 自动下载和应用更新的策略
  updateStrategy?:
    | "alwaysAlert" // 调试环境（__DEV__）默认值，使用系统默认的alert页面提示热更且会在有报错时弹出提示
    | "alertUpdateAndIgnoreError" // 生产环境默认值，在有热更时使用系统默认的alert页面提示热更，但不弹出任何报错提示
    | "silentAndNow" // 自动静默下载并立刻应用热更
    | "silentAndLater"; // 自动静默下载，但仅在用户退出app后重启时应用更新
    | null; // 不自动下载和应用更新，如需自定义热更界面请选择此项

  // 是否在热更重启后自动标记为成功，默认为true
  // 一般情况下不建议手动标记
  autoMarkSuccess?: boolean;

  // 是否在若干ms后自动清除最后的报错，默认为不清除
  dismissErrorAfter?: number;

  // 是否在开发环境中检查热更，默认为false。如需在开发环境中调试热更，请打开此选项。
  // 但即便打开此选项，也仅能检查、下载热更，并不能实际应用热更。实际应用热更必须在release包中进行。
  // 此选项需 v10.4.2+ 版本
  debug?: boolean;

  // 是否在调用 checkUpdate 和 downloadUpdate 时抛出错误，默认为不抛出错误，通过 lastError 获取错误信息
  // 启用后可以使用 try catch 语句 捕获错误，同时 lastError 也仍然可用
  // try {
  //   await checkUpdate();
  // } catch (e) {
  //   console.error(e);
  // }
  // 此选项需 v10.15.2+ 版本
  throwError?: boolean;

  // 在检查更新前执行，返回 false 则取消检查更新
  // 此选项需 v10.12.0+ 版本
  beforeCheckUpdate?: () => Promise<boolean>;

  // 在每次检查更新结束后执行，可用于上报检查结果；不影响原有检查流程
  // 此选项需 v10.38.3+ 版本
  afterCheckUpdate?: (state: UpdateCheckState) => Promise<void> | void;

  // 在下载更新前执行，返回 false 则取消下载更新，可以配合自定义的 metaInfo 做一些条件控制
  // 此选项需 v10.12.0+ 版本
  beforeDownloadUpdate?: (info: UpdateInfo) => Promise<boolean>;

  // 在下载更新后执行，返回 false 则取消内置策略进一步执行，可以配合自定义的 metaInfo 做一些条件控制
  // 此选项需 v10.27.0+ 版本
  afterDownloadUpdate?: (info: UpdateInfo) => Promise<boolean>;

  // 在原生包过期时执行，返回 false 则取消内置策略进一步执行，可以配合自定义的 metaInfo 做一些条件控制
  // 此选项需 v10.28.2+ 版本
  onPackageExpired?: (info: UpdateInfo) => Promise<boolean>;

  // 在 switchVersion 或 restartApp 触发立即重启前执行，返回 false 则取消本次重启
  // 可用于等待 Sentry 等原生 SDK 停止采样、flush 上报队列后再销毁 RN 实例
  // 此选项需 v10.42.2+ 版本
  beforeReload?: (
    context: BeforeReloadContext,
  ) => Promise<boolean | void> | boolean | void;

  // 是否关闭更新生命周期事件上报（版本健康度统计），默认为 false（开启）
  // 详见下方「版本健康度事件上报」一节
  // 此选项需 v10.47.0+ 版本
  disableTelemetry?: boolean;

  // 是否关闭 JS 报错上报，默认为 false（开启）
  // 详见「JS 报错监控」一节：https://pushy.reactnative.cn/docs/errors
  // 此选项需 v10.55.0+ 版本
  disableErrorReporting?: boolean;

  // 是否关闭原生冷启动检测（每次冷启动后由原生代码独立发起的后台检查），
  // 默认为 false（开启）。关闭后将失去「强制启动」救砖通道，
  // 详见下方「原生冷启动检测」一节
  // 此选项需 v10.52.1+ 版本
  disableNativeCheck?: boolean;

  // 原生配置来源，默认 javascript：继续由 JS 同步配置。
  // native：由原生 configure 管理，JS 不再覆盖原生配置；
  // 此模式下原生是否禁用由 configure 的 disabled 控制，
  // JS 的 disableNativeCheck 不再写入原生存储。
  // 此选项需 v10.57.0+ 版本；原生 configure/checkAndUpdate 同样需要 v10.57.0+，升级后须重新构建原生包。
  nativeConfigSource?: "javascript" | "native";
}

// 检查更新结束后的状态
type UpdateCheckState = {
  // completed: 检查完成；skipped: 因 debug、web 环境或 beforeCheckUpdate 返回 false 等原因跳过；error: 检查出错
  status: "completed" | "skipped" | "error";
  // status 为 completed 时的检查结果
  result?: UpdateInfo;
  // status 为 error 时的错误对象
  error?: Error;
};

// beforeReload 接收到的重启上下文
type BeforeReloadContext = {
  // switchVersion: 立即应用已下载热更；restartApp: 直接重启当前应用
  type: "switchVersion" | "restartApp";
  // type 为 switchVersion 时，表示即将应用的热更 hash
  hash?: string;
};

// 日志事件类型
type EventType =
  // 更新失败，重启后发生回滚
  | "rollback"
  // 检查更新时报错
  | "errorChecking"
  // 正在发起检查
  | "checking"
  // 正在下载更新
  | "downloading"
  // 已下载更新
  | "downloadSuccess"
  // 更新失败
  | "errorUpdate"
  // 更新成功
  | "markSuccess"
  // 已恢复到内置包（resetToPackagedBundle 成功），需 v10.48.0+ 版本
  | "reset"
  // 恢复内置包失败，需 v10.48.0+ 版本
  | "errorReset"
  // 下载apk
  | "downloadingApk"
  // 下载apk前申请存储权限被用户拒绝
  | "rejectStoragePermission"
  // 下载apk前申请存储权限发生错误
  | "errorStoragePermission"
  // 下载apk时发生错误
  | "errorDownloadAndInstallApk";

// 日志事件数据
interface EventData {
  // 当前已完成的热更hash值，如尚未热更则为空字符串
  currentVersion: string;
  // 客户端版本信息
  cInfo: {
    rnu: string; // 当前 react-native-update 版本
    rn: string; // 当前 react-native 版本
    os: string; // 当前操作系统及版本
    uuid: string; // 用户标识符
  };
  // 客户端原生版本号
  packageVersion: string;
  // 编译时间戳
  buildTime: number;
  // 报错相关的信息
  message?: string;
  // 发生回滚的版本hash值
  rolledBackVersion?: string;
  // 更新失败的新版本hash值
  newVersion?: string;
  // 其他一些数据
  [key: string]: any;
}
```

#### 版本健康度事件上报

自 v10.47.0 起，SDK 会在更新流程的关键节点向更新服务自动上报少量生命周期事件，用于在管理端展示每个热更版本的健康度（下载失败率、patch 失败率、回滚率等），帮助你在发版后第一时间发现有问题的版本：

- `download_success` / `download_fail`：热更包下载成功 / 全部下载策略失败
- `patch_fail`：增量 patch 应用失败（含降级为完整包成功的情形）或版本切换失败
- `rollback`：新版本启动异常，发生自动回滚
- `mark_success`：新版本启动并标记成功

上报内容仅包含热更版本 hash、原生版本号、`cInfo`（SDK/RN/系统版本与设备标识符，与 checkUpdate 请求一致）以及失败时截断后的错误信息摘要，不涉及任何业务数据。上报为一次性异步请求，不重试、失败静默，不会影响更新流程与性能；调试环境（`__DEV__`）下不会上报。

如不希望上报这些事件，可在初始化时关闭：

```js
const pushyClient = new Pushy({
  appKey,
  disableTelemetry: true,
});
```

注意：关闭后管理端将无法统计该客户端的版本健康度，也无法在版本发生大面积异常时为你提供预警。

#### JS 报错上报

自 v10.55.0 起，SDK 会把热更版本中发生的 JavaScript 异常上报给更新服务，管理后台用发布时归档的 sourcemap 把堆栈还原回原始源码位置。未捕获异常会自动上报（在 React Native 现有的全局 `ErrorUtils` 处理器之上追加一层，不影响 Sentry 等已有集成），也可以在 `catch` 中手动调用 `captureException`：

```js
pushyClient.captureException(error, {
  extra: { screen: "checkout" },
});
```

如不希望上报，可在初始化时设置 `disableErrorReporting: true`。完整说明（包括后台界面、sourcemap 归档要求与手动上报用法）见 [JS 报错监控](/docs/errors.md)。

#### 原生冷启动检测

自 v10.52.1 起，客户端会在每次冷启动几秒后，由**原生代码**独立发起一次后台检查更新（完全不依赖 JS）。它的意义在于救砖：如果某次热更把 JS 打死，设备再也无法运行 JS 侧的检查逻辑，此时只有这条原生通道还能把修复版本拉回来（配合管理后台的[强制启动](/docs/publish.md#强制启动救砖)标记激活）。

行为要点：

- **不会打扰正常流程**：常规情况下它只做下载与缓存，是否激活取决于你配置的策略——`checkStrategy: null` 时原生只下载不激活；仅当服务端下发了强制启动标记时才会越过策略激活
- **JS 会复用它的结果**：JS 侧检查更新会直接复用原生刚拿到的响应缓存，冷启动时可少一次网络请求
- **安全护栏**：设备本地的回滚保护优先级最高；激活后若启动异常，首次启动崩溃保护依然会自动回滚

如确有需要（如流量/电量预算、合规要求联网需用户同意等场景），可在初始化时关闭：

```js
const pushyClient = new Pushy({
  appKey,
  disableNativeCheck: true,
});
```

注意：关闭后该客户端将失去强制启动救砖能力——一旦被坏热更卡死只能重装应用。

#### beforeReload 示例：重启前清理原生 SDK

`beforeReload` 会在 `switchVersion()` 和 `restartApp()` 真正重启前执行。返回 `false` 会取消本次重启；抛出异常或 Promise reject 时也不会继续重启。`switchVersionLater()` 不会立即销毁当前 RN 实例，因此不会触发此钩子。

如果应用接入了 Sentry profiling、性能采样、日志上传等可能跨线程工作的原生 SDK，可以在这里先停止采样并 flush 队列，再让 Pushy 重启：

```ts
import { NativeModules } from "react-native";
import * as Sentry from "@sentry/react-native";
import { Pushy } from "react-native-update";

const pushyClient = new Pushy({
  appKey,
  beforeReload: async (_context) => {
    try {
      NativeModules.RNSentry?.stopProfiling?.();
    } catch {}

    const flushed = await Promise.race([
      Sentry.flush(),
      new Promise<boolean>((resolve) => setTimeout(() => resolve(false), 1500)),
    ]);

    // 返回 false 会取消本次立即重启，等待下一次检查或手动触发。
    return flushed;
  },
});
```

#### useUpdate()

热更相关的工具函数。此方法也可使用别名 `usePushy` 引入。

:::info
注意，在使用 `<UpdateProvider>` 的当前组件（一般是根组件）中无法直接调用`useUpdate`，只有当前组件的子组件才能调用。
:::

```js
const {
  checkUpdate,
  switchVersion,
  switchVersionLater,
  markSuccess,
  dismissError,
  downloadUpdate,
  downloadAndInstallApk,
  getCurrentVersionInfo,
  currentVersionInfo,
  parseTestQrCode,
  currentHash,
  packageVersion,
  client,
  progress,
  updateInfo,
  lastError,
  restartApp,
  resetToPackagedBundle,
} = useUpdate();
```

其类型定义和功能如下：

```ts
interface UpdateContext {
  // 检查更新（注意在 v10.26.0 版本之前，`checkUpdate`方法本身没有返回值，只能从`useUpdate()`返回的`updateInfo`中获取）
  // 我们也仍然推荐优先从`useUpdate()`中获取`updateInfo`
  checkUpdate: () => Promise<void | UpdateInfo>;
  // 下载热更完成后调用，立即重启切换新版本
  switchVersion: () => Promise<void>;
  // 下载热更完成后调用，用户手动重启app后切换新版本（静默更新）
  switchVersionLater: () => Promise<void>;
  // 热更完成重启后，手动标记热更完成
  markSuccess: () => void;
  // 清除最后的报错状态
  dismissError: () => void;
  // 下载热更, v10.16.0+ 版本返回值为`boolean`，表示是否下载成功
  downloadUpdate: () => Promise<boolean | void>;
  // 下载并安装apk
  downloadAndInstallApk: (url: string) => Promise<void>;
  // 异步获取当前已热更版本的信息，v10.31.2 版本后用 `currentVersionInfo` 代替
  getCurrentVersionInfo: () => Promise<{
    name?: string;
    description?: string;
    metaInfo?: string;
  }>;
  // 当前已热更版本的信息，需 v10.31.2+ 版本
  currentVersionInfo: {
    name?: string;
    description?: string;
    metaInfo?: string;
  };
  // 解析测试二维码，此方法需 v10.11.2+ 版本
  parseTestQrCode: (qrCode: string) => void;
  // 当前的版本hash
  currentHash: string;
  // 当前的原生版本号
  packageVersion: string;
  // 当前的pushy热更服务实例
  client?: Pushy;
  // 立即重启应用，需 v10.28.2+ 版本
  restartApp: () => Promise<void>;
  // 恢复到原生包内置的 bundle，返回是否成功，需 v10.48.0+ 版本
  resetToPackagedBundle: (options?: { restart?: boolean }) => Promise<boolean>;
  // 下载开始后的进度数据
  progress?: {
    hash: string;
    // 已下载的字节数
    received: number;
    // 待下载的总字节数
    total: number;
  };
  // 热更相关信息
  updateInfo?: {
    // 已是最新版本，无需热更
    upToDate?: true;
    // 当前原生版本已过期，需要下载新的原生版本
    expired?: true;
    // 在pushy网页管理端设置的原生版本下载地址
    downloadUrl?: string;
    // 是否存在新的热更
    update?: true;
    // 新热更的版本名称
    name?: string;
    // 新热更的hash值
    hash?: string;
    // 新热更的更新说明
    description?: string;
    // 新热更携带的额外元数据
    metaInfo?: string;
    // 当前热更是否已暂停
    paused?:
      | "app" // 当前应用所有原生版本暂停
      | "package" // 仅当前原生版本暂停
      | "quota"; // 因检查次数超限而暂停
    // 其他信息
    message?: string;
  };
  // 检查、下载、应用热更等过程中的最近一次报错
  lastError?: Error;
}
```

***

#### async function checkUpdate()

触发更新检查，返回`updateInfo`（注意在 v10.26.0 版本之前，`checkUpdate`方法本身没有返回值，只能从`useUpdate()`返回的`updateInfo`中获取，且我们仍然推荐优先使用`useUpdate()`来获取），返回值有三种情形：

1. `{expired: true}`：该应用原生包已过期（三种情况：1. 主动设置为过期状态，2. 主动删除，3. 从未上传），需要引导用户下载或跳转到应用市场(需要在网页管理端设置中填写`downloadUrl`)。如需在应用内执行 apk 更新，还需配置[安装权限与系统确认流程](/docs/api.md#async-function-downloadandinstallapkurl)。

```js
{
    expired: true,
    downloadUrl: 'http://appstore/downloadUrl',
}
```

2. `{upToDate: true}`：当前已经更新到最新，无需进行更新。

3. `{update: true}`：当前有新版本可以更新。`name`、`description`字段可以用于展示给用户版本号，更新内容等信息，而`metaInfo`字段则可以根据你的需求自定义一些标记(如是否静默更新、是否强制更新等等，自己根据标记的属性做一些条件流程控制)，具体用法可参考[场景实践](/docs/bestpractice.md#%E5%85%83%E4%BF%A1%E6%81%AFmeta-info%E7%9A%84%E4%BD%BF%E7%94%A8)。另外还有几个字段，包含了热更新文件的下载地址，

```js
{
    update: true,
    name: '1.0.3-rc',
    hash: 'hash',
    description: '添加聊天功能\n修复商城页面BUG',
    metaInfo: '{"silent":true}',
    pdiffUrl: 'http://update-packages.reactnative.cn/hash',
    diffUrl: 'http://update-packages.reactnative.cn/hash',
}
```

***

#### async function downloadUpdate()

下载热更包。仅当`update:true`时实际进行下载。会更新`progress`数据。v10.16.0+ 版本返回值为`boolean`，表示是否下载成功。

***

#### async function downloadAndInstallApk(url)

下载更新的 apk 包，并通过 Android 系统的 `PackageInstaller` 发起安装。`url` 必须为可直接下载到 apk 文件的地址。此功能仅支持 Android 5.0（API 21）及以上版本。

安装必须由用户主动触发并在系统安装界面中确认，普通应用无法使用此 API 静默安装。方法在系统确认界面成功打开后返回，并不表示用户已经完成安装。

要使用此功能，需要在最终应用的 `AndroidManifest.xml` 中手动声明安装权限：

```xml
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
```

APK 下载到应用私有目录后会直接写入 `PackageInstaller.Session`，不需要申请外部存储权限。

在 Android 8.0（API 26）及以上版本中，用户还必须允许当前应用“安装未知应用”。首次调用时如果尚未授权，SDK 会打开当前应用对应的系统设置页，并以 `APK_INSTALL_PERMISSION_REQUIRED` 错误结束本次调用。用户完成授权后，需要再次调用此方法。提交安装 Session 后，SDK 会处理 `STATUS_PENDING_USER_ACTION` 并打开 Android 系统提供的安装确认界面；用户拒绝确认时不会安装。

:::warning
注意某些应用市场可能会因为上述权限拒绝应用上架。如被明确拒绝，建议去掉上述权限重新提交，不会影响热更新功能。
:::

***

#### function markSuccess()

**一般情况下请勿手动调用此函数**。调用此函数作为更新成功的标记（否则下次启动会默认失败自动回滚）。

***

#### currentVersionInfo

当前已热更版本的信息（如尚未热更过则为空对象）。需 v10.31.2+ 版本。

`currentVersionInfo` 是同步字段，推荐用它代替 `getCurrentVersionInfo()`：

```js
const { currentVersionInfo } = useUpdate();

console.log(currentVersionInfo.name);
```

字段示例：

```js
{
    name: '1.0.3-rc',
    description: '添加聊天功能\n修复商城页面BUG',
    metaInfo: '{"silent":true}',
}
```

***

#### function captureException(error, context?)

手动上报一个 JavaScript 异常，需 v10.55.0+ 版本。`context` 可选 `fatal`（是否致命，默认 false）、`componentStack`（React 组件堆栈）与 `extra`（自定义上下文，仅接受字符串、数字、布尔与 null，最多 32 个字段）。

调用是同步返回、永不抛错的：传输在后台进行，失败静默，同一个 error 对象只会上报一次。仅在运行于热更版本时上报，调试环境（`__DEV__`）下不上报。详见 [JS 报错监控](/docs/errors.md)。

```js
try {
  await submitOrder(order);
} catch (e) {
  pushyClient.captureException(e, { extra: { orderId: order.id } });
}
```

***

#### async function getCurrentVersionInfo()

获取当前已热更版本的信息（如尚未热更过则返回空对象）。v10.31.2 版本之后可以直接用 `currentVersionInfo` 代替。

返回值示例：

```js
{
    name: '1.0.3-rc',
    description: '添加聊天功能\n修复商城页面BUG',
    metaInfo: '{"silent":true}',
}
```

***

#### function restartApp()

立即重启应用。v10.28.2+ 版本可用。

如果配置了 `beforeReload`，会等待它完成后再重启；当 `beforeReload` 返回 `false`、抛出异常或 Promise reject 时，会取消本次重启。

***

#### async function resetToPackagedBundle(options?)

恢复到原生包内置的 bundle，返回 `boolean` 表示是否成功。v10.48.0+ 版本可用。

调用后会清空全部热更状态、删除所有已下载的热更版本，下次启动将直接加载打包在原生安装包内的 bundle。传入 `{ restart: true }` 则会在成功后立即重启生效（重启内部走 `restartApp`，同样受 `beforeReload` 控制）。设备标识符（uuid）会保留，不影响灰度分桶。

可用于客服指令、远程开关、异常兜底等需要"恢复出厂"的场景：

```js
const { resetToPackagedBundle } = useUpdate();

// 清空热更并立即重启回内置包
const ok = await resetToPackagedBundle({ restart: true });
```

也可以通过热更服务实例直接调用：

```js
const ok = await pushyClient.resetToPackagedBundle();
```

与其他更新流程 API 一致，此方法默认不抛出错误：失败时返回 `false`，错误信息（错误码 `RESET_FAILED`）可通过 `lastError` / `onError` 获取；如初始化时配置了 `throwError: true` 则会抛出。

:::warning
请务必检查返回值：此方法需要原生模块支持（v10.48.0+），如果只是通过热更把新版 JS 下发到了旧版原生包上，调用会返回 `false`——此时应用仍在运行热更 bundle，并没有恢复到内置包。
:::

***

#### function switchVersion()

立即重启应用，并加载已经下载完毕的版本。

> 注意!不可依赖`progress`来判断下载完成，必须要在`await downloadUpdate()`之后再调用此方法。

如果配置了 `beforeReload`，会传入 `{ type: "switchVersion", hash }` 并等待它完成后再重启；当 `beforeReload` 返回 `false`、抛出异常或 Promise reject 时，会取消本次重启。

***

#### function switchVersionLater()

在下一次启动应用的时候加载已经下载完毕的版本。

> 注意!不可依赖`progress`来判断下载完成，必须要在`await downloadUpdate()`之后再调用此方法。

此方法不会立即销毁当前 RN 实例，因此不会触发 `beforeReload`。

***

#### function parseTestQrCode(qrCode: string)

解析测试二维码，一般用于给 QA 人员测试热更新。如果在应用中已有扫码功能，则可以在应用中扫描 pushy 后台的测试二维码来测试任意版本的热更包。
注意如果你使用自定义的(更新策略（updateStrategy）)\[[https://pushy.reactnative.cn/docs/integration#updatestrategy%E6%9B%B4%E6%96%B0%E5%BA%94%E7%94%A8%E7%AD%96%E7%95%A5\]，请务必从](https://pushy.reactnative.cn/docs/integration#updatestrategy%E6%9B%B4%E6%96%B0%E5%BA%94%E7%94%A8%E7%AD%96%E7%95%A5]，请务必从) `useUpdate()` 中获取 `updateInfo` ，而不要依赖 checkUpdate 方法的返回值，否则扫码不会有后续动作。

![testqrcode](/static/image/testqrcode.24c22c1ebe.png)
注意使用此方法，上述界面中的"使用 Deep Link"选项 **请不要
** 勾选。
代码示例：

```js
<Camera
  onReadCode={({ nativeEvent: { codeStringValue } }) => {
    // 识别到二维码后先关闭相机
    setShowCamera(false);
    // 先解析是否是pushy的测试二维码
    if (parseTestQrCode(codeStringValue)) {
      // 如果是pushy的测试二维码，则不再做其他业务扫码逻辑
      return;
    }
    // 如果不是，继续处理其他业务扫码逻辑
  }}
/>
```

***

### Android 方法

#### UpdateContext.setCustomInstanceManager(ReactInstanceManager instanceManager)

如果是集成/混编 Android 方案，则可以使用此方法传入你自行创建的 ReactInstanceManager。自`v5.5.8`版本起可用。

示例：

```java
import cn.reactnative.modules.update.UpdateContext

mReactInstanceManager = ReactInstanceManager.builder()
                // ...各种setter，但注意不要调用setBundleAssetName
                .setJSBundleFile(UpdateContext.getBundleUrl(mContext, "assets://index.android.bundle"))
                .build();
UpdateContext.setCustomInstanceManager(mReactInstanceManager);
```
