移动端web页面调用原生jsbridge的封装

为了统一android端和ios端调用原生jsbridge方法统一,且web端不需要使用callback方式接收回调,特封装了以下js工具类:

// 全局回调管理器
window.CallbackManager = {callbacks: new Map(),registerCallback: function (callbackId, callback) {
this.callbacks.set(callbackId, callback);
},unregisterCallback: function (callbackId) {
this.callbacks.delete(callbackId);
},invokeCallback: function (callbackId, result) {const callback = this.callbacks.get(callbackId);console.log("查看回调数据:"+callbackId+"***"+result);if (callback) {callback(result);console.log("执行了回调");this.unregisterCallback(callbackId);}
},invokeCallbackForIOS: function (result) {
let decodedResponse = decodeURIComponent(result);
const jsonObject = JSON.parse(decodedResponse);
let callbackId = jsonObject.callbackIdconst callback = this.callbacks.get(callbackId);
console.log("查看回调数据:"+callbackId+"***"+result);
if (callback) {callback(jsonObject.result);console.log("执行了回调");this.unregisterCallback(callbackId);}}};window.mobileNativeMethod= {
callHandler: function (methodName, params, callback) {let userAgent = navigator.userAgent;if (/iPad|iPhone|iPod/.test(userAgent)) {// iOS平台调用原生方法let callbackId = Math.random().toString(36).substring(7);let jsonParams = JSON.parse(params)jsonParams.methodName = methodNamejsonParams.callbackId = callbackIdwindow.webkit.messageHandlers.mobileNativeMethod.postMessage(JSON.stringify(jsonParams));CallbackManager.registerCallback(callbackId, callback);} else if (userAgent.indexOf('Android') > -1) {// Android平台调用原生方法if (window.androidJavascript) {console.log("查看调用:"+methodName+"***"+params)let callbackId = Math.random().toString(36).substring(7);window.androidJavascript.callHandler(methodName, params, callbackId);CallbackManager.registerCallback(callbackId, callback);}} else {console.warn('Unsupported platform');}}
};

在web页面移动端统一使用 **window.mobileNativeMethod.callBack(methodName,params, callback)**方法调用原生实现的方法。
methodName是字符串方法名,params是Map参数,如果需要接收回调需要实现callback,如果不需要回调可以省略回调。

此处以android原生端实现的jsbridge为例,示例实现如下:

public class MyWebViewJavaScript {
private final String TAG = “MyWebViewJavaScript”;
private TextView mTvtitle;
private SetWebTitle mSetWebTitle;
List mHandles;
public Map<String, String> callBackIdStack;
private StWebView mWebView;
private Handler mHandler;
//响应数据
private String response = “”;

public interface SetWebTitle {void toSetWebTitle(String title);void toHideTitleBar(boolean isHide);
}public WebViewJavaScript(StWebView webview, SetWebTitle setWebTitle) {EventBusUtil.register(this);this.mWebView = webview;callBackIdStack = new HashMap<>();mHandler = new Handler(Looper.getMainLooper());this.mSetWebTitle = setWebTitle;mHandles = new ArrayList<>();//缓存相关的js通讯渠道mHandles.add(new CacheChannelImpl());//公共的js通讯渠道mHandles.add(new CommonChannelImpl(mWebView.getContext()));
}@JavascriptInterface
public void callHandler(String handleName, String jsonArgs, String callbackId) {if (mWebView == null) {return;}//设置web页面标题if (handleName.equals("setAppBarTitle")) {JSONObject jsonObject = JSON.parseObject(jsonArgs);String title = jsonObject.getString("title");if (null != mSetWebTitle) {mSetWebTitle.toSetWebTitle(title);} else {Log.d(TAG, "Interface SetWebTitle is null");}return;}//是否隐藏标题栏if (handleName.equals("hideTitleBar")) {JSONObject jsonObject = JSON.parseObject(jsonArgs);boolean isHide = jsonObject.getBoolean("isHide");if (null != mSetWebTitle) {mSetWebTitle.toHideTitleBar(isHide);} else {Log.d(TAG, "Interface SetWebTitle is null");}return;}boolean hasMethod = false;for (IJsCallHandle handle : mHandles) {if (handle.handle(handleName)) {if (handle instanceof CacheChannelImpl) {handle.run(mWebView, jsonArgs, callbackId, callBackIdStack);} else {handle.run(mWebView, jsonArgs);callBackIdStack.put(handleName, callbackId);}hasMethod = true;break;}}if (!hasMethod) {//未实现方法 handleNamemHandler.post(new Runnable() {@Overridepublic void run() {Gson gson = new GsonBuilder().disableHtmlEscaping() // 禁用 HTML 转义.create();HashMap<String, Object> mmap = new HashMap<>();mmap.put("result", "");mmap.put("code", "error");mmap.put("message", String.format("未实现方法%s", handleName));mmap.put("methodName", handleName);response = gson.toJson(mmap);String jsFunctionCall = "javascript:CallbackManager.invokeCallback('" + callbackId + "', '" + response + "')";mWebView.loadUrl(jsFunctionCall);callBackIdStack.remove(handleName);}});}}
}

CommonChannelImpl的实现示例:

public class CommonChannelImpl implements IJsCallHandle {
private Map<String, Boolean> methods = new HashMap<String, Boolean>();
private String mHandleName = "";
private Context mContext;public CommonChannelImpl(Context context) {this.mContext = context;//权限请求methods.put("requestPermission", false);//获取应用基本信息methods.put("getAppInfo", false);//web页面导航返回methods.put("NavigatorPop", false);//打开浏览器methods.put("openBrowser", false);//跳转页面methods.put("jumpPage", false);//打电话methods.put("callPhone", false);
}@Override
public boolean handle(String handleName) {if (methods.containsKey(handleName)) {mHandleName = handleName;methods.put(handleName, true);return true;}return false;
}@Override
public void run(StWebView webView, String jsonArgs) {long requestCode = 0;if (!TextUtils.isEmpty(jsonArgs)) {JSONObject jobj = JSON.parseObject(jsonArgs);if (jobj.containsKey("requestCode")) {requestCode = jobj.getLong("requestCode");}}switch (mHandleName) {case "requestPermission":EventMessage<Object> eventMessage1 = new EventMessage<>(0, requestCode, "module-permission", mHandleName, jsonArgs);EventBusUtil.sendEvent(eventMessage1);break;case "getAppInfo":EventMessage<Object> eventMessage = new EventMessage<>(0, requestCode, "component-phoneinfo", mHandleName, jsonArgs);EventBusUtil.sendEvent(eventMessage);break;case "NavigatorPop":Handler mainHandler = new Handler(Looper.getMainLooper());mainHandler.post(new Runnable() {@Overridepublic void run() {if (webView.canGoBack()) {webView.goBack();} else {if (mContext instanceof AppCompatActivity) {((AppCompatActivity) mContext).finish();}}}});break;case "openBrowser":JSONObject jsonObject = JSON.parseObject(jsonArgs);if (jsonObject != null) {String url = jsonObject.getString("url");if (!url.contains("http")) {url = "http://" + url;}Intent intent = new Intent(Intent.ACTION_VIEW);intent.setData(Uri.parse(url));mContext.startActivity(intent);}break;case "jumpPage":JSONObject jsonObject1 = JSON.parseObject(jsonArgs);String pageUrl = jsonObject1.getString("pageUrl");JSONObject params = jsonObject1.getJSONObject("params");Map<String, Object> map = new HashMap<>();for (String key : params.keySet()) {map.put(key, params.get(key));}ARouterHelper.navigateToFlutterPage(pageUrl, map);break;case "callPhone":JSONObject jsonObject2 = JSON.parseObject(jsonArgs);String number = jsonObject2.getString("number");Intent intent = new Intent(Intent.ACTION_DIAL);intent.setData(Uri.parse("tel:" + number));mContext.startActivity(intent);break;default:break;}}
}

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

RHCE——WEB服务器的部署及优化

URL组成 <scheme>://<user>:<password><host>:<port>/<path>:<params>?<query>#<frag> scheme 方案 访问服务器以获取资源时要使用哪种协议 user 用户 某些方案访问资源时需要的用户名 pass…

day03(单片机高级)RTOS

目录 RTOS(实时操作系统) 裸机开发模式 轮询方式 前后台&#xff08;中断方式&#xff09; 改进&#xff08;前后台&#xff08;中断&#xff09;&#xff09;定时器 裸机进一步优化 裸机的其他问题 RTOS的概念 什么是RTOS 为什么要使用 RTOS RTOS的应用场景 RTOS的…

基于SSM的毕业论文管理系统【附源码】

基于SSM的毕业论文管理系统&#xff08;源码L文说明文档&#xff09; 目录 4 系统设计 4.1 系统结构设计 4.2 系统顺序图设计 4.3 系统数据库设计 5 系统的实现 5.1 登录模块的实现 5.2 学生管理模块的实现 5.3 导师管理模块的实现 5.4 课题管理模块的实现 …

擎耀数字车灯CAN/LIN总线网络定向数据采集控制解决方案实施流程

2024年是数字车灯崛起的元年&#xff0c;随着车辆的智能化和网络化程度不断提高&#xff0c;车载网络系统&#xff08;如CAN总线&#xff09;成为连接各个电子控制单元&#xff08;ECU&#xff09;的重要纽带。车灯作为车辆重要的安全组件之一&#xff0c;其工作状态直接影响到…

【C++之STL】摸清 string 的模拟实现(上)

文章目录 1. 为什么要模拟实现&#xff1f;2. 基本框架搭建3. 构造函数3. 1 默认构造/from c_str3. 2 拷贝构造3. 2. 1 深浅拷贝 3. 3 fill3. 4 迭代器区间构造 4. 容量操作4. 1 size()和capacity()和empty()4. 2 clear()4. 3 resize()4. 4 reserve() 1. 为什么要模拟实现&…

视频直播5G CPE解决方案:ZX7981PG/ZX7981PMWIFI6网络覆盖

方案背景 视频直播蓬勃发展的当下&#xff0c;传统直播网络联网方式的局限性越来越明显。目前传统直播的局限性主要集中在以下几个方面&#xff1a; 传统直播间网络架构条件有限&#xff0c;可连接WIFI数量少&#xff0c;多终端同时直播难以维持&#xff1b;目前4G网络带宽有限…

input file结合vue3和vant实现上传图片效果,并显示上传进度百分比%

这里写自定义目录标题 采用的dom结构是input file&#xff0c;label事件绑定&#xff0c;一下为代码传入参数为uploadNum实现效果如图上传中&#xff0c;图片1上传成功&#xff0c;图片2 采用的dom结构是input file&#xff0c;label事件绑定&#xff0c;一下为代码 传入参数为…

SELECT 语句详解

开发准备 注:如果你是从上一节直接进入本节进行学习的,请先删除上一节建立的数据库mysql_shiyan,删除语句为DROP DATABASE mysql_shiyan;。在正式开始本实验内容之前,需要先下载相关数据库表,搭建好一个名为mysql_shiyan 的数据库(有三张表:department,employee,projec…

重力传感器算法概述!

一、核心技术 高精度重力测量技术&#xff1a; 无人机重力传感器的核心技术之一是能够高精度地测量重力加速度数据。这通常依赖于先进的传感器设计和制造工艺&#xff0c;以确保传感器具有高度的灵敏度和稳定性。 例如&#xff0c;中国船舶第七〇七研究所自主研发的低空重力…

炼码LintCode--数据库题库(级别:中等;数量:更新中~)--刷题笔记_03

目录 炼码LintCode--数据库题库&#xff08;级别&#xff1a;中等&#xff1b;数量&#xff1a;更新中~&#xff09;--刷题笔记_033617 更换连续两个人的座位&#xff08;case when&#xff09;题&#xff1a;sql&#xff1a;解释&#xff1a; 3615 数据中位数&#xff08;窗…

【stm入门学习SPI_铁头山羊系列教程】

stm入门学习SPI_铁头山羊教程 1.SPI总线1.电路结构与通信协议2.SPI的特点&#xff1a;3. 极性 相位4. 4中时钟模式5. 比特位的传输模式6.数据宽度 2. SPI引脚IO引脚初始化 1.SPI总线 1.电路结构与通信协议 主机向从机NSS引脚发送低电压&#xff0c;选中该从机。 主机通过向MOS…

RK3568平台开发系列讲解(platform虚拟总线驱动篇)实验:点亮一个LED

🚀返回专栏总目录 文章目录 一、设备树二、平台驱动三、应用沉淀、分享、成长,让自己和他人都能有所收获!😄 📢xxx 程序编写的主要内容为添加 LED 灯的设备树节点、在驱动程序中使用 of 函数获取设备节点中的属性,编写测试应用程序。 • 首先向设备树添加 LED 设备节点…

Spring Boot 与腾讯云 MySQL 监听 Binlog 数据变化,并使用 UI 展示页面效果

引言 在现代的分布式系统和微服务架构中&#xff0c;数据同步和变更监控是保证系统一致性和实时性的核心问题之一。MySQL 数据库的 binlog&#xff08;二进制日志&#xff09;功能能够记录所有对数据库的修改操作&#xff0c;如插入&#xff08;INSERT&#xff09;、更新&…

菜鸟驿站二维码/一维码 取件识别功能

特别注意需要引入 库文 ZXing 可跳转&#xff1a; 记录【WinForm】C#学习使用ZXing.Net生成条码过程_c# zxing-CSDN博客 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using static System.Net.…

PlantUML——时序图

PlantUML时序图 背景 时序图&#xff08;Sequence Diagram&#xff09;&#xff0c;又名序列图、循序图&#xff0c;是一种UML交互图&#xff0c;用于描述对象之间发送消息的时间顺序&#xff0c;显示多个对象之间的动态协作。时序图的使用场景非常广泛&#xff0c;几乎各行各…

算法——链表相交(leetcode23)

链表相交这题就是找出两个相交链表相交的节点并返回 如上图假设上方第一个节点是链表A的头结点下方第一个节点是链表B的头结点 解法有以下两种 方法一(移动长链表指针后同步移动两个链表的指针直至相等) 也就是先遍历链表A和链表B的长度接着得到链表A和B长度的差值然后领长链…

STM32单片机锁死

自己画了一块stm32f407板子&#xff0c;外部晶振用了25MHz&#xff0c;烧写了8MHz的程序&#xff0c;第一次烧写成功&#xff0c;第二次开始识别不到芯片&#xff0c;第一次烧写成功由于外部晶振为25Hz&#xff0c;芯片内频率计算器却是按照8MHz写的&#xff0c;所以得出最后的…

Windows文件资源管理器增强工具

引言&#xff1a; 资源管理器在我们使用电脑时是经常用到的&#xff0c;各种文件资源等的分类整理都离不开它。但是Windows Explorer确实不好用&#xff0c;不智能&#xff0c;不符合人体工程学。特别是在一些场合&#xff0c;在打开的一堆文件夹里&#xff0c;想从中找到自己要…

聚类中3个解空间的描述

深度学习中做分类任务时&#xff0c;我们常常根据最后的全连接层得到一组向量A&#xff08;比如&#xff1a;[0.9, 0.7, 0.2]&#xff09;&#xff0c;这组向量经过归一化得到向量B(比如&#xff1a;[0.5&#xff0c; 0.3&#xff0c; 0.2])&#xff0c;再根据B向量采用概率最大…

Empirical analysis of hardware-assisted GPU virtualization

​ 年份&#xff1a;2019 作者&#xff1a;Anshuj Garg 会议&#xff1a;ESCI 出版商&#xff1a;IEEE 摘要 本篇文章对vGPU虚拟化的性能开销、调度算法的影响、同构与异构工作负载的干扰效应&#xff0c;以及PCI直通与vGPU的性能差异进行了研究。结果表明&#xff0c;vGP…