当前位置: 首页 > news >正文

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

  1. 使用 WebView.addJavascriptInterface(Object, String); 映射对象和方法到 js 中一个变量, 例如:

    public static class JsUtils {@JavascriptInterfacepublic void call(String funcName, String jsonMsg) { // 具体多少个参数对上 js 即可...}
    }WebViewIns.addJavascriptInterface(new JsUtils(), "gJavaObj");
    
  2. 直接使用 gJavaObj 对象即可

    gJavaObj.call(funcName, jsonMsg);
    

加载 js 代码

  • 使用 WebView.loadUrl

    String 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&#xff1a;你要的WebView与 JS 交互方式 都在这里了…...

22.WEB渗透测试-BurpSuite(一)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;21.WEB渗透测试-HTTP协议&#xff08;下&#xff09;-CSDN博客 工具的使用需要先搭建靶场…...

前端性能优化:防抖与节流

一、防抖和节流主要是干什么的 防抖和节流主要用于控制函数执行的频率&#xff0c;通过限制函数的触发次数&#xff0c;避免函数被过度调用而引发的性能问题或产生不必要的副作用。 二、防抖 防抖是什么: 1、对于在事件被触发 n 秒后再执行的回调 --> 延迟执行 2、如果…...

Copilot 编程助手的介绍及使用

介绍 Copilot 是2021年由 GitHub 与 OpenAI 合作研发的一款编程助手&#xff0c;同时也是全球首款使用OpenAI Codex模型&#xff08;GPT-3后代&#xff09;打造的大规模生成式AI开发工具。 Copilot 底层模型目前经过了数十亿行公开代码的训练&#xff0c;与大多数代码辅助工具…...

数据库专题(oracle基础和进阶)

前言 本专题主要记录自己最近学的数据库&#xff0c;有兴趣一起补习的可以一起看看&#xff0c;有补充和不足之处请多多指出。希望专题可以给自己还有读者带去一点点提高。 数据库基本概念 本模块有参考&#xff1a;数据库基本概念-CSDN博客 数据库管理系统是一个由互相关联的…...

web蓝桥杯2022省赛真题:水果拼盘

代码及注释&#xff1a; /* TODO&#xff1a;待补充代码 */ #pond {display: flex; //flex布局flex-direction: column; //主轴方向从上到下flex-wrap: wrap; //子元素换行 } 知识点&#xff1a; flex弹性布局 父元素&#xff1a;diasplay: flex; flex-d…...

Web核心

目录 Web核心HTTP概念&#xff1a;协议特点&#xff1a;请求数据格式响应数据格式 Tomcat简介基本使用配置部署项目IDEA中创建 Maven Web 项目 IDEA使用Tomcat Servlet简介快速入门执行流程生命周期体系结构Servlet urlPattern配置一个Servlet&#xff0c;可以配置多个 urlPatt…...

iOS应用审核问题解决方案及优化方法 ✨

摘要 本文将针对iOS应用提交审核时可能遇到的问题&#xff0c;如“你必须在Xcode中添加com.apple.developer.game-center密钥”&#xff0c;以及突然间提交送审报错情况进行探讨。通过大量查询资料和尝试&#xff0c;结合案例分析&#xff0c;提供了解决方案和优化方法&#xf…...

java post、get请求第三方https接口

java post、get请求第三方https接口 前段时间做项目新加功能由于要对接其它系统&#xff0c;请求系统接口传输数据。写完后发现我写的这个方法和网上现有的例子有点不太一样&#xff0c;可能是因为我做的项目是政务网的原因&#xff0c;但我想正常的即便是互联网的系统请求方式…...

【C语言】鸡兔同笼,鸡和兔共 100 只,共 284 只脚,求鸡和兔的个数。

鸡兔同笼&#xff0c;鸡和兔共 100 只&#xff0c;共 284 只脚&#xff0c;求鸡和兔的个数。 int main() {for (int i 0; ; i){if (2 * i 4 * (100 - i) 284){printf("鸡的数量&#xff1a;%d,兔子的数量&#xff1a;%d", i, 100 - i);break;} } }这里直接算出题…...

沪漂8年回郑州三年如何走上创业之路

大家好&#xff0c;我是大牛&#xff0c;目前人在郑州。 现在标签是&#xff1a; 创业者&#x1f697;&#x1f438; (注册有自己的公司&#xff0c;主要是为了自己的产品和接外包项目)独立开发者&#x1f468;&#x1f3fb;&#x1f4bb; (有自己的小项目)数字游民&…...

MySQL数据库—事务与存储类型

一、事务&#xff1a; 1.事务的概念&#xff1a; 事务是一种机制、一个操作序列&#xff0c;包含了一组数据库操作命令&#xff0c;并且把所有的命令作为一个整体一起向系统提交或撤销操作请求&#xff0c;即这组数据库命令要么都执行&#xff0c;要么都不执行。事务是一个不…...

蓝桥杯刷题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 学生信息管理系统设计和实现以及文档报告 博主介绍&#xff1a;多年java开发经验&#xff0c;专注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 属于轻量级开源的嵌入式关系型数据库&#xff0c;但它支持 ACID(Atomicity,Consistency,Isolation,Durability) 事务。 SQLite Download Page: https://www.sqlite.org/download.html 第一步&#xff1a;在 php.ini 中开启 extensionsqlite3 第二步&#xff1a;连接数…...

【代驾+顺风车+货运】全开源双端APP代驾+顺风车+货运代驾小程序源码

内容目录 一、详细介绍二、效果展示1.部分代码2.效果图展示 一、详细介绍 系统是基于Thinkphpuniapp开发的&#xff0c;全开源未加密&#xff0c;这套源码可以拿回去自己做二开 后台用户端司机端 功能详情介绍&#xff1a; 车主实名认证&#xff0c;驾驶证认证&#xff0c;车…...

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&#xff1a;使用正则表达式搜索文本&#xff0c;将匹配的行打印出来&#xff08;匹配到的标红&#xff09; 命令格式&#xff1a;grep [option] pattern file <1> 命令参数 -A<显示行数>&#xff1a;除了显示符合范本样式的那一列之外&#xff0c;并…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

C# 类和继承(抽象类)

抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

【git】把本地更改提交远程新分支feature_g

创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...

SpringCloudGateway 自定义局部过滤器

场景&#xff1a; 将所有请求转化为同一路径请求&#xff08;方便穿网配置&#xff09;在请求头内标识原来路径&#xff0c;然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...

dify打造数据可视化图表

一、概述 在日常工作和学习中&#xff0c;我们经常需要和数据打交道。无论是分析报告、项目展示&#xff0c;还是简单的数据洞察&#xff0c;一个清晰直观的图表&#xff0c;往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server&#xff0c;由蚂蚁集团 AntV 团队…...

return this;返回的是谁

一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请&#xff0c;不同级别的经理有不同的审批权限&#xff1a; // 抽象处理者&#xff1a;审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...

LLMs 系列实操科普(1)

写在前面&#xff1a; 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容&#xff0c;原视频时长 ~130 分钟&#xff0c;以实操演示主流的一些 LLMs 的使用&#xff0c;由于涉及到实操&#xff0c;实际上并不适合以文字整理&#xff0c;但还是决定尽量整理一份笔…...

02.运算符

目录 什么是运算符 算术运算符 1.基本四则运算符 2.增量运算符 3.自增/自减运算符 关系运算符 逻辑运算符 &&&#xff1a;逻辑与 ||&#xff1a;逻辑或 &#xff01;&#xff1a;逻辑非 短路求值 位运算符 按位与&&#xff1a; 按位或 | 按位取反~ …...

MySQL体系架构解析(三):MySQL目录与启动配置全解析

MySQL中的目录和文件 bin目录 在 MySQL 的安装目录下有一个特别重要的 bin 目录&#xff0c;这个目录下存放着许多可执行文件。与其他系统的可执行文件类似&#xff0c;这些可执行文件都是与服务器和客户端程序相关的。 启动MySQL服务器程序 在 UNIX 系统中&#xff0c;用…...

Qwen系列之Qwen3解读:最强开源模型的细节拆解

文章目录 1.1分钟快览2.模型架构2.1.Dense模型2.2.MoE模型 3.预训练阶段3.1.数据3.2.训练3.3.评估 4.后训练阶段S1: 长链思维冷启动S2: 推理强化学习S3: 思考模式融合S4: 通用强化学习 5.全家桶中的小模型训练评估评估数据集评估细节评估效果弱智评估和民间Arena 分析展望 如果…...