- 添加 symbolicator 服务配置到 docker-compose.yml - 配置 bugcollect-service 连接 symbolicator URL - 设置 symbolicator 端口映射和资源限制 - 添加源码映射文件挂载目录 - 为 RN/Android/iOS/Flutter 堆栈符号化提供支持 docs(xwebview): 更新已知问题文档 - 记录 RN 0.85 Bridgeless 模式下 react-native-blob-util 崩溃问题 - 说明 react-native-blob-util 在 JSI/TurboModule 下初始化失败原因 - 提供宿主 app 使用 XWebViewContent 替代方案 - 添加待修复方案说明
152 行
4.9 KiB
Markdown
152 行
4.9 KiB
Markdown
# @xuqm/rn-xwebview
|
||
|
||
XuqmGroup RN SDK WebView 模块。提供增强型 WebView 组件和 JSBridge 通信能力。
|
||
|
||
## 安装
|
||
|
||
```bash
|
||
yarn add @xuqm/rn-xwebview react-native-webview react-native-blob-util react-native-svg
|
||
```
|
||
|
||
Peer dependencies:`react >= 18`,`react-native >= 0.76`,`@react-navigation/native >= 7.0.0`
|
||
|
||
## 组件
|
||
|
||
### XWebViewScreen — 全屏 WebView(React Navigation screen)
|
||
|
||
```tsx
|
||
import { XWebViewScreen } from '@xuqm/rn-xwebview'
|
||
|
||
// 在导航中使用
|
||
<XWebViewScreen />
|
||
// URL 通过 openXWebView() 预设
|
||
```
|
||
|
||
### XWebViewView — 嵌入式 WebView 组件
|
||
|
||
```tsx
|
||
import { XWebViewView } from '@xuqm/rn-xwebview'
|
||
|
||
<XWebViewView
|
||
config={{
|
||
url: 'https://example.com',
|
||
title: '嵌入式网页',
|
||
jsBridgeName: 'XWebViewBridge',
|
||
}}
|
||
/>
|
||
```
|
||
|
||
### XWebViewProgress — 进度条
|
||
|
||
```tsx
|
||
import { XWebViewProgress } from '@xuqm/rn-xwebview'
|
||
|
||
<XWebViewProgress progress={50} />
|
||
```
|
||
|
||
## API
|
||
|
||
| API | 说明 |
|
||
|-----|------|
|
||
| `openXWebView(url, options?)` | 打开 WebView 页面 |
|
||
| `setXWebViewController(controller)` | 设置全局 WebView 控制器 |
|
||
| `getXWebViewConfig()` | 获取当前 WebView 配置 |
|
||
| `XWebViewControl` | WebView 控制器类 |
|
||
|
||
## XWebViewConfig 参数
|
||
|
||
| 参数 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| `url` | string | 初始加载地址 |
|
||
| `title` | string | 页面标题 |
|
||
| `jsBridgeName` | string | JS 桥接对象名(默认 `'XWebViewBridge'`) |
|
||
| `hideToolbar` | boolean | 隐藏顶栏 |
|
||
| `userAgent` | string? | 自定义 User-Agent |
|
||
| `injectedJavaScript` | string? | 页面加载后注入的 JS |
|
||
| `onMessage` | (event) => void | H5 发送消息回调 |
|
||
|
||
## JSBridge 通信
|
||
|
||
```js
|
||
// H5 → Native
|
||
window.XWebViewBridge.postMessage(JSON.stringify({ type: 'login', token: '...' }))
|
||
|
||
// Native → H5
|
||
controller.postMessageToWeb("window.dispatchEvent(new CustomEvent('nativeMsg', { detail: { key: 'value' } }))")
|
||
```
|
||
|
||
### 内置 JSBridge Handler
|
||
|
||
| Action | 说明 | 参数 |
|
||
|--------|------|------|
|
||
| `xuqm.getDeviceInfo` | 获取设备信息 | — |
|
||
| `xuqm.getToken` | 获取当前用户 token | — |
|
||
| `xuqm.getUserInfo` | 获取用户信息 | — |
|
||
| `xuqm.openNativePage` | 打开原生页面 | `{ route, params? }` |
|
||
| `xuqm.closeWebView` | 关闭 WebView | — |
|
||
| `xuqm.showToast` | 显示 Toast | `{ message }` |
|
||
| `xuqm.scanQRCode` | 打开扫码页(需宿主注册 handler) | — |
|
||
|
||
## 文件下载
|
||
|
||
XWebView 内置文件下载支持,自动拦截以下场景:
|
||
|
||
1. URL 以常见下载扩展名结尾(`.pdf`, `.zip`, `.apk` 等)
|
||
2. `<a download="...">` 标签点击
|
||
3. `blob:` URL 下载(通过 injected JS 拦截)
|
||
|
||
### 使用 `handleDownloadRequest`
|
||
|
||
```ts
|
||
import { handleDownloadRequest } from '@xuqm/rn-xwebview'
|
||
|
||
const handle = await handleDownloadRequest(url, hintFilename, {
|
||
autoDownload: true,
|
||
downloadConflict: 'rename',
|
||
onDownloadProgress: (p) => console.log(`${p.percentage}%`),
|
||
onDownloadComplete: (r) => console.log('saved to', r.filePath),
|
||
onDownloadError: (url, err) => console.error(err),
|
||
})
|
||
// handle?.cancel() 可取消下载
|
||
```
|
||
|
||
### XWebViewConfig 下载相关参数
|
||
|
||
| 参数 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| `autoDownload` | boolean | 自动下载(默认 true),false 时需 onDownloadDecide |
|
||
| `downloadConflict` | `'rename' \| 'overwrite'` | 文件名冲突策略(默认 rename) |
|
||
| `onDownloadStart` | (request) => void | 下载开始回调 |
|
||
| `onDownloadProgress` | (progress) => void | 下载进度回调 |
|
||
| `onDownloadComplete` | (result) => void | 下载完成回调 |
|
||
| `onDownloadError` | (url, error) => void | 下载失败回调 |
|
||
| `onDownloadDecide` | (request) => Decision | 非自动模式下的下载决策回调 |
|
||
|
||
### 低级 API
|
||
|
||
| API | 说明 |
|
||
|-----|------|
|
||
| `fetchDownloadInfo(url, hintFilename?)` | HEAD 请求获取文件名/MIME/大小 |
|
||
| `saveBase64File(base64, filename, savePath?, conflict)` | 保存 base64 数据为文件 |
|
||
| `startDownload(url, filename, savePath?, conflict, onProgress, onComplete, onError)` | 开始下载,返回 DownloadHandle |
|
||
|
||
详细 handler 列表见 `@xuqm/rn-common` 的 `xwebview/` 目录。
|
||
|
||
## 已知问题
|
||
|
||
### RN 0.85 Bridgeless 模式下 `react-native-blob-util` 崩溃
|
||
|
||
**现象**:宿主 app 使用 RN 0.85 Bridgeless 模式时,引入 `XWebViewView` 会触发
|
||
`XWebViewDownload.ts` 中 `react-native-blob-util` 的模块级初始化,导致
|
||
`Cannot read property 'getConstants' of null`。
|
||
|
||
**根因**:`react-native-blob-util` 目前在 RN 0.85 JSI/TurboModule 路径下 `ReactNativeBlobUtil`
|
||
原生模块为 `null`,`PackageList.java` 的旧架构注册方式不足以在 Bridgeless 模式下完成初始化。
|
||
|
||
**临时方案**:宿主 app 的 `XWebViewContent` 直接使用 `react-native-webview`,
|
||
跳过 `XWebViewView`,功能对等(无下载拦截和 JSBridge,纯内容展示场景够用)。
|
||
|
||
**待修复**:
|
||
- 升级 `react-native-blob-util` 到支持 Bridgeless 的版本,或
|
||
- 在 `XWebViewDownload.ts` 中对 `ReactNativeBlobUtil` 为 null 做防御,延迟到实际下载时才初始化
|