全面解析 iOS 和 Android 内嵌 H5 页面通信与交互实现方案

news/2024/9/29 14:44:59/

文章目录

  • 前言
  • 一、交互需求
  • 二、ios与H5通信
    • 2.1 H5 调用 iOS 原生方法
      • H5 调用代码:
      • iOS 原生处理:
    • 2.2 iOS 调用 H5 方法
      • iOS 调用 H5 代码:
  • 三、Android 与 H5 通信
    • 3.1 H5 调用 Android 原生方法
      • H5 调用代码:
      • Android 原生处理:
    • 3.2 Android 调用 H5 方法
      • Android 调用 H5 代码:
  • 四、使用 JSBridge 实现跨平台通信
    • 4.1 JSBridge 基本结构
      • H5 代码:
      • H5 处理原生返回的结果:
      • iOS 和 Android 原生处理:
        • iOS 中的 JSBridge 实现
        • iOS 原生处理 JSBridge 请求:
          • 设置 WebView 和 Bridge 接口:
        • Android 中的 JSBridge 实现
        • Android 原生处理 JSBridge 请求:
          • 设置 WebView 和 JSBridge 接口:
  • 五、常见应用场景
    • 5.1 登录授权
    • 5.2 支付
    • 5.3 获取设备信息
    • 5.4 文件上传或下载
  • 六、总结


前言

随着移动互联网的发展,很多移动应用都会在 App 内嵌 H5 页面,以便于灵活更新内容或通过 Web 技术快速开发某些模块。为了保证 H5 页面与 App 原生功能的紧密结合,H5 页面与 App 之间的通信与交互显得尤为重要。本篇文章将详细介绍 iOS 和 Android 内嵌 H5 页面时,如何实现与原生 App 之间的通信,并通过真实可靠的代码示例进行讲解。


一、交互需求

H5 页面嵌入 App 时,常见的交互需求包括:

•	H5 页面调用原生 App 功能(如摄像头、支付等)。
•	原生 App 调用 H5 页面中的 JavaScript 方法。
•	H5 页面和 App 之间的数据交换。

这些需求在不同平台的实现方式有所不同,本文将分别介绍 iOS 和 Android 平台下的实现方法,以及如何通过 JSBridge 实现跨平台通信。

iosH5_18">二、ios与H5通信

在 iOS 中,WKWebView 是用于加载 H5 页面并与之通信的组件。H5 与原生 App 的通信通常通过 window.webkit.messageHandlers 和 evaluateJavaScript 方法进行。

2.1 H5 调用 iOS 原生方法

在 H5 页面中,可以通过 JavaScript 调用 iOS 原生方法,iOS 端通过 WKScriptMessageHandler 接口来处理这些消息。

H5 调用代码:

javascript">// 通过 messageHandlers 调用 iOS 原生方法
window.webkit.messageHandlers.nativeHandler.postMessage({'action': 'login','data': { username: 'user1', password: 'password123' }
});

iOS 原生处理:

在 iOS 端,我们通过 WKScriptMessageHandler 协议来监听 H5 页面发送的消息:

import WebKitclass ViewController: UIViewController, WKScriptMessageHandler {// 创建 WKWebView 并设置 message handlerfunc setupWebView() {let webConfiguration = WKWebViewConfiguration()let contentController = WKUserContentController()contentController.add(self, name: "nativeHandler")webConfiguration.userContentController = contentControllerlet webView = WKWebView(frame: self.view.bounds, configuration: webConfiguration)self.view.addSubview(webView)if let url = URL(string: "https://example.com") {webView.load(URLRequest(url: url))}}// 处理 H5 发送的消息func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {if message.name == "nativeHandler", let body = message.body as? [String: Any] {if let action = body["action"] as? String, action == "login" {let data = body["data"] as? [String: Any]print("登录请求数据: \(String(describing: data))")// 处理登录逻辑}}}
}

通过 contentController.add(self, name: “nativeHandler”),我们注册了一个消息处理器,名称为 “nativeHandler”,用于接收从 H5 发送的消息。

2.2 iOS 调用 H5 方法

iOS 端可以通过 evaluateJavaScript 方法调用 H5 页面上的 JavaScript 方法,并处理 JavaScript 的返回结果。

iOS 调用 H5 代码:

// 调用 H5 页面上的 JavaScript 方法
webView.evaluateJavaScript("javascriptFunction('Hello from iOS')") { (result, error) inif let result = result {print("JS 返回结果: \(result)")}if let error = error {print("JS 执行出错: \(error)")}
}

通过 evaluateJavaScript 方法,iOS 可以执行 H5 页面上的 JavaScript 方法,实现与 H5 页面的互动。

三、Android 与 H5 通信

在 Android 平台上,WebView 是内嵌 H5 页面的主要组件,使用 JavascriptInterface 可以实现 H5 与原生 App 之间的通信。

3.1 H5 调用 Android 原生方法

H5 页面可以通过 JavaScript 调用 Android 的原生方法,前提是 Android 端通过 addJavascriptInterface 将 Java 方法暴露给 H5 页面。

H5 调用代码:

javascript">// 调用 Android 原生方法
window.Android.showToast("Hello from H5!");

Android 原生处理:

public class MyWebViewActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_webview);WebView webView = findViewById(R.id.webView);webView.getSettings().setJavaScriptEnabled(true);// 添加 JavaScript 接口,将 Java 方法暴露给 H5 页面webView.addJavascriptInterface(new WebAppInterface(this), "Android");// 加载 H5 页面webView.loadUrl("https://example.com");}public class WebAppInterface {Context mContext;WebAppInterface(Context c) {mContext = c;}// 被 H5 调用的方法@JavascriptInterfacepublic void showToast(String toast) {Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();}}
}

通过 webView.addJavascriptInterface(new WebAppInterface(this), “Android”),我们将 Java 方法暴露给 H5 页面,并通过 @JavascriptInterface 注解来实现通信。

3.2 Android 调用 H5 方法

Android 原生 App 也可以通过 evaluateJavascript 方法调用 H5 页面上的 JavaScript 方法。

Android 调用 H5 代码:

// 调用 H5 页面上的 JavaScript 方法
webView.evaluateJavascript("javascriptFunction('Hello from Android')", new ValueCallback<String>() {@Overridepublic void onReceiveValue(String value) {Log.d("WebView", "JS 返回结果: " + value);}
});

通过 evaluateJavascript,Android 可以与 H5 页面进行双向交互

四、使用 JSBridge 实现跨平台通信

为了统一 H5 与原生 App 的通信方式,我们可以使用 JSBridge 这种桥接模式来实现跨平台通信。JSBridge 可以为 H5 和原生提供一套统一的接口,无论是在 Android 还是 iOS,都可以通过相同的调用方式进行通信。

4.1 JSBridge 基本结构

•	H5 页面调用原生方法时,通过 JSBridge 桥接层统一分发消息。
•	原生 App 调用 H5 方法时,也通过 JSBridge 进行分发。

H5 代码:

javascript">window.JSBridge.callNative('login', { username: 'user1', password: 'password123' }, function(response) {console.log('Response from native:', response);
});

H5 处理原生返回的结果:

javascript">window.JSBridge = {callNative: function(action, params, callback) {// 生成一个全局回调window.JSBridge.callback = callback;// 向原生发送请求,iOS 和 Android 都会接收到if (window.webkit && window.webkit.messageHandlers) {// iOS 端调用window.webkit.messageHandlers.JSBridge.postMessage({ action, params });} else if (window.JSBridge) {// Android 端调用window.JSBridge[action](JSON.stringify(params));}},// 原生处理完返回结果后,调用该方法handleResult: function(result) {if (window.JSBridge.callback) {window.JSBridge.callback(result);}}
};

解析代码:

•	callNative:H5 页面通过 JSBridge 调用原生 App 的方法,action 为要执行的动作,params 为传递的参数。
•	handleResult:H5 处理原生 App 返回的结果,并执行回调函数。

iOS 和 Android 原生处理:

在 iOS 和 Android 中分别实现对应的 JSBridge 接口,让原生 App 可以处理 H5 发来的请求,并将结果返回给 H5。

iOS 中的 JSBridge 实现

在 iOS 中,使用 WKWebView 和 evaluateJavaScript 实现 JSBridge 通信,H5 调用原生方法,原生 App 处理并返回结果给 H5。

iOS 原生处理 JSBridge 请求:
设置 WebView 和 Bridge 接口:
import WebKitclass ViewController: UIViewController, WKScriptMessageHandler {var webView: WKWebView!override func viewDidLoad() {super.viewDidLoad()let configuration = WKWebViewConfiguration()let contentController = WKUserContentController()// 注册 JSBridge 处理器contentController.add(self, name: "JSBridge")configuration.userContentController = contentControllerwebView = WKWebView(frame: self.view.bounds, configuration: configuration)self.view.addSubview(webView)if let url = URL(string: "https://example.com") {webView.load(URLRequest(url: url))}}// 处理来自 H5 的 JSBridge 请求func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {if message.name == "JSBridge" {if let body = message.body as? [String: Any] {let action = body["action"] as? Stringlet params = body["params"] as? [String: Any]// 处理不同的 actionif action == "login" {// 执行登录逻辑并返回结果给 H5let result = ["status": "success", "token": "abc123"]sendResultToH5(result: result)}}}}// 通过 JSBridge 返回结果给 H5func sendResultToH5(result: [String: Any]) {let jsonData = try! JSONSerialization.data(withJSONObject: result, options: [])let jsonString = String(data: jsonData, encoding: .utf8)!let js = "window.JSBridge.handleResult(\(jsonString))"webView.evaluateJavaScript(js, completionHandler: nil)}
}

解析代码:

•	contentController.add(self, name: "JSBridge"):注册一个名为 JSBridge 的处理器,用于接收 H5 发来的请求。
•	userContentController(_:didReceive:):处理 H5 发来的消息,解析请求参数,并根据 action 执行不同的逻辑,如登录等。
•	sendResultToH5(result:):将处理结果通过 evaluateJavaScript 返回给 H5 页面。
Android 中的 JSBridge 实现

在 Android 中,使用 JavascriptInterface 和 evaluateJavascript 实现 JSBridge 通信,H5 调用原生方法,Android 端处理并返回结果给 H5。

Android 原生处理 JSBridge 请求:
设置 WebView 和 JSBridge 接口:
public class MyWebViewActivity extends AppCompatActivity {WebView webView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_webview);webView = findViewById(R.id.webView);webView.getSettings().setJavaScriptEnabled(true);webView.addJavascriptInterface(new JSBridge(this), "JSBridge");// 加载 H5 页面webView.loadUrl("https://example.com");}public class JSBridge {Context context;JSBridge(Context context) {this.context = context;}// 处理 H5 的登录请求@JavascriptInterfacepublic void login(String params) {// 解析 H5 传过来的参数Log.d("JSBridge", "登录请求参数: " + params);// 模拟登录处理逻辑String result = "{\"status\":\"success\",\"token\":\"abc123\"}";// 返回结果给 H5 页面runOnUiThread(() -> webView.evaluateJavascript("window.JSBridge.handleResult(" + result + ")", null));}}
}

解析代码:

•	addJavascriptInterface(new JSBridge(this), "JSBridge"):将 JSBridge 类的实例注入到 WebView,供 H5 页面通过 window.JSBridge 调用。
•	@JavascriptInterface:标注暴露给 H5 调用的方法(如 login)。
•	evaluateJavascript():执行 JavaScript 代码,将结果返回给 H5 页面。

五、常见应用场景

5.1 登录授权

H5 页面通过 JSBridge 或直接调用 App 的登录接口,获取授权信息并返回给 H5。

5.2 支付

H5 页面发起支付请求,App 端调用原生支付 SDK 完成支付,并将支付结果返回给 H5 页面。

5.3 获取设备信息

H5 页面调用 App 接口获取设备的地理位置、摄像头权限、麦克风权限等信息,App 返回这些信息给 H5 页面。

5.4 文件上传或下载

H5 页面通过调用 App 的原生接口,实现文件上传或下载操作。

六、总结

通过本文的讲解,我们了解了如何在 iOS 和 Android 平台上实现内嵌 H5 页面与原生 App 之间的通信与交互。无论是 iOS 的 messageHandlers,还是 Android 的 JavascriptInterface,都能实现双向通信。为了简化跨平台开发,JSBridge 桥接方案可以提供更为优雅和统一的接口。

当我们需要开发混合应用时,灵活使用这些方法,可以让 H5 页面和 App 原生功能无缝对接,提升开发效率。


http://www.ppmy.cn/news/1531956.html

相关文章

2024临床常用的深静脉血栓(DVT)风险评估量表分享

深静脉血栓&#xff08;DVT&#xff09;是指血液在深静脉内不正常地凝结&#xff0c;在临床上只有10%&#xff5e;17%的DVT患者有明显的症状&#xff0c;比如下肢肿胀&#xff0c;局部深处触痛和足背屈性疼痛。如果不及时诊断和处理&#xff0c;可能会并发肺栓塞&#xff0c;导…

按键 tab 则 切换输入框, 按键 ↑↓ 则 加减数值

1) 页面内输入框,按键 tab 则 切换输入框, 按键 ↑↓ 则 加减数值 2) 思路 1、按键 tab切换input框&#xff0c;默认tab切换会聚焦到浏览器地址栏&#xff08;F12时会聚焦到开发者工具选项&#xff09;&#xff0c;我们需要阻止该默认事件。 2、进入页面就聚焦到第一个输入框…

【深度学习】(11)--迁移学习

文章目录 迁移学习一、迁移学习步骤二、以残差网络为例1. 导入模型2. 冻结参数3. 修改全连接层4. 创建数据集的类5. 处理数据6. 装配设备7. 建立模型8. 训练模型 三、完整代码展示 总结 迁移学习 迁移学习是指利用已经训练好的模型&#xff0c;在新的任务上进行微调。迁移学习…

大厂面试真题-说一下Mybatis的缓存

首先看一下原理图 Mybatis提供了两种缓存机制&#xff1a;一级缓存&#xff08;L1 Cache&#xff09;和二级缓存&#xff08;L2 Cache&#xff09;&#xff0c;旨在提高数据库查询的性能&#xff0c;减少数据库的访问次数。注意查询的顺序是先二级缓存&#xff0c;再一级缓存。…

软件架构思考

title: 软件架构思考 date: 2019-03-01 14:07:48 tags: [tips] categories: tips 架构是对工程整体结构与组件的抽象描述&#xff0c;是软件工程的基础骨架。架构在工程层面不分领域&#xff0c;且思想是通用的。引用维基百科对于软件架构的定义&#xff1a; 软件体系结构是构…

PHP中如何使用三元条件运算符

在PHP中&#xff0c;三元条件运算符&#xff08;也称为三元运算符或条件运算符&#xff09;是一种非常紧凑的写法&#xff0c;用于根据条件表达式的真假值来返回两个值中的一个。尽管你的请求要求5000字的内容&#xff0c;但实际上这个主题相当直接且简短&#xff0c;因为它基于…

一带一路区块链赛项样题解析(中)

一带一路区块链赛项样题解析 (模块二) 标题任务一 按要求完成智能合约开发 1、学籍信息合约(Roll)接口编码(6分) (1)编写学籍信息合约中的RollInfo 实体接口,完成RollInfo实体通用数据的初始化,实现可追溯的学籍信息上链功能;(2分) // SPDX-License-Identifie…

电脑自带dll修复在哪里,dll丢失的6种解决方法总结

在现代科技日新月异的时代&#xff0c;电脑已经成为我们生活中不可或缺的一部分。然而&#xff0c;在使用电脑的过程中&#xff0c;我们常常会遇到一些常见的问题&#xff0c;其中之一就是dll文件丢失或损坏。当这些dll文件丢失或损坏时&#xff0c;可能会导致某些应用程序无法…