WebView 与原生交互的原理

2025-04-25  本文已影响0人  lukyy

Web 与原生应用交互是现代混合应用开发中的核心概念,主要涉及 JavaScript 与原生代码(Java/Objective-C/Swift等)之间的通信。以下是其核心原理和实现方式:

基本原理

  1. 桥接机制(Bridge):在 Web 和原生环境之间建立通信桥梁
  2. 消息传递:通过特定格式的消息在两种环境间传递数据和调用请求

主要实现方式

1. JavaScript 调用原生功能

iOS 实现

// WKWebView 示例
let userContentController = WKUserContentController()
userContentController.add(self, name: "nativeHandler")

let config = WKWebViewConfiguration()
config.userContentController = userContentController
let webView = WKWebView(frame: .zero, configuration: config)

// 处理来自 JS 的消息
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
    if message.name == "nativeHandler" {
        // 处理原生逻辑
    }
}

Android 实

WebViewaddJavascriptInterface 方法
@JavascriptInterface 注解标记可调用方法

// Android 示例
public class WebAppInterface {
    @JavascriptInterface
    public void showToast(String toast) {
        Toast.makeText(context, toast, Toast.LENGTH_SHORT).show();
    }
}
webView.addJavascriptInterface(new WebAppInterface(), "Android");
2. 原生调用 JavaScript

iOS

// UIWebView
webView.stringByEvaluatingJavaScript(from: "javascriptFunction()")
// WKWebView
webView.evaluateJavaScript("javascriptFunction()") { (result, error) in
    // 处理结果
}

Android

webView.evaluateJavascript("javascript:javascriptFunction()", new ValueCallback<String>() {
    @Override
    public void onReceiveValue(String value) {
        // 处理返回值
    }
});

3. URL Scheme 拦截

通过自定义 URL 方案实现通信:

// JS 端触发
window.location.href = "myapp://action?param=value";

原生端拦截并处理:

// iOS - 在 WKNavigationDelegate 中
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
    if let url = navigationAction.request.url, url.scheme == "myapp" {
        // 处理自定义 scheme
        decisionHandler(.cancel)
        return
    }
    decisionHandler(.allow)
}
// Android - 重写 WebViewClient
webView.setWebViewClient(new WebViewClient() {
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        if (url.startsWith("myapp://")) {
            // 处理自定义 scheme
            return true;
        }
        return false;
    }
});

现代框架的实现

React Native
Flutter

Flutter 与 Android/iOS分别是怎么交互的?
WebView 插件提供类似桥接功能
MethodChannel 用于通信

Cordova/Ionic

性能考虑

  1. 同步 vs 异步:大多数桥接是异步的以避免阻塞
  2. 序列化开销:大数据量传递时有性能损耗
  3. 线程安全:需要注意跨线程操作问题

安全考虑

  1. 验证所有来自 Web 的输入
  2. 限制暴露的原生接口
  3. 防止 JavaScript 注入攻击
上一篇 下一篇

猜你喜欢

热点阅读