小伙伴你好,可以使用 ArkWeb组件 来实现 Web 应用的快速迁移和混合开发,可以最大程度复用现有 Web 资产代码。
解决方案
方案一:ArkWeb组件嵌入方案
说明:这是迁移成本最低的方案。通过 Web组件 来加载现有的Web页面,配合JSBridge实现原生与Web的双向通信。您现有的Web核心功能可以直接复用,只需开发原生壳和必要的桥接逻辑即可。
实现流程:

实现步骤:
1. 创建Web组件加载页面
代码示例:
import { webview } from '@kit.ArkWeb';
@Entry
@Component
struct WebComponent {
controller: webview.WebviewController = new webview.WebviewController();
build() {
Column() {
Web({ src: 'https://your-web-app.com', controller: this.controller })
.width('100%')
.height('100%')
}
}
}
2. 配置应用侧调用前端页面函数
当需要从原生侧调用Web页面的JavaScript函数时,使用 runJavaScript() 方法。
代码示例:
import { webview } from '@kit.ArkWeb';
import { BusinessError } from '@kit.BasicServicesKit';
@Entry
@Component
struct WebComponent {
controller: webview.WebviewController = new webview.WebviewController();
build() {
Column() {
Button('调用JS函数')
.onClick(() => {
// 调用前端页面的JavaScript函数
this.controller.runJavaScript('yourJsFunction()')
.then((result) => {
console.log('runJavaScript result: ' + result);
})
.catch((error: BusinessError) => {
console.error(`runJavaScript error: ${error.code}, ${error.message}`);
});
})
Web({ src: $rawfile('index.html'), controller: this.controller })
.width('100%')
.height('100%')
}
}
}
3. 配置前端页面调用应用侧函数
当Web页面需要调用原生能力时,通过 javaScriptProxy 注册原生对象供前端调用。
代码示例:
import { webview } from '@kit.ArkWeb';
/**
* 定义供前端调用的原生对象类
*/
class NativeBridge {
/**
* 获取设备信息
* @returns 设备信息字符串
*/
getDeviceInfo(): string {
return 'HarmonyOS Device';
}
/**
* 显示原生Toast
* @param message 消息内容
*/
showToast(message: string): void {
console.info('Toast: ' + message);
// 调用原生Toast API
}
/**
* 打开原生页面
* @param pageName 页面名称
*/
openNativePage(pageName: string): void {
console.info('Open page: ' + pageName);
// 实现原生页面跳转
}
}
@Entry
@Component
struct WebComponent {
controller: webview.WebviewController = new webview.WebviewController();
// 创建原生桥接对象
nativeBridge: NativeBridge = new NativeBridge();
build() {
Column() {
Web({ src: $rawfile('index.html'), controller: this.controller })
.javaScriptProxy({
object: this.nativeBridge,
name: 'nativeBridge', // 前端通过此名称调用
methodList: ['getDeviceInfo', 'showToast', 'openNativePage'],
controller: this.controller
})
.width('100%')
.height('100%')
}
}
}
4. 前端页面调用原生方法
在您的Web页面中,可以直接通过注册的对象名调用原生方法:
// 前端JavaScript代码
// 获取设备信息
const deviceInfo = nativeBridge.getDeviceInfo();
console.log(deviceInfo);
// 显示原生Toast
nativeBridge.showToast('操作成功');
// 打开原生页面
nativeBridge.openNativePage('settingsPage');
关键API说明:
方案二:混合开发方案(ArkUI + ArkWeb)
说明:将关键页面(如首页、登录页)使用ArkUI原生开发以获得更好的性能和用户体验,复杂业务页面继续使用Web组件加载。这种方案兼顾了开发效率和用户体验。
实现步骤:
1. 识别关键页面:分析应用的页面结构,将高频访问、性能敏感的页面标记为需要原生化的页面
2. 原生页面与Web页面混合架构
// MainPage.ets - 原生首页
import { router } from '@kit.ArkUI';
@Entry
@Component
struct MainPage {
build() {
Column() {
// 原生首页内容,获得最佳性能
Text('首页')
.fontSize(24)
Button('进入业务页面')
.onClick(() => {
// 跳转到Web页面
router.pushUrl({ url: 'pages/WebBusinessPage' });
})
}
}
}
// WebBusinessPage.ets - Web业务页面
import { webview } from '@kit.ArkWeb';
@Entry
@Component
struct WebBusinessPage {
controller: webview.WebviewController = new webview.WebviewController();
build() {
Column() {
Web({ src: 'https://your-web-app.com/business', controller: this.controller })
.width('100%')
.height('100%')
}
}
}
建议方案:
- 首页、登录页等高频页面建议原生化
- 复杂业务逻辑页面可继续使用Web
- 通过统一的导航框架管理原生页面和Web页面
- 保持一致的UI风格和交互体验
方案三:加载本地Web资源方案
说明:将Web应用打包到应用的 rawfile 目录中,通过加载本地资源实现离线访问,提升加载速度和用户体验。适合对网络依赖较小的应用场景。
实现步骤:
1. 将Web资源放入rawfile目录
将打包后的Web资源(HTML、CSS、JS、图片等)放入 src/main/resources/rawfile/ 目录:
src/main/resources/rawfile/
├── index.html
├── css/
│ └── style.css
├── js/
│ └── app.js
└── images/
└── logo.png
2. 加载本地Web资源
import { webview } from '@kit.ArkWeb';
@Entry
@Component
struct LocalWebPage {
controller: webview.WebviewController = new webview.WebviewController();
build() {
Column() {
// 加载本地HTML文件
Web({ src: $rawfile('index.html'), controller: this.controller })
.width('100%')
.height('100%')
.domStorageAccess(true) // 启用DOM存储
.fileAccess(true) // 启用文件访问
}
}
}
建议方案:
- 适合离线场景或网络环境较差的情况
- 加载速度更快,用户体验更好
- 需要在应用更新时同步更新Web资源
- 注意资源文件大小对应用包体积的影响
迁移建议
推荐迁移路径
根据您的情况(核心功能已完成大部分),建议采用以下渐进式迁移路径:
| 阶段 |
目标 |
工作内容 |
| 第一阶段 |
快速上架 |
使用方案一,通过Web组件直接加载现有Web应用 |
| 第二阶段 |
体验优化 |
使用方案二,将首页等关键页面原生化 |
| 第三阶段 |
深度优化 |
根据用户反馈,逐步将更多页面原生化 |
Web组件生命周期管理
在迁移过程中,了解 Web组件的生命周期 对于正确管理页面状态非常重要:
- onPageBegin:页面开始加载时触发
- onPageEnd:页面加载完成时触发
- onProgressChange:页面加载进度变化时触发
- onErrorReceive:页面加载错误时触发
Web({ src: 'https://your-web-app.com', controller: this.controller })
.onPageBegin((event) => {
console.info('页面开始加载: ' + event?.url);
})
.onPageEnd((event) => {
console.info('页面加载完成: ' + event?.url);
})
.onProgressChange((event) => {
console.info('加载进度: ' + event?.newProgress);
})
.onErrorReceive((event) => {
console.error('加载错误: ' + event?.error?.getErrorInfo());
})
参考文档