DSBridge - H5与Native高效通信的跨端解决方案
什么是 DSBridge
DSBridge 是一个现代化的 JavaScript 桥接库,用于实现 H5 与 Native(iOS/Android)之间的双向通信。它提供了同步调用、异步调用、进度回调等多种通信方式,是目前业界较为成熟的跨端通信解决方案之一。
为什么选择 DSBridge
传统方案的痛点
在使用传统的 WebView 通信方案时,我们经常会遇到以下问题:
- 异步问题:JavaScript 无法同步获取 Native 返回值
- 类型转换复杂:参数和返回值需要手动序列化和反序列化
- 调试困难:缺少统一的错误处理和日志追踪
- API 不统一:iOS 和 Android 需要使用不同的调用方式
DSBridge 的优势
- ✅ 同步调用支持:支持同步获取 Native 返回值
- ✅ 类型安全:自动处理数据序列化和反序列化
- ✅ 进度回调:支持 Native 向 H5 返回多次进度信息
- ✅ 跨平台统一:iOS 和 Android 使用相同的 API
- ✅ 命名空间:避免方法名冲突
- ✅ 调试友好:内置调试模式
安装
npm install dsbridge
# 或
yarn add dsbridge
基本使用
H5 端调用 Native
import dsBridge from 'dsbridge'
// 1. 异步调用(推荐)
dsBridge.call('getUserInfo', { userId: '123' }, (data) => {
console.log('用户信息:', data)
})
// 2. 同步调用(谨慎使用,会阻塞主线程)
const result = dsBridge.call('getToken')
console.log('Token:', result)
// 3. 使用命名空间
dsBridge.call('user.login', {
username: 'admin',
password: '123456'
}, (res) => {
if (res.success) {
console.log('登录成功')
}
})
Native 调用 H5
// H5 端注册方法供 Native 调用
dsBridge.register('updateUserInfo', (data) => {
console.log('收到 Native 推送的用户信息:', data)
// 更新页面数据
updateUI(data)
// 返回处理结果给 Native
return { success: true }
})
// 使用命名空间注册
dsBridge.register('app.onResume', () => {
console.log('应用从后台恢复')
// 刷新页面数据
refreshData()
})
进阶使用
进度回调
当 Native 执行耗时操作时,可以多次回调 H5 报告进度:
dsBridge.call('downloadFile', {
url: 'https://example.com/large-file.zip'
}, (progress) => {
if (progress.status === 'downloading') {
// 更新进度条
updateProgress(progress.percent)
} else if (progress.status === 'complete') {
console.log('下载完成:', progress.filePath)
} else if (progress.status === 'error') {
console.error('下载失败:', progress.message)
}
})
判断方法是否存在
// 检查 Native 是否实现了某个方法
if (dsBridge.hasNativeMethod('scanQRCode')) {
dsBridge.call('scanQRCode', {}, (result) => {
console.log('扫码结果:', result)
})
} else {
// 降级方案:使用 H5 扫码库
useH5QRCodeScanner()
}
设置调试模式
// 开启调试模式,会打印所有通信日志
dsBridge.setDebug(true)
实际应用场景
1. 获取设备信息
// 获取设备信息
dsBridge.call('device.getInfo', {}, (info) => {
console.log('设备信息:', {
platform: info.platform, // 'iOS' | 'Android'
version: info.version, // 系统版本
appVersion: info.appVersion // APP 版本
})
})
2. 调用原生能力
// 调用相机
dsBridge.call('camera.takePicture', {
quality: 0.8,
maxWidth: 1080
}, (result) => {
if (result.success) {
displayImage(result.imageUrl)
}
})
// 调用定位
dsBridge.call('location.getCurrentPosition', {}, (position) => {
console.log('当前位置:', position.latitude, position.longitude)
})
// 扫描二维码
dsBridge.call('scanQRCode', {}, (result) => {
if (result.text) {
handleQRCodeResult(result.text)
}
})
3. 原生分享
// 分享内容
dsBridge.call('share.toFriend', {
title: '文章标题',
desc: '文章描述',
imageUrl: 'https://example.com/image.jpg',
link: 'https://example.com/article/123'
}, (res) => {
if (res.success) {
toast('分享成功')
}
})
4. 页面跳转
// 跳转到原生页面
dsBridge.call('navigation.push', {
page: 'UserProfilePage',
params: { userId: '123' }
})
// 关闭当前 WebView
dsBridge.call('navigation.close', {})
最佳实践
1. 封装统一的调用方法
// utils/bridge.js
import dsBridge from 'dsbridge'
export const bridge = {
// 异步调用
callAsync(method, params = {}) {
return new Promise((resolve, reject) => {
if (!dsBridge.hasNativeMethod(method)) {
reject(new Error(`Native 方法 ${method} 不存在`))
return
}
dsBridge.call(method, params, (res) => {
if (res.error) {
reject(new Error(res.error))
} else {
resolve(res.data || res)
}
})
})
},
// 同步调用
callSync(method, params = {}) {
if (!dsBridge.hasNativeMethod(method)) {
console.warn(`Native 方法 ${method} 不存在`)
return null
}
return dsBridge.call(method, params)
},
// 注册方法
register(method, handler) {
dsBridge.register(method, handler)
}
}
// 使用示例
bridge.callAsync('getUserInfo', { userId: '123' })
.then(data => {
console.log('用户信息:', data)
})
.catch(err => {
console.error('获取失败:', err)
})
2. 类型定义(TypeScript)
// types/bridge.d.ts
interface BridgeResponse<T = any> {
success: boolean
data?: T
error?: string
}
interface UserInfo {
id: string
name: string
avatar: string
}
// 定义所有 Native 方法
interface NativeMethods {
getUserInfo(params: { userId: string }): Promise<UserInfo>
getToken(): string
scanQRCode(): Promise<{ text: string }>
// ...
}
3. 错误处理
// 统一错误处理
const callNative = async (method, params) => {
try {
// 检查是否在 APP 环境
if (!window.dsBridge) {
console.warn('不在 APP 环境中')
return null
}
// 检查方法是否存在
if (!dsBridge.hasNativeMethod(method)) {
console.warn(`Native 方法 ${method} 未实现`)
return null
}
// 调用方法
return await bridge.callAsync(method, params)
} catch (error) {
console.error(`调用 Native 方法失败: ${method}`, error)
// 上报错误
reportError(error)
return null
}
}
4. 环境判断
// utils/env.js
export const isInApp = () => {
return !!window.dsBridge
}
export const isIOS = () => {
return isInApp() && /iPhone|iPad|iPod/i.test(navigator.userAgent)
}
export const isAndroid = () => {
return isInApp() && /Android/i.test(navigator.userAgent)
}
// 使用
if (isInApp()) {
// 在 APP 中使用 Native 能力
dsBridge.call('getLocation')
} else {
// 在浏览器中使用 H5 能力
navigator.geolocation.getCurrentPosition()
}
常见问题
1. 调用无响应
- 检查 Native 端是否正确注册了方法
- 确认方法名和命名空间是否正确
- 使用
hasNativeMethod检查方法是否存在 - 开启调试模式查看日志
2. 参数传递问题
- DSBridge 会自动序列化 JSON,无需手动转换
- 避免传递函数、循环引用等无法序列化的数据
- 大数据量建议使用进度回调分批传输
3. 同步调用阻塞
- 同步调用会阻塞 JavaScript 主线程,谨慎使用
- 优先使用异步调用
- 仅在获取简单数据(如 token)时使用同步调用
总结
DSBridge 是一个强大而灵活的跨端通信解决方案,它极大地简化了 H5 与 Native 之间的交互。通过合理使用 DSBridge,我们可以:
- 充分利用 Native 能力,提升用户体验
- 统一 iOS 和 Android 的调用方式,降低维护成本
- 使用进度回调处理复杂的异步操作
- 通过命名空间组织代码,提高可维护性
在实际项目中,建议结合业务需求进行二次封装,统一错误处理和类型定义,让跨端通信更加健壮和易用。
相关资源
官方仓库
- GitHub (Android):https://github.com/wendux/DSBridge-Android
- GitHub (iOS):https://github.com/wendux/DSBridge-IOS
- npm 包地址:https://www.npmjs.com/package/dsbridge
官方文档
作者相关文章
- DSBridge 实战应用与原理解析 - DSBridge 在实际项目中的应用案例和技术细节
- 三端统一调用协议 - 作者关于跨端通信的思考
其他资源
- 作者:wendux(也是 Fly.js、dio.js 等项目的作者)
- 相关项目:Fly.js - 支持所有 JavaScript 运行环境的请求库
