creator-webview与Android交互
title: creator-webview与Android交互
categories: Cocos2dx
tags: [cocos2dx, creator, webview, 交互]
date: 2024-03-23 13:17:20
comments: false
mathjax: true
toc: true
creator-webview与Android交互
前篇
- Android:你要的WebView与 JS 交互方式 都在这里了 - https://cloud.tencent.com/developer/article/1394361
java 调用 js
-
使用
WebView.evaluateJavascript执行 js 代码String callStr = String.format("window['java2js'](`%s`, `%s`)", funcName, jsonMsg); WebViewIns.evaluateJavascript(callStr, null);如果要透传数据结构或 json, 最好用 base64 加密一下, 然后在 js 中再解密出来, 以保证这些数据不会破会 js 代码的结构
一般跨语言的交互中, 我都会使用 base64 去加密数据使之变成正常的字符串
js 调用 java
-
使用
WebView.addJavascriptInterface(Object, String);映射对象和方法到 js 中一个变量, 例如:public static class JsUtils {@JavascriptInterfacepublic void call(String funcName, String jsonMsg) { // 具体多少个参数对上 js 即可...} }WebViewIns.addJavascriptInterface(new JsUtils(), "gJavaObj"); -
直接使用 gJavaObj 对象即可
gJavaObj.call(funcName, jsonMsg);
加载 js 代码
-
使用
WebView.loadUrlString bdg = "js 代码"; WebView.loadUrl("javascript:" + bdg); -
js 代码书写有严格的要求, 例如:
// 1. 一定要以这种 执行方法 的方式初始化 // 2. 语句结尾要加 ;, 不然报错 Invalid left-hand side expression in postfix operation // 3. 注释必须清楚掉 (function() {window.cm = {};window.java2js = function(f, m) {var oldCb = window.cm[f];if (oldCb) oldCb(window.atob(m));window.cm[f] = null;};window.WebViewJavascriptBridge = {init: function() { },registerHandler: function() { },callHandler: function(f, m, c) {window.cm[f] = c;gJavaObj.call(f, m);},};document.dispatchEvent(new Event("WebViewJavascriptBridgeReady")); })()-
可以使用 uglyjs 把代码压缩成一行
String bdg = "window.cm={},window.java2js=function(f,m){var oldCb=window.cm[f];oldCb&&oldCb(window.atob(m)),window.cm[f]=null},window.WebViewJavascriptBridge={init:function(){},registerHandler:function(){},callHandler:function(f,m,c){window.cm[f]=c,gJavaObj.call(f,m)}},document.dispatchEvent(new Event(\"WebViewJavascriptBridgeReady\"));"
-
完整的 java, html 代码
java
-
代码
import android.annotation.SuppressLint; import android.app.Activity; import android.app.AlertDialog; import android.net.http.SslError; import android.util.Base64; import android.view.ViewGroup; import android.webkit.JavascriptInterface; import android.webkit.SslErrorHandler; import android.webkit.WebResourceRequest; import android.webkit.WebResourceResponse; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.LinearLayout; import android.widget.RelativeLayout;import java.io.ByteArrayInputStream; import java.nio.charset.StandardCharsets; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.function.Consumer;public class WebviewHelper {public static WebviewHelper instance = null;private RelativeLayout mLayoutRoot;private WebView mWebview;private static Map<String, BridgeHandler> mJsCb = new HashMap<>();public static void showWebview(final Activity activity, final String url, final ActivityMgr.CodeRunnable task) {closeWebview(activity, () -> {instance = new WebviewHelper();instance.show(activity, url);if (task != null) {task.run(ActivityMgr.Ok, "");}});}public static void closeWebview(final Activity activity, final Runnable task) {activity.runOnUiThread(() -> {if (instance != null) {instance.destroy();}if (task != null) {task.run();}});}public static boolean goBack() {ActivityMgr.Act.moveTaskToBack(true);return false;}@SuppressLint("SetJavaScriptEnabled")public void show(Activity activity, final String url) {final RelativeLayout rLayout = new RelativeLayout(activity);mLayoutRoot = rLayout;RelativeLayout.LayoutParams rParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);LinearLayout.LayoutParams lParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);final WebView wv = new WebView(activity);wv.setWebViewClient(new WebviewClientHelper());mWebview = wv;wv.setLayoutParams(lParams);rLayout.addView(wv);activity.addContentView(rLayout, rParams);mWebview.addJavascriptInterface(new JsUtils(), "gJavaObj");//AndroidtoJS类对象映射到js的test对象wv.loadUrl(url);// 设置webviewWebSettings settings = wv.getSettings();settings.setJavaScriptCanOpenWindowsAutomatically(true);settings.setJavaScriptEnabled(true);settings.setDomStorageEnabled(true);settings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); // 有缓存就使用缓存settings.setSupportZoom(false);settings.setBuiltInZoomControls(true);}public static void regHandler(String name, BridgeHandler bh) {mJsCb.put(name, bh);}private void destroy() {if (mWebview != null) {mWebview.destroy();mWebview = null;}if (mLayoutRoot != null) {ViewGroup vg = (ViewGroup) mLayoutRoot.getParent();vg.removeView(mLayoutRoot);mLayoutRoot = null;}instance = null;}public interface BridgeHandler {void handler(String var1, Consumer<String> var2);}public static class JsUtils {@JavascriptInterfacepublic void call(String funcName, String jsonMsg) {BridgeHandler bh = mJsCb.get(funcName);if (bh == null) {ActivityMgr.E("no func: %s", funcName);return;}bh.handler(jsonMsg, (result) -> {try {// 交互是需要 base64 处理一下result = Base64.encodeToString((result != null ? result : "").getBytes(StandardCharsets.UTF_8), Base64.DEFAULT);String callStr = String.format("window['java2js'](`%s`, `%s`)", funcName, result);instance.mWebview.evaluateJavascript(callStr, null);} catch (Exception e) {e.printStackTrace();}});}}public static class WebviewClientHelper extends WebViewClient {public boolean isLoadBdg = false;@Overridepublic void onPageFinished(WebView view, String url) {if (!isLoadBdg) {String bdg = "window.cm={},window.java2js=function(f,m){var oldCb=window.cm[f];oldCb&&oldCb(window.atob(m)),window.cm[f]=null},window.WebViewJavascriptBridge={init:function(){},registerHandler:function(){},callHandler:function(f,m,c){window.cm[f]=c,gJavaObj.call(f,m)}},document.dispatchEvent(new Event(\"WebViewJavascriptBridgeReady\"));";view.loadUrl("javascript:" + bdg);isLoadBdg = true;}super.onPageFinished(view, url);}} }
html
-
代码
<!DOCTYPE html> <html> <head><script>document.addEventListener('WebViewJavascriptBridgeReady', function() {console.log("--- WebViewJavascriptBridgeReady");},false);function js2java() {console.log("--- js2java");// gJavaObj.hello("Hello Terry")var funcName = "StartInfo"var jsonMsg = "World 002"window.WebViewJavascriptBridge.callHandler(funcName, jsonMsg, function(responseData) {console.log("--- responseData:", responseData);})}console.log("--- web loaded");</script><title>Test Webview</title> </head><body><div id="mydiv"><br /><br /><button onclick="js2java()"> js2java </button></div> </body> </html>
相关文章:
creator-webview与Android交互
title: creator-webview与Android交互 categories: Cocos2dx tags: [cocos2dx, creator, webview, 交互] date: 2024-03-23 13:17:20 comments: false mathjax: true toc: true creator-webview与Android交互 前篇 Android:你要的WebView与 JS 交互方式 都在这里了…...
22.WEB渗透测试-BurpSuite(一)
免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 内容参考于: 易锦网校会员专享课 上一个内容:21.WEB渗透测试-HTTP协议(下)-CSDN博客 工具的使用需要先搭建靶场…...
前端性能优化:防抖与节流
一、防抖和节流主要是干什么的 防抖和节流主要用于控制函数执行的频率,通过限制函数的触发次数,避免函数被过度调用而引发的性能问题或产生不必要的副作用。 二、防抖 防抖是什么: 1、对于在事件被触发 n 秒后再执行的回调 --> 延迟执行 2、如果…...
Copilot 编程助手的介绍及使用
介绍 Copilot 是2021年由 GitHub 与 OpenAI 合作研发的一款编程助手,同时也是全球首款使用OpenAI Codex模型(GPT-3后代)打造的大规模生成式AI开发工具。 Copilot 底层模型目前经过了数十亿行公开代码的训练,与大多数代码辅助工具…...
数据库专题(oracle基础和进阶)
前言 本专题主要记录自己最近学的数据库,有兴趣一起补习的可以一起看看,有补充和不足之处请多多指出。希望专题可以给自己还有读者带去一点点提高。 数据库基本概念 本模块有参考:数据库基本概念-CSDN博客 数据库管理系统是一个由互相关联的…...
web蓝桥杯2022省赛真题:水果拼盘
代码及注释: /* TODO:待补充代码 */ #pond {display: flex; //flex布局flex-direction: column; //主轴方向从上到下flex-wrap: wrap; //子元素换行 } 知识点: flex弹性布局 父元素:diasplay: flex; flex-d…...
Web核心
目录 Web核心HTTP概念:协议特点:请求数据格式响应数据格式 Tomcat简介基本使用配置部署项目IDEA中创建 Maven Web 项目 IDEA使用Tomcat Servlet简介快速入门执行流程生命周期体系结构Servlet urlPattern配置一个Servlet,可以配置多个 urlPatt…...
iOS应用审核问题解决方案及优化方法 ✨
摘要 本文将针对iOS应用提交审核时可能遇到的问题,如“你必须在Xcode中添加com.apple.developer.game-center密钥”,以及突然间提交送审报错情况进行探讨。通过大量查询资料和尝试,结合案例分析,提供了解决方案和优化方法…...
java post、get请求第三方https接口
java post、get请求第三方https接口 前段时间做项目新加功能由于要对接其它系统,请求系统接口传输数据。写完后发现我写的这个方法和网上现有的例子有点不太一样,可能是因为我做的项目是政务网的原因,但我想正常的即便是互联网的系统请求方式…...
【C语言】鸡兔同笼,鸡和兔共 100 只,共 284 只脚,求鸡和兔的个数。
鸡兔同笼,鸡和兔共 100 只,共 284 只脚,求鸡和兔的个数。 int main() {for (int i 0; ; i){if (2 * i 4 * (100 - i) 284){printf("鸡的数量:%d,兔子的数量:%d", i, 100 - i);break;} } }这里直接算出题…...
沪漂8年回郑州三年如何走上创业之路
大家好,我是大牛,目前人在郑州。 现在标签是: 创业者🚗🐸 (注册有自己的公司,主要是为了自己的产品和接外包项目)独立开发者👨🏻💻 (有自己的小项目)数字游民&…...
MySQL数据库—事务与存储类型
一、事务: 1.事务的概念: 事务是一种机制、一个操作序列,包含了一组数据库操作命令,并且把所有的命令作为一个整体一起向系统提交或撤销操作请求,即这组数据库命令要么都执行,要么都不执行。事务是一个不…...
蓝桥杯刷题8
1. 世纪末的星期 import java.util.Calendar; public class Main {public static void main(String[] args) {Calendar calendar Calendar.getInstance();for(int year 1999;year<100000;year100){calendar.set(Calendar.YEAR,year);calendar.set(Calendar.MONTH,11);cale…...
Java中的String字符串练习
目录 Java中的String字符串练习 01-用户登录 02-遍历字符串并统计字符个数 03-字符串拼接 04-字符串反转 注意点 05-金额转化(简单) 代码解释: 06-手机号屏蔽 07-身份证号码查看 易错点: 08-敏感词替换 01-用户登录 package com.xiaonan.exercise06;import java.u…...
基于JavaWeb SSM mybatis 学生信息管理系统设计和实现以及文档报告
基于JavaWeb SSM mybatis 学生信息管理系统设计和实现以及文档报告 博主介绍:多年java开发经验,专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 …...
二进制源码部署mysql8.0.35
二进制部署mysql8.0.35 创建mysql用户 [rootzyq ~]#: useradd -r -s /sbin/nologin -M mysql [rootzyq ~]#: id mysql uid990(mysql) gid990(mysql) groups990(mysql)上传mysql文件 [rootzyq ~]#: ls anaconda-ks.cfg mysql-8.0.35-linux-glibc2.28-x86_64.tar.xz解压 [roo…...
PHP 读取嵌入式数据 SQLite3
SQLite3 属于轻量级开源的嵌入式关系型数据库,但它支持 ACID(Atomicity,Consistency,Isolation,Durability) 事务。 SQLite Download Page: https://www.sqlite.org/download.html 第一步:在 php.ini 中开启 extensionsqlite3 第二步:连接数…...
【代驾+顺风车+货运】全开源双端APP代驾+顺风车+货运代驾小程序源码
内容目录 一、详细介绍二、效果展示1.部分代码2.效果图展示 一、详细介绍 系统是基于Thinkphpuniapp开发的,全开源未加密,这套源码可以拿回去自己做二开 后台用户端司机端 功能详情介绍: 车主实名认证,驾驶证认证,车…...
C++语言学习(三)—— 文件操作
目录 一、文件操作 1.1 打开文件 1.2 关闭文件 1.3 读取文件 1.4 写入文件 1.5 文件指针 1.6 文件状态 1.7 其他文件操作 二、文件操作函数 2.1 打开文件函数 2.2 关闭文件函数 2.3 写入文件函数 2.4 读取文件函数 2.5 读取一行函数 2.6 获取文件大小函数 2.7 …...
linux文本三剑客 --- grep、sed、awk
1、grep grep:使用正则表达式搜索文本,将匹配的行打印出来(匹配到的标红) 命令格式:grep [option] pattern file <1> 命令参数 -A<显示行数>:除了显示符合范本样式的那一列之外,并…...
05-系统技术架构师必备——软件工程方法与UML建模体系
关键词:UML建模、Scrum、敏捷开发、软件测试、白盒测试、McCabe复杂度、瀑布模型、RUPUML 软件工程 敏捷开发 软件测试 Scrum RUP 系统架构 建模系统技术架构师必备——软件工程方法与UML建模体系 摘要 UML建模和软件工程方法是系统技术架构师与开发团队沟通的"…...
一个简单的MCP代码示例
MCP项目测试示例from fastmcp import FastMCP# 1. 创建 MCP 服务器实例 mcp FastMCP("MyFirstServer")# 2. 定义一个工具(Tool):AI 可以调用的函数 mcp.tool() def add(a: int, b: int) -> int:"""将两个数字相…...
Python自动化办公:批量处理Word文档的实用技巧
Python自动化办公:批量处理Word文档的实用技巧 在日常办公中,处理大量Word文档是常见任务,比如批量修改格式、提取内容或生成报告。手动操作不仅耗时,还容易出错。本文将介绍如何使用Python自动化处理Word文档,通过代码…...
跨平台macOS组件获取:系统部署专家的高效解决方案
跨平台macOS组件获取:系统部署专家的高效解决方案 【免费下载链接】gibMacOS Py2/py3 script that can download macOS components direct from Apple 项目地址: https://gitcode.com/gh_mirrors/gi/gibMacOS 在macOS系统部署和维护的复杂环境中,…...
基于DSP与SC1083 ADC的光纤远程数据采集系统设计实战
1. 项目概述:当DSP遇上高速光缆,如何构建一个“快、准、稳”的远程数据采集系统在工业自动化、电力监测、超声无损检测这些领域,我们经常需要面对一个头疼的问题:如何把现场传感器采集到的大量、高速、有时甚至是微弱的模拟信号&a…...
如何构建现代自托管音乐播放器:音乐爱好者的完整使用指南
如何构建现代自托管音乐播放器:音乐爱好者的完整使用指南 【免费下载链接】feishin A modern self-hosted music player. 项目地址: https://gitcode.com/gh_mirrors/fe/feishin 在数字音乐时代,音乐爱好者面临着数据隐私、平台依赖和个性化体验的…...
工厂MES数据自动采集怎样用AI完成?资深架构师的非侵入式集成落地指南
摘要: 我是架构师老王。在2026年工业数字化转型的深水区,工厂MES数据自动采集已不再是简单的“连线接口”,而是演变为一场关于“感知、决策与执行”的架构革命。面对老旧系统API缺失、烟囱式架构林立以及信创环境下严苛的安全合规要求&#x…...
混合精度递归Cholesky分解:算法优化与硬件加速实践
1. 混合精度递归Cholesky分解的技术背景在科学计算领域,对称正定(SPD)线性系统的求解是一个基础而关键的问题。这类问题广泛存在于计算流体动力学、气候建模、金融风险分析等实际应用中。以气候建模为例,全球大气环流模型需要求解的线性系统矩阵规模可达…...
洛雪音乐音源完全指南:如何免费获取全网高品质音乐资源
洛雪音乐音源完全指南:如何免费获取全网高品质音乐资源 【免费下载链接】lxmusic- lxmusic(洛雪音乐)全网最新最全音源 项目地址: https://gitcode.com/gh_mirrors/lx/lxmusic- 作为音乐爱好者,你是否厌倦了在不同音乐平台间来回切换只为找到一首…...
