WebView是现代移动应用中不可或缺的组件,它使应用能够显示Web内容,实现混合开发。本文将详细介绍鸿蒙系统中WebView的开发技术,包括基本使用、性能优化和最佳实践。
鸿蒙系统支持多种WebView实现:
在开发WebView应用前,需要在配置文件中添加相关权限:
{
"module": {
"requestPermissions": [
{
"name": "ohos.permission.INTERNET",
"reason": "访问网络内容",
"usedScene": {
"ability": [
"MainAbility"
],
"when": "always"
}
}
]
}
}
import webview from '@ohos.web.webview';
@Entry
@Component
struct WebViewDemo {
@State webviewController: webview.WebviewController = new webview.WebviewController();
build() {
Column() {
Web({
src: 'https://developer.harmonyos.com',
controller: this.webviewController
})
.width('100%')
.height('100%')
.onPageBegin((e) => {
console.info('页面开始加载:', e.url);
})
.onPageEnd((e) => {
console.info('页面加载完成:', e.url);
})
.onError((e) => {
console.error('加载错误:', e.error);
})
}
}
}
export class WebViewManager {
private webviewController: webview.WebviewController;
constructor(controller: webview.WebviewController) {
this.webviewController = controller;
}
// 加载URL
public loadUrl(url: string): void {
this.webviewController.loadUrl(url);
}
// 加载HTML内容
public loadHtml(html: string, baseUrl?: string): void {
this.webviewController.loadData(html, 'text/html', 'UTF-8', baseUrl);
}
// 执行JavaScript
public async evaluateJavaScript(script: string): Promise<string> {
try {
return await this.webviewController.runJavaScript(script);
} catch (error) {
console.error('执行JavaScript失败:', error);
throw error;
}
}
// 导航控制
public canGoBack(): Promise<boolean> {
return this.webviewController.canGoBack();
}
public goBack(): void {
this.webviewController.goBack();
}
public canGoForward(): Promise<boolean> {
return this.webviewController.canGoForward();
}
public goForward(): void {
this.webviewController.goForward();
}
public reload(): void {
this.webviewController.reload();
}
// 清理缓存
public clearCache(): void {
this.webviewController.clearCache();
}
}
// 定义JavaScript接口
class JavaScriptInterface {
// 调用原生方法
public callNative(data: string): string {
console.info('收到JavaScript调用:', data);
// 处理来自JavaScript的调用
return 'Native响应:' + data;
}
// 获取设备信息
public getDeviceInfo(): string {
return JSON.stringify({
platform: 'HarmonyOS',
version: '3.0',
deviceType: 'phone'
});
}
}
// WebView管理器扩展
export class WebViewBridgeManager extends WebViewManager {
// 注册JavaScript接口
public registerJavaScriptInterface(): void {
const jsInterface = new JavaScriptInterface();
this.webviewController.addJavaScriptInterface('NativeBridge', jsInterface);
}
// 注入JavaScript代码
public injectJavaScript(): void {
const script = `
window.NativeBridge = {
callNative: function(data) {
return window.NativeBridge.callNative(data);
},
getDeviceInfo: function() {
return JSON.parse(window.NativeBridge.getDeviceInfo());
}
};
`;
this.evaluateJavaScript(script);
}
}
下面我们将实现一个混合开发的新闻应用,展示如何结合WebView和原生功能:
import webview from '@ohos.web.webview';
import prompt from '@ohos.prompt';
@Entry
@Component
struct NewsApp {
@State currentUrl: string = 'https://news.example.com';
@State isLoading: boolean = false;
@State canGoBack: boolean = false;
private webviewController: webview.WebviewController = new webview.WebviewController();
private webViewManager: WebViewBridgeManager = new WebViewBridgeManager(this.webviewController);
aboutToAppear() {
this.initializeWebView();
}
async initializeWebView() {
// 注册JavaScript接口
this.webViewManager.registerJavaScriptInterface();
// 注入JavaScript代码
this.webViewManager.injectJavaScript();
// 检查是否可以后退
this.updateNavigationState();
}
async updateNavigationState() {
this.canGoBack = await this.webViewManager.canGoBack();
}
build() {
Column() {
// 导航栏
Row() {
Button({
type: ButtonType.Circle,
stateEffect: true
}) {
Image($r('app.media.back'))
.width(24)
.height(24)
}
.enabled(this.canGoBack)
.onClick(() => this.handleBack())
Button({
type: ButtonType.Circle,
stateEffect: true
}) {
Image($r('app.media.refresh'))
.width(24)
.height(24)
}
.onClick(() => this.webViewManager.reload())
TextInput({ text: this.currentUrl })
.width('60%')
.onChange((value: string) => {
this.currentUrl = value;
})
Button({
type: ButtonType.Circle,
stateEffect: true
}) {
Image($r('app.media.share'))
.width(24)
.height(24)
}
.onClick(() => this.handleShare())
}
.width('100%')
.height(50)
.padding(10)
.backgroundColor('#F5F5F5')
// 加载指示器
if (this.isLoading) {
LoadingProgress()
.width(50)
.height(50)
.position({
x: '50%',
y: '50%'
})
}
// WebView内容
Web({
src: this.currentUrl,
controller: this.webviewController
})
.width('100%')
.height('100%')
.onPageBegin((e) => {
this.isLoading = true;
this.currentUrl = e.url;
})
.onPageEnd((e) => {
this.isLoading = false;
this.updateNavigationState();
})
.onError((e) => {
this.isLoading = false;
prompt.showToast({
message: '加载失败:' + e.error
});
})
.javaScriptAccess(true)
.fileAccess(true)
.domStorageAccess(true)
}
.width('100%')
.height('100%')
}
// 处理返回事件
async handleBack() {
if (await this.webViewManager.canGoBack()) {
this.webViewManager.goBack();
}
}
// 处理分享
async handleShare() {
try {
// 获取页面标题
const title = await this.webViewManager.evaluateJavaScript(
'document.title'
);
// 调用系统分享
// 这里需要实现具体的分享逻辑
prompt.showToast({
message: `分享:${title}`
});
} catch (error) {
console.error('分享失败:', error);
}
}
// 自定义JavaScript方法
private injectCustomJavaScript() {
const script = `
// 监听页面图片点击
document.addEventListener('click', function(e) {
if (e.target.tagName === 'IMG') {
window.NativeBridge.callNative(JSON.stringify({
type: 'imageClick',
src: e.target.src
}));
}
});
// 添加下拉刷新
let startY = 0;
document.addEventListener('touchstart', function(e) {
startY = e.touches[0].pageY;
});
document.addEventListener('touchmove', function(e) {
const moveY = e.touches[0].pageY;
if (moveY - startY > 100 && window.scrollY === 0) {
window.NativeBridge.callNative(JSON.stringify({
type: 'pullToRefresh'
}));
}
});
`;
this.webViewManager.evaluateJavaScript(script);
}
}
// WebView预加载管理器
class WebViewPreloader {
private static instance: WebViewPreloader;
private preloadedWebView: webview.WebviewController | null = null;
private constructor() {}
public static getInstance(): WebViewPreloader {
if (!WebViewPreloader.instance) {
WebViewPreloader.instance = new WebViewPreloader();
}
return WebViewPreloader.instance;
}
// 预加载WebView
public preload(): void {
if (!this.preloadedWebView) {
this.preloadedWebView = new webview.WebviewController();
// 初始化配置
this.preloadedWebView.setWebviewSettings({
javaScriptEnabled: true,
domStorageEnabled: true
});
}
}
// 获取预加载的WebView
public getPreloadedWebView(): webview.WebviewController | null {
const webview = this.preloadedWebView;
this.preloadedWebView = null;
return webview;
}
}
// WebView缓存管理器
class WebViewCacheManager {
// 清理指定域名的缓存
public async clearDomainCache(domain: string): Promise<void> {
try {
const webviewController = new webview.WebviewController();
await webviewController.clearCache();
await webviewController.clearHistory();
console.info(`已清理${domain}的缓存`);
} catch (error) {
console.error('清理缓存失败:', error);
throw error;
}
}
// 设置缓存策略
public setCacheMode(mode: webview.CacheMode): void {
const webviewController = new webview.WebviewController();
webviewController.setCacheMode(mode);
}
}
本文详细介绍了鸿蒙系统中WebView开发的主要内容,包括:
通过本文的学习,开发者可以掌握鸿蒙系统WebView开发的核心知识,能够开发出性能优秀、体验流畅的混合应用。在实际开发中,建议结合具体业务需求,合理运用本文介绍的各项技术,同时注意性能优化和安全防护。