当前位置: 首页 > 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;并…...

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...

Linux 文件类型,目录与路径,文件与目录管理

文件类型 后面的字符表示文件类型标志 普通文件&#xff1a;-&#xff08;纯文本文件&#xff0c;二进制文件&#xff0c;数据格式文件&#xff09; 如文本文件、图片、程序文件等。 目录文件&#xff1a;d&#xff08;directory&#xff09; 用来存放其他文件或子目录。 设备…...

如何在看板中体现优先级变化

在看板中有效体现优先级变化的关键措施包括&#xff1a;采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中&#xff0c;设置任务排序规则尤其重要&#xff0c;因为它让看板视觉上直观地体…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题&#xff08;可多选&#xff09; 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘&#xff1a;专注于发现数据中…...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

srs linux

下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935&#xff0c;SRS管理页面端口是8080&#xff0c;可…...

【VLNs篇】07:NavRL—在动态环境中学习安全飞行

项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战&#xff0c;克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...

在树莓派上添加音频输入设备的几种方法

在树莓派上添加音频输入设备可以通过以下步骤完成&#xff0c;具体方法取决于设备类型&#xff08;如USB麦克风、3.5mm接口麦克风或HDMI音频输入&#xff09;。以下是详细指南&#xff1a; 1. 连接音频输入设备 USB麦克风/声卡&#xff1a;直接插入树莓派的USB接口。3.5mm麦克…...

算法打卡第18天

从中序与后序遍历序列构造二叉树 (力扣106题) 给定两个整数数组 inorder 和 postorder &#xff0c;其中 inorder 是二叉树的中序遍历&#xff0c; postorder 是同一棵树的后序遍历&#xff0c;请你构造并返回这颗 二叉树 。 示例 1: 输入&#xff1a;inorder [9,3,15,20,7…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现指南针功能

指南针功能是许多位置服务应用的基础功能之一。下面我将详细介绍如何在HarmonyOS 5中使用DevEco Studio实现指南针功能。 1. 开发环境准备 确保已安装DevEco Studio 3.1或更高版本确保项目使用的是HarmonyOS 5.0 SDK在项目的module.json5中配置必要的权限 2. 权限配置 在mo…...