Skip to main content

加载在线 iframe 与之通信

WebView 加载的是一个在线的 iframe 内容,并且原生安卓/iOS 应用直接与这个 iframe 进行消息传递。我们可以利用 WebView 的 JavaScript 接口和 postMessage 方法来实现这一点。

安卓 (Android)

1. 设置 WebView 并启用 JavaScript

WebView webView = findViewById(R.id.webview);
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebViewClient(new WebViewClient());
webView.loadUrl("https://iframe-example.com");

2. 创建 JavaScript 接口

public class WebAppInterface {
Context mContext;

WebAppInterface(Context c) {
mContext = c;
}

@JavascriptInterface
public void handleMessage(String message) {
// 处理来自 JavaScript 的消息
Log.d("WebAppInterface", "Received message: " + message);
}
}

3. 将接口添加到 WebView

webView.addJavascriptInterface(new WebAppInterface(this), "AndroidInterface");

4. 在 iframe 页面中发送和接收消息

iframe-example.com 页面中的 JavaScript

// 假设这个代码在 iframe-example.com 中
function sendMessageToAndroid() {
if (window.AndroidInterface) {
window.AndroidInterface.handleMessage('Hello from iframe');
}
}

function receiveMessageFromAndroid(message) {
console.log('Received message from Android:', message);
}

window.addEventListener('message', function (event) {
if (event.data && event.data.source === 'android') {
receiveMessageFromAndroid(event.data.message);
}
});

5. 在安卓端发送消息到 iframe

// 发送消息到 iframe
webView.post(new Runnable() {
@Override
public void run() {
webView.evaluateJavascript("window.postMessage({source: 'android', message: 'Hello from Android'}, '*');", null);
}
});

iOS

1. 设置 WKWebView 并启用 JavaScript

import UIKit
import WebKit

class ViewController: UIViewController, WKScriptMessageHandler {
var webView: WKWebView!

override func viewDidLoad() {
super.viewDidLoad()

let config = WKWebViewConfiguration()
let contentController = WKUserContentController()
contentController.add(self, name: "iosListener")
config.userContentController = contentController

webView = WKWebView(frame: self.view.frame, configuration: config)
self.view.addSubview(webView)

if let url = URL(string: "https://iframe-example.com") {
webView.load(URLRequest(url: url))
}
}

func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
if message.name == "iosListener" {
if let messageBody = message.body as? String {
print("Received message from JavaScript: \(messageBody)")
}
}
}
}

2. 在 iframe 页面中发送和接收消息

iframe-example.com 页面中的 JavaScript

// 假设这个代码在 iframe-example.com 中
function sendMessageToiOS() {
if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.iosListener) {
window.webkit.messageHandlers.iosListener.postMessage('Hello from iframe');
}
}

function receiveMessageFromiOS(message) {
console.log('Received message from iOS:', message);
}

window.addEventListener('message', function (event) {
if (event.data && event.data.source === 'ios') {
receiveMessageFromiOS(event.data.message);
}
});

3. 在 iOS 端发送消息到 iframe

// 发送消息到 iframe
webView.evaluateJavaScript("window.postMessage({source: 'ios', message: 'Hello from iOS'}, '*');", completionHandler: nil)

通过上述代码,你可以在原生安卓和 iOS 应用中直接与加载的在线 iframe 内容进行消息传递。请确保 iframe-example.com 页面中的 JavaScript 代码已经包含了相应的消息处理逻辑。

iframe 不做任何展示,只进行数据交互

如果 WebView 仅用于数据处理而不做任何展示,我们可以将其隐藏起来,并通过 JavaScript 接口在后台进行消息传递和数据处理。以下是如何在 Android 和 iOS 上实现这一目标的示例。

安卓 (Android)

1. 设置隐藏的 WebView 并启用 JavaScript

首先,将 WebView 设置为隐藏状态。

<!-- 在 res/layout/activity_main.xml 中添加一个隐藏的 WebView -->
<WebView
android:id="@+id/webview"
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="gone"/>

然后,在 MainActivity 中配置 WebView。

public class MainActivity extends AppCompatActivity {
private WebView webView;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

webView = findViewById(R.id.webview);
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebViewClient(new WebViewClient());
webView.loadUrl("https://iframe-example.com");

webView.addJavascriptInterface(new WebAppInterface(this), "AndroidInterface");
}

public class WebAppInterface {
Context mContext;

WebAppInterface(Context c) {
mContext = c;
}

@JavascriptInterface
public void handleMessage(String message) {
// 处理来自 JavaScript 的消息
Log.d("WebAppInterface", "Received message: " + message);
// 这里可以处理数据或调用其他方法
}
}

// 发送消息到 iframe
public void sendMessageToIframe(String message) {
webView.post(new Runnable() {
@Override
public void run() {
webView.evaluateJavascript("window.postMessage({source: 'android', message: '" + message + "'}, '*');", null);
}
});
}
}

2. 在 iframe 页面中发送和接收消息

iframe-example.com 页面中的 JavaScript

// 假设这个代码在 iframe-example.com 中
function sendMessageToAndroid() {
if (window.AndroidInterface) {
window.AndroidInterface.handleMessage('Hello from iframe');
}
}

function receiveMessageFromAndroid(message) {
console.log('Received message from Android:', message);
}

window.addEventListener('message', function (event) {
if (event.data && event.data.source === 'android') {
receiveMessageFromAndroid(event.data.message);
}
});

iOS

1. 设置隐藏的 WKWebView 并启用 JavaScript

首先,将 WKWebView 设置为隐藏状态。

import UIKit
import WebKit

class ViewController: UIViewController, WKScriptMessageHandler {
var webView: WKWebView!

override func viewDidLoad() {
super.viewDidLoad()

let config = WKWebViewConfiguration()
let contentController = WKUserContentController()
contentController.add(self, name: "iosListener")
config.userContentController = contentController

webView = WKWebView(frame: CGRect.zero, configuration: config)
webView.isHidden = true
self.view.addSubview(webView)

if let url = URL(string: "https://iframe-example.com") {
webView.load(URLRequest(url: url))
}
}

func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
if message.name == "iosListener" {
if let messageBody = message.body as? String {
print("Received message from JavaScript: \(messageBody)")
// 这里可以处理数据或调用其他方法
}
}
}

// 发送消息到 iframe
func sendMessageToIframe(message: String) {
webView.evaluateJavaScript("window.postMessage({source: 'ios', message: '\(message)'}, '*');", completionHandler: nil)
}
}

2. 在 iframe 页面中发送和接收消息

iframe-example.com 页面中的 JavaScript

// 假设这个代码在 iframe-example.com 中
function sendMessageToiOS() {
if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.iosListener) {
window.webkit.messageHandlers.iosListener.postMessage('Hello from iframe');
}
}

function receiveMessageFromiOS(message) {
console.log('Received message from iOS:', message);
}

window.addEventListener('message', function (event) {
if (event.data && event.data.source === 'ios') {
receiveMessageFromiOS(event.data.message);
}
});

通过上述代码,你可以在 Android 和 iOS 应用中使用隐藏的 WebView 进行数据处理,而不进行任何展示。请确保 iframe-example.com 页面中的 JavaScript 代码已经包含了相应的消息处理逻辑。