使用JS代理 实现大对象的功能拆解

news2025/1/16 15:51:28

序言

在Android开发中,可以通过webView的addJavascriptInterface方法注入一个对象到网页中。但是随着开发的需求越来越多。这个对象身上的方法也越来越多。这个对象对应的java类,体积越来越大,不利于维护。为了在不影响之前代码的基础上。把之前的方法调用,比如 api1.methodA(paramB) 的形式通过js中的代理功能转化为 api2.callProxy(‘methodA’,paramB) 的形式。
这样在api2对应的java类中就可以使用反射或者其他方法,动态的查找需要调用的本地方法。就可以将原来api1对应的类拆解,利于后期维护.

代码

对应的js代码

(function () {
  
    try {
        const originalObject = {

        };

        const handler = {
            get(target, property, receiver) {
                // 这里可以拦截所有对属性的访问,包括方法  
                console.log(`Accessing property: ${property}`);

                // 检查属性是否存在  
                if (!(property in target)) {
                    // 如果方法不存在,创造它,保存起来   
                    target[property] = function (param) {
                        if (typeof (window['trsAppJsBridgeProxy']) == 'object') {
                            window['trsAppJsBridgeProxy'].callProxy(property, param);
                        }
                        console.log("调用方法,名称为" + property + " 参数为:" + param);
                    }

                }
                return target[property];
            }
        };

        // 使用Proxy创建一个新对象,它将对原始对象的所有操作委托给handler  
        const proxyObject = new Proxy(originalObject, handler);

        window.trsAppJSBridge = proxyObject;

        console.log("注入trsAppJSBridge成功");
        return true;
    } catch (e) {
        console.log("注入trsAppJSBridge失败,error=" + e);
        return false;
    }
})()

对应的java代码

package com.trs.nmip.common.ui.base.web;

import android.util.Log;
import android.webkit.JavascriptInterface;

import com.tencent.smtt.sdk.WebView;

/**
 * <pre>
 * Created by zhuguohui
 * Date: 2024/4/24
 * Time: 14:15
 * Desc:
 * </pre>
 */
public class TrsJsProxy {
    private static final String injectJS = "(function () {\n" +
            "  \n" +
            "    try {\n" +
            "        const originalObject = {\n" +
            "\n" +
            "        };\n" +
            "\n" +
            "        const handler = {\n" +
            "            get(target, property, receiver) {\n" +
            "                // 这里可以拦截所有对属性的访问,包括方法  \n" +
            "                console.log(`Accessing property: ${property}`);\n" +
            "\n" +
            "                // 检查属性是否存在  \n" +
            "                if (!(property in target)) {\n" +
            "                    // 如果方法不存在,创造它,保存起来   \n" +
            "                    target[property] = function (param) {\n" +
            "                        if (typeof (window['trsAppJsBridgeProxy']) == 'object') {\n" +
            "                            window['trsAppJsBridgeProxy'].callProxy(property, param);\n" +
            "                        }\n" +
            "                        console.log(\"调用方法,名称为\" + property + \" 参数为:\" + param);\n" +
            "                    }\n" +
            "\n" +
            "                }\n" +
            "                return target[property];\n" +
            "            }\n" +
            "        };\n" +
            "\n" +
            "        // 使用Proxy创建一个新对象,它将对原始对象的所有操作委托给handler  \n" +
            "        const proxyObject = new Proxy(originalObject, handler);\n" +
            "\n" +
            "        window.trsAppJSBridge = proxyObject;\n" +
            "\n" +
            "        console.log(\"注入trsAppJSBridge成功\");\n" +
            "        return true;\n" +
            "    } catch (e) {\n" +
            "        console.log(\"注入trsAppJSBridge失败,error=\" + e);\n" +
            "        return false;\n" +
            "    }\n" +
            "})()\n";

    private static final String NAME = "trsAppJsBridgeProxy";

    public static void rejectToWebView(WebView webView) {

        webView .evaluateJavascript(injectJS, s -> {
            Log.i("zzz", "onReceiveValue: s="+ s);
            webView.addJavascriptInterface(new TrsJsProxy(),NAME);
        });
    }

    public TrsJsProxy() {

    }

    @JavascriptInterface
    public void callProxy(String methodName,String param){
        Log.d("zzz", "callProxy() called with: methodName = [" + methodName + "], param = [" + param + "]");
    }

}

调用

为了实现对原来网页中的js调用的无缝切换,需要在原来网页js执行之前,注入上面的内容。需要在WebViewClientonPageStarted 方法中执行

     webView.setWebViewClient(new WebViewClient() {
  @Override
            public void onPageStarted(WebView webView, String s, Bitmap bitmap) {
                super.onPageStarted(webView, s, bitmap);
                TrsJsProxy.rejectToWebView(webView);
            }
	}

运行结果在这里插入图片描述

在这里插入图片描述

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

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

相关文章

操作系统安全:Windows与Linux的安全标识符,身份鉴别和访问控制

「作者简介」&#xff1a;2022年北京冬奥会中国代表队&#xff0c;CSDN Top100&#xff0c;学习更多干货&#xff0c;请关注专栏《网络安全自学教程》 操作系统有4个安全目标&#xff0c;也就是说想要保证操作系统的安全&#xff0c;就必须实现这4个需求&#xff1a; 标识系统…

网络协议安全:OSI七层模型分层及作用,数据封装与解封过程,数据传输过程。

「作者简介」&#xff1a;2022年北京冬奥会中国代表队&#xff0c;CSDN Top100&#xff0c;学习更多干货&#xff0c;请关注专栏《网络安全自学教程》 这一章节我们需要知道OSI分哪七层&#xff0c;每层的作用&#xff0c;知道数据在七层模型中是怎样传输的&#xff0c;封包和解…

数据结构练习:链表扩容

大致步骤&#xff1a; 一&#xff1a;创建一个新链表&#xff0c;遍历原链表的同时&#xff0c;将原链表的值复制给新链表 二&#xff1a;将新链表插入到原链表中&#xff08;大致如下&#xff09; 注&#xff1a; 1.头结点是不存有数据的 2.记得malloc后要free 3.*&是…

男士休闲裤比较好的品牌有哪些?高品质休闲男装推荐

穿衣服最重要的并不是要求多好看多时尚&#xff0c;相信绝大部分年纪在23岁以上的男同胞们更希望穿一些简约好搭配的款式&#xff0c;更重要的其实就是要求质量耐穿&#xff0c;以及有足够好的舒适性。 但是现在市面上的品牌实在是太多了&#xff0c;而且质量也参差不齐&#x…

SpringBoot 3.x + Swagger3 踩坑实录

问题描述 维护的SpringBoot版本是3.0版本&#xff0c;翻教程的时候发现很多SpringBoot2.x版本用的都是springfox&#xff0c;但问题是在SpringBoot3.x版本后&#xff0c;逐渐不支持springfox&#xff0c;强行启动会导致异常&#xff0c;现阶段使用的Springdoc进行替换。 参考…

设计模式-六大原则

设计模式的六大原则是软件工程中的基本概念&#xff0c;使得构建可维护、可扩展和可重用的代码。 1.单一职责原则&#xff08;Single Responsibility Principle&#xff09;&#xff1a;一个类或方法应该只有一个引起变化的原因&#xff0c;确保类或模块的功能高度内聚。 案例&…

力扣数据库题库学习(4.22日)

577. 员工奖金 问题链接 思路分析 Employee表与Bonus表通过empId字段可以连接&#xff0c;需求是查出奖金少于1000的员工名和奖金值。 这里奖金少于1000的情况就是没有奖金有奖金但少于1000 这里我给出的解决方案就是使用左连接&#xff0c;将Employee表作为左表&#xff…

c++二叉树的进阶--二叉搜索树

1. 二叉搜索树的概念 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性质的二叉树: 若它的左子树不为空&#xff0c;则左子树上所有节点的值都小于根节点的值 若它的右子树不为空&#xff0c;则右子树上所有节点的值都大于根节点的值 它的左…

企业为什么要选择通配符SSL证书使用?

企业选择使用通配符SSL证书主要是出于以下几个重要原因&#xff1a; 1. 经济性&#xff1a; - 节省成本&#xff1a;相较于为每一个子域名单独购买并维护单独的SSL证书&#xff0c;通配符证书能够以一张证书覆盖同一主域名下的所有同级子域名&#xff0c;无需为新增或已有的子域…

SpringBoot框架——8.MybatisPlus常见用法(常用注解+内置方法+分页查询)

1.MybatisPlus常用注解&#xff1a; 1.1 当数据库、表名和字段名和实体类完全一致时无需加注解&#xff0c;不一致时&#xff1a; TableName指定库名 TableId指定表名 TableField指定字段名 1.2 自增主键&#xff1a; TableId(typeIdType.AUTO) private Long id; 1.3 实体类中属…

【JAVA】java 中的Stream 常用函数

java 中的Stream 常用函数 一、简介1.1、什么是Stream&#xff1f;1.2、创建Stream1.3、Stream的特性 二、Stream的操作2.1、中间操作&#xff1a;2.2、终端操作&#xff1a;2.3、Stream的并行处理 三、Stream 常用函数四、使用示例4.1、计算集合中偶数的平方和&#xff1a;4.2…

新手也能学会的甘特图制作教程

甘特图是什么&#xff1f; 甘特图(Gantt Chart)是一种以图表形式直观展示项目计划的工具,由20世纪初的管理学家亨利甘特(Henry Gantt)发明并命名。它具有以下几个主要特点: 水平时间轴 甘特图的横轴是一条时间轴,通常按天、周或月来刻度,直观展示了项目从开始到结束的整个时间…

【信息收集】端口扫描masscan负载均衡识别lbd

★★免责声明★★ 文章中涉及的程序(方法)可能带有攻击性&#xff0c;仅供安全研究与学习之用&#xff0c;读者将信息做其他用途&#xff0c;由Ta承担全部法律及连带责任&#xff0c;文章作者不承担任何法律及连带责任。 1、什么是masscan masscan在kali系统上是自带的端口扫描…

回归预测 | Matlab实现BO-RF贝叶斯优化随机森林多变量回归预测

回归预测 | Matlab实现BO-RF贝叶斯优化随机森林多变量回归预测 目录 回归预测 | Matlab实现BO-RF贝叶斯优化随机森林多变量回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现BO-RF贝叶斯优化随机森林多变量回归预测&#xff1b; 2.输入7个特征&#xf…

考研日常记录(upd 24.4.24)

由于实在太无聊了 &#xff0c; 所以记录以下考研备考日常 &#xff0c; 增加一点成就感 &#xff0c; 获得一点前进动力。 文章目录 2024.4.18 周四课程情况&#xff1a;时间规划&#xff1a; 2024.4.19 周五课程情况&#xff1a;时间规划&#xff1a; 2024.4.20 周六2024.4.2…

Java知识总结---并发篇

线程 线程的状态 Java中线程可以有如下6中状态&#xff1a; NEW 新创建 RUNNABLE 可运行 BLOCKED 阻塞 WAITING 等待 TIMED WAITING 计时等待 TERMINATED 终止 线程的创建 &#xff08;1&#xff09;继承Thread类 public class ExtendsThread extends Thread { O…

学习Docker笔记

在23号刚刚学完新版本的docker还想说回去继续学习老版本的springcloud课程里面的docker 结果一看黑马首页新版本课程出了&#xff0c;绷不住了。以下是我学习新版本docker的笔记&#xff0c;记录了我学习过程遇到的各种bug和解决&#xff0c;也参考了黑马老师的笔记&#xff1a…

SLMs之Phi-3:Phi-3的简介、安装和使用方法、案例应用之详细攻略

SLMs之Phi-3&#xff1a;Phi-3的简介、安装和使用方法、案例应用之详细攻略 导读&#xff1a;2024年4月23日&#xff0c;微软发布Phi-3&#xff0c;这是微软推出的一款新的开源AI模型家族Phi-3。背景痛点&#xff1a;小语言模型(SLM)尽管规模不大&#xff0c;但在语言理解、代码…

three.js 制作卡牌正反面 旋转

1.效果图 2.代码 <template><div><div id"container"></div></div> </template><script> import * as THREE from "three"; import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.…

C语言指针进阶:各类型指针变量详解

目录 1. 字符指针变量2. 数组指针变量2.1 什么是数组指针变量2.2 数组指针变量的初始化 3. 二维数组传参的本质4. 函数指针变量4.1 函数指针变量的创建4.2 函数指针变量的使用4.3 代码分析4.3.1 typedef 关键字 5. 函数指针数组6. 转移表 正文开始。 1. 字符指针变量 我们可以…