「混合开发」H5与原生App交互流程方案全面解析

目录

内嵌H5调用iOS内的方法

1. 背景

2. 解决方案

2.1 创建WebView

2.2 注册原生方法

2.3 H5调用原生方法

3. 序列图

H5 调用 Android:详细指南

整体流程

每一步的详细说明

步骤1:在Android项目中设置WebView

步骤2:定义JavaScript接口

步骤3:加载H5网页

步骤4:在H5中调用Android方法

步骤5:处理Android的方法返回值

状态图

序列图

h5页面运行环境判断

一、先上代码:js封装

二、js封装代码的一些说明

三、配合vue封装个自定义指令


 

1.本文将介绍如何在H5页面中调用iOS原生方法,实现混合开发的功能。

2.本文将介绍如何在H5页面中调用Android原生方法,实现混合开发的功能。

3. h5页面运行环境判断


为什么H5能直接调用?

  • 环境注入:App启动WebView时,会向JS环境注入特定对象:

    • Android:注入window.Android对象

    • iOS:注入window.webkit.messageHandlers容器

  • 协议约定:双方提前约定方法名和参数格式

  • 桥梁作用:WebView充当通信代理,转发JS调用到原生代码

内嵌H5调用iOS内的方法

1. 背景

随着移动互联网的快速发展,原生应用与H5页面的结合成为了一种常见的开发方式。而在一些特定的场景中,我们需要在H5页面中调用iOS原生方法来实现一些功能,比如调用相册、获取地理位置等等。

2. 解决方案

在iOS中,我们可以通过JavaScriptCore框架来实现H5与iOS原生方法的交互。下面将介绍具体的实现步骤。

2.1 创建WebView

首先,我们需要在iOS原生应用中创建一个WebView,用于加载H5页面。可以使用WKWebViewUIWebView来实现,这里以WKWebView为例。

import WebKitclass ViewController: UIViewController, WKUIDelegate, WKScriptMessageHandler {var webView: WKWebView!override func loadView() {let webConfiguration = WKWebViewConfiguration()webView = WKWebView(frame: .zero, configuration: webConfiguration)webView.uiDelegate = selfview = webView}override func viewDidLoad() {super.viewDidLoad()// 加载H5页面if let url = Bundle.main.url(forResource: "index", withExtension: "html") {webView.loadFileURL(url, allowingReadAccessTo: url.deletingLastPathComponent())}// 注册JavaScript与原生方法的消息通信webView.configuration.userContentController.add(self, name: "nativeMethod")}
}
2.2 注册原生方法

在iOS原生应用中,我们需要注册一些原生方法,供H5页面调用。可以通过WKScriptMessageHandler协议来实现。

extension ViewController {func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {if message.name == "nativeMethod" {let body = message.body as? [String: Any]let method = body?["method"] as? Stringlet params = body?["params"] as? [String: Any]if method == "openCamera" {openCamera()} else if method == "getLocation" {getLocation()}}}func openCamera() {// 打开相机逻辑}func getLocation() {// 获取地理位置逻辑}
}
2.3 H5调用原生方法

在H5页面中,我们可以通过JavaScript代码来调用iOS原生方法。可以使用window.webkit.messageHandlers对象来发送消息给iOS原生应用。

function callNativeMethod(method, params) {window.webkit.messageHandlers.nativeMethod.postMessage({ method: method, params: params });
}// 调用原生相机方法示例
callNativeMethod("openCamera");// 调用原生地理位置方法示例
callNativeMethod("getLocation");

3. 序列图

下面是一个使用Sequence Diagram插件绘制的序列图,说明了H5调用iOS原生方法的流程。

iOS原生应用H5页面iOS原生应用H5页面调用原生方法执行原生方法


 

H5 调用 Android:详细指南

在现代的应用开发中,H5(HTML5)和原生Android应用之间的交互变得越来越重要。通过这种交互,开发者可以充分利用两者的优势,提高用户体验。在本文中,我将为你详细介绍如何实现H5调用Android的过程,包括每一步的详细步骤、代码示例以及图示表示。

整体流程

下面是H5调用Android的流程表:

步骤描述
1在Android项目中设置WebView
2定义JavaScript接口
3加载H5网页
4在H5中调用Android方法
5处理Android的方法返回值

每一步的详细说明

步骤1:在Android项目中设置WebView

首先,在你的Android项目中创建一个WebView,以便加载H5页面。

// MainActivity.java
import android.os.Bundle;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity {private WebView webView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 找到WebView组件webView = findViewById(R.id.webView);// 允许JavaScript执行webView.getSettings().setJavaScriptEnabled(true);// 加载H5页面webView.setWebViewClient(new WebViewClient());webView.loadUrl("file:///android_asset/index.html"); //加载本地H5页面}
}

代码说明:

  • getSettings().setJavaScriptEnabled(true);:允许在WebView中执行JavaScript,这样H5能够调用安卓的方法。
  • loadUrl(...):加载你的H5页面,可以是本地文件或网络地址。
步骤2:定义JavaScript接口

你需要定义一个JavaScript接口,使H5能够调用Android的方法。

import android.webkit.JavascriptInterface;public class WebAppInterface {MainActivity mActivity;WebAppInterface(MainActivity c) {mActivity = c;}@JavascriptInterfacepublic void showToast(String toast) {Toast.makeText(mActivity, toast, Toast.LENGTH_SHORT).show();}
}// 在MainActivity中
webView.addJavascriptInterface(new WebAppInterface(this), "Android");

代码说明:

  • @JavascriptInterface注解让H5中的JavaScript可以访问Android的方法。
  • showToast(String toast)是供H5调用的一个示例方法。
步骤3:加载H5网页

H5页面的内容可以是一个简单的HTML文件,比如index.html

<!DOCTYPE html>
<html>
<head><title>H5 to Android</title><script type="text/javascript">function callAndroid() {// 调用Android方法Android.showToast("Hello from H5!");}</script>
</head>
<body>H5调用Android<button onclick="callAndroid()">调用Android</button>
</body>
</html>

代码说明:

  • onclick="callAndroid()":当用户点击按钮时,将调用callAndroid函数,该函数将通过Android接口调用showToast方法。
步骤4:在H5中调用Android方法

之前的代码已经涵盖了这一部分。用户点击按钮时,H5会调用Android的showToast方法。

步骤5:处理Android的方法返回值

如果你的Android方法需要返回值,确保你在JavaScript接口中做相应的处理。例如,假设你要在Android中返回当前时间:

@JavascriptInterface
public String getCurrentTime() {return java.text.DateFormat.getDateTimeInstance().format(new java.util.Date());
}

然后在H5中调用它:

function fetchTime() {// 获取当前时间并显示var currentTime = Android.getCurrentTime();alert("Current Time: " + currentTime);
}

状态图

以下是H5与Android之间的状态转移图示,描述了用户如何触发操作:

H5页面调用AndroidAndroid执行返回结果

序列图

下面是H5调用Android的序列图:

AndroidH5AndroidH5调用showToast("Hello from H5!")显示Toast消息

h5页面运行环境判断

  • 判断h5页面所处的运行环境,以便针对不同的环境做兼容性或差异化处理;
  • 由于很多时候需要一进页面就第一时间做处理,所以异步的判断方法都不予考虑,必须是能实时获取的;
  • 那么自然的,判断UA是最好、最方便的方式。

一、先上代码:js封装

platform.js:

const ua = window.navigator.userAgent.toLowerCase()// android平台
const isAndroid = (() => {return /Android|Adr/i.test(ua)
})()// ios平台
const isIos = (() => {return /iPhone|iPod|iPad/i.test(ua)
})()// 微信生态
const isWechat = (() => {return /MicroMessenger/i.test(ua)
})()// 微信小程序
const isWxmp = (() => {return /miniProgram/i.test(ua) || window.__wxjs_environment === 'miniprogram'
})()// 钉钉环境
const isDingding = (() => {return /DingTalk/i.test(ua)
})()// 自家的android客户端
const isInnerAdr = (() => {return isAndroid && /dianyidian/i.test(ua)
})()// 自家的ios客户端
const isInnerIos = (() => {return isIos && /dianyidian/i.test(ua)
})()// 自家的app客户端
const isInnerApp = (() => {return isInnerAdr || isInnerIos
})()// 站内
const isInner = (() => {return isInnerAdr || isInnerIos || isWxmp
})()// 站外
const isOuter = (() => {return !isInner
})()export default {isAndroid,isIos,isWechat,isWxmp,isDingding,isInnerAdr,isInnerIos,isInnerApp,isInner,isOuter
}

 

二、js封装代码的一些说明

  • 微信生态,包括微信小程序、微信内置浏览器、微信公众号等
  • 针对hybrid混合开发模式中的webview内嵌h5页,需要判断自家的客户端,这时需要让客户端开发人员修改webview的UA,添加上特殊的UA标识,用来给h5做判断,比如我这里的标识就是dianyidian。
  • 关于站内站外的划分因人而异,自己决定,使用方便就好。
  • 导出的每一个属性值都是boolean类型,true或false。
  • 在自家ios客户端接入阿里百川后发现UA被莫名的覆盖了,这种情况可以额外加个判断处理:
// 自家ios客户端
const isInnerIos = (() => {if (isIos && /baichuan/i.test(ua)) {// 兼容ios客户端跳转阿里百川授权后再打开webview的userAgent被百川覆盖的问题return true}return isIos && /dianyidian/i.test(ua)
})()
  • 以上都是实际项目中经过考验了的,放心使用。

三、配合vue封装个自定义指令

  • 指令作用:根据页面运行环境给元素添加相应的class类名,这样就可以在css样式里很方便的对不同环境做不同的处理。
  • 指令封装:
// 先引入上述封装的platform.js
import platform from '@/utils/platform'export default {bind (el) {Object.keys(platform).forEach(v => {if (platform[v]) {el.classList.add(v)}})}
}
  • 使用示例:
<template><div class="demo" v-platforms>使用示例</div>
</template><script>
import platforms from '@/directive/platforms/index'export default {directives: { platforms }
}
</script><style lang='less' scoped>
.demo {color: red;&.isAdr {// 安卓平台下的自定义样式处理}&.isIos {// ios平台下的自定义样式处理}&.isWxmp {// 微信小程序下的自定义样式处理}// 其他环境下也一样,任性的加......
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/diannao/86458.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

webpack打包vue项目

要在 Vue 项目中使用 Webpack 进行打包&#xff0c;通常有几种不同的方式来设置你的项目。以下是基本步骤&#xff1a; 1. 使用 Vue CLI 创建项目&#xff08;推荐&#xff09; Vue CLI 是官方提供的一个脚手架工具&#xff0c;它内置了对 Webpack 的支持&#xff0c;并且简化…

Linux环境-通过命令查看zookeeper注册的服务

假设前置条件如下&#xff1a; 1.root权限用户名&#xff1a;zookeeper 2.zookeeper所在服务器地址&#xff1a;168.7.3.254&#xff08;非真实ip&#xff09; 3.zookeeper的bin文件路径&#xff1a;/opt/zookeeper/bin 4.确保zookeeper注册中心已启动 查看注册中心服务如下&a…

BLEU评分:机器翻译质量评估的黄金标准

BLEU评分&#xff1a;机器翻译质量评估的黄金标准 1. 引言 在自然语言处理(NLP)领域&#xff0c;衡量一个机器翻译模型的性能至关重要。BLEU (Bilingual Evaluation Understudy) 作为一种自动化评估指标&#xff0c;自2002年由IBM的Kishore Papineni等人提出以来&#xff0c;…

ArcGIS计算多个栅格数据的平均栅格

3种方法计算多个栅格数据的平均栅格 1->使用“ 栅格计算器”工具 原理就是把多幅影像数据相加&#xff0c;然后除以个数&#xff0c;就能得到平均栅格。 2-> 使用“像元统计数据”工具&#xff0c;如果是ArcGIS pro&#xff0c;则是“像元统计”工具。使用这个工具可以…

Ubantu-Docker配置最新镜像源250605

尝试其他镜像加速器 阿里云镜像加速器&#xff1a;登录阿里云&#xff0c;进入容器镜像服务获取专属加速器地址。毫秒镜像&#xff1a;https://docker.1ms.run。DockerHub镜像加速器&#xff1a;https://docker.xuanyuan.me。Docker Hub 镜像加速服务&#xff1a;https://dock…

中医有效性探讨

文章目录 西医是如何发展到以生物化学为药理基础的现代医学&#xff1f;传统医学奠基期&#xff08;远古 - 17 世纪&#xff09;近代医学转型期&#xff08;17 世纪 - 19 世纪末&#xff09;​现代医学成熟期&#xff08;20世纪至今&#xff09; 中医的源远流长和一脉相承远古至…

Unity网络通信笔记

需求 首先要意识到网络通信面对的是一个怎么样的情景&#xff1a; 服务器会连任意个客户端&#xff0c;任意时刻可能有客户端连入连出&#xff1b;服务端和客户端可能任意时刻给对方发消息&#xff0c;所以双方都要一直准备好接收。但是两端还有别的事要做&#xff0c;通信不…

EasyRTC嵌入式音视频通信SDK音视频功能驱动视频业务多场景应用

一、方案背景​ 随着互联网技术快速发展&#xff0c;视频应用成为主流内容消费方式。用户需求已从高清流畅升级为实时互动&#xff0c;EasyRTC作为高性能实时音视频框架&#xff0c;凭借低延迟、跨平台等特性&#xff0c;有效满足市场对多元化视频服务的需求。 二、EasyRTC技术…

《MLB美职棒》勇士队排名·棒球1号位

亚特兰大勇士队&#xff08;Atlanta Braves&#xff09;是美国职业棒球大联盟&#xff08;MLB&#xff09;中历史最悠久的球队之一&#xff0c;隶属于国家联盟&#xff08;NL&#xff09;东区。 球队基本信息 成立时间&#xff1a;1871年&#xff08;前身为波士顿红袜帽队&…

yaml读取写入常见错误 (‘cannot represent an object‘, 117)

错误一&#xff1a;yaml.representer.RepresenterError: (‘cannot represent an object’, 117) 出现这个问题一直没找到原因&#xff0c;后面把yaml.safe_dump直接替换成yaml.dump&#xff0c;确实能保存&#xff0c;但出现乱码&#xff1a; 放弃yaml.dump&#xff0c;又切…

每日一令:Linux 极简通关指南 - 汇总

专栏列表 &#x1f4bb; 每日一令&#xff1a;Linux 极简通关指南 (25篇) 【基础】每天掌握一个Linux命令 - nsenter&#xff1a;深入容器与命名空间的利器 发布于 2025-06-08 22:27:04【基础】 每天掌握一个Linux命令 - journalctl&#xff1a;系统日志管理的得力助手 发布于…

Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术点解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、Spring MVC与MyBatis技术点解析 第一轮&#xff1a;基础概念问题 请解释Spring框架的核心容器是什么&#xff1f;它的作用是什么&#xff1f; 程序员JY回答&#xff1a;Spring框架的核心容器是IoC容器&#xff08;控制反转…

渗透测试服务如何全方位评估企业安全状况并揭示潜在缺陷?

渗透测试服务通过模拟攻击行为&#xff0c;对企业整体安全状况进行全方位评估&#xff0c;旨在揭示潜在的安全缺陷并制定相应的修复措施。以下为渗透测试服务报告的核心内容。 测试类型适配 外部渗透测试旨在模仿外部网络攻击者&#xff0c;尝试突破企业网络安全防线&#xf…

SwiftUI 数据绑定与视图更新(@State、@ObservedObject、@EnvironmentObject)

引言 在 SwiftUI 中&#xff0c;界面并不是通过手动刷新来更新的&#xff0c;而是由状态驱动的。当状态发生变化&#xff0c;SwiftUI 会自动识别哪些视图需要重绘&#xff0c;从而保持 UI 与数据的一致性。这种声明式的方式大大简化了界面开发的流程&#xff0c;但也带来一个问…

21-Oracle 23 ai-Automatic SQL Plan Management(SPM)

小伙伴们&#xff0c;有没有迁移数据库完毕后或是突然某一天在同一个实例上同样的SQL&#xff0c; 性能不一样了、业务反馈卡顿、业务超时等各种匪夷所思的现状。 于是SPM定位开始&#xff0c;OCM考试中SPM必考。 其他的AWR、ASH、SQLHC、SQLT、SQL profile等换作下一个话题…

[Linux] 命令行管理文件

目录 FHS 文件路径导航 ls命令 tree命令 stat命令 touch命令 命令行管理文件 mkdir命令 cp命令 mv命令 rm和rmdir命令 软链接 硬链接 软连接硬链接区别 shell扩展匹配文件 FHS FHS采用树形结构组织文件&#xff0c;定义了系统中每个区域的用途、所需要的最小构…

自动化过程中,如何定位一闪而过的toast?

MutationObserver实战&#xff1a;动态捕获页面Toast消息的终极解决方案 一、代码全景解析 const observer new MutationObserver((mutations) > {// 回调函数主体... });observer.observe(document.body, {childList: true,subtree: true });核心组件解析 组件作用重要…

基于 Three.js 的数字雨波纹效果技术解析

文章目录 一、基础环境搭建与 Three.js 引入​二、场景与相机设置​三、后期处理:光晕效果的实现​四、纹理创建:定制雨滴、波纹和水花外观​五、粒子系统:模拟雨滴下落与交互​1,雨滴粒子系统​2,波纹与水花系统​六、动画循环与交互响应​本文将深入剖析一段实现该效果的…

联想拯救者R9000P 网卡 Realtek 8852CE Ubuntu/Mint linux 系统睡眠后,无线网卡失效

联想拯救者R9000P 网卡型号 Realtek PCle GbE Family Controller Realtek 8852CE WiFi 6E PCI-E NIC 系统版本 Ubuntu 24.04 / mint 22.1 问题现象 rtw89_8852ce&#xff0c;Link is Down&#xff0c;xtal si not ready&#xff0c;mac init fail&#xff0c;xtal si not …

Java详解LeetCode 热题 100(26):LeetCode 142. 环形链表 II(Linked List Cycle II)详解

文章目录 1. 题目描述1.1 链表节点定义 2. 理解题目2.1 问题可视化2.2 核心挑战 3. 解法一&#xff1a;HashSet 标记访问法3.1 算法思路3.2 Java代码实现3.3 详细执行过程演示3.4 执行结果示例3.5 复杂度分析3.6 优缺点分析 4. 解法二&#xff1a;Floyd 快慢指针法&#xff08;…