Web 与原生应用交互是现代混合应用开发中的核心概念,主要涉及 JavaScript 与原生代码(Java/Objective-C/Swift等)之间的通信。以下是其核心原理和实现方式:
基本原理
- 桥接机制(Bridge):在 Web 和原生环境之间建立通信桥梁
- 消息传递:通过特定格式的消息在两种环境间传递数据和调用请求
主要实现方式
1. JavaScript 调用原生功能
iOS 实现
-
UIWebView/WKWebView:
-JavaScriptCore
框架(UIWebView)
-evaluateJavaScript
方法(WKWebView)
-WKScriptMessageHandler
协议
// 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 实
WebView 的 addJavascriptInterface
方法
@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
- 使用异步的批量桥接机制
- 通过 JSON 序列化消息
- 三个主要线程:UI 线程、原生模块线程、JavaScript 线程
React Native与原生交互的原理
Flutter
Flutter 与 Android/iOS分别是怎么交互的?
WebView 插件提供类似桥接功能
MethodChannel 用于通信
Cordova/Ionic
- 通过
cordova.js
提供桥接 - 插件系统扩展原生功能
性能考虑
- 同步 vs 异步:大多数桥接是异步的以避免阻塞
- 序列化开销:大数据量传递时有性能损耗
- 线程安全:需要注意跨线程操作问题
安全考虑
- 验证所有来自 Web 的输入
- 限制暴露的原生接口
- 防止 JavaScript 注入攻击
网友评论