当前位置: 首页 > 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>
    

相关文章:

  • Unity:2D
  • 读算法的陷阱:超级平台、算法垄断与场景欺骗笔记19_前方的路
  • leetcode最大连续1的个数(简单)
  • docker 容器与本地主机间文件/文件夹的传输
  • 如何用VSCode和Clangd与Clang-Format插件高效阅读Linux内核源码及写驱动
  • python与excel第一节
  • 【ORB-SLAM3】在 Ubuntu20.04 上编译 ORM-SLAM3 并使用 D435i 运行测试
  • 海康威视的观澜大模型技术
  • C语言内存函数(1)【memcpy函数的使用与模拟实现】【memmove函数的使用和模拟实现】
  • Fabric Measurement
  • 并发编程之Java 对象头的详细解析
  • 3个Tips,用“AI”开启新生活
  • 使用Python抓取抖音直播间数据的简易指南【第152篇—抓取数据】
  • 使用 PyOpenGL 进行 2D 图形渲染总结
  • 康奋威科技邀您到场参观2024长三角快递物流展
  • 【译】React性能工程(下) -- 深入研究React性能调试
  • Android开发 - 掌握ConstraintLayout(四)创建基本约束
  • bootstrap创建登录注册页面
  • egg(89)--egg之redis的发布和订阅
  • Flannel解读
  • jdbc就是这么简单
  • JS题目及答案整理
  • leetcode讲解--894. All Possible Full Binary Trees
  • MaxCompute访问TableStore(OTS) 数据
  • Theano - 导数
  • Vim Clutch | 面向脚踏板编程……
  • Vue ES6 Jade Scss Webpack Gulp
  • WePY 在小程序性能调优上做出的探究
  • 搭建gitbook 和 访问权限认证
  • 大型网站性能监测、分析与优化常见问题QA
  • 飞驰在Mesos的涡轮引擎上
  • 看域名解析域名安全对SEO的影响
  • 离散点最小(凸)包围边界查找
  • 前端面试之CSS3新特性
  • 深入浏览器事件循环的本质
  • 什么软件可以提取视频中的音频制作成手机铃声
  • Play Store发现SimBad恶意软件,1.5亿Android用户成受害者 ...
  • Semaphore
  • 积累各种好的链接
  • # 手柄编程_北通阿修罗3动手评:一款兼具功能、操控性的电竞手柄
  • #etcd#安装时出错
  • #gStore-weekly | gStore最新版本1.0之三角形计数函数的使用
  • #include到底该写在哪
  • #宝哥教你#查看jquery绑定的事件函数
  • (day 12)JavaScript学习笔记(数组3)
  • (html转换)StringEscapeUtils类的转义与反转义方法
  • (ZT)北大教授朱青生给学生的一封信:大学,更是一个科学的保证
  • (附源码)springboot炼糖厂地磅全自动控制系统 毕业设计 341357
  • (力扣记录)1448. 统计二叉树中好节点的数目
  • (转)Linux整合apache和tomcat构建Web服务器
  • (转)程序员技术练级攻略
  • *setTimeout实现text输入在用户停顿时才调用事件!*
  • ./indexer: error while loading shared libraries: libmysqlclient.so.18: cannot open shared object fil
  • .bat批处理(二):%0 %1——给批处理脚本传递参数
  • .helper勒索病毒的最新威胁:如何恢复您的数据?