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

【Android】类加载器热修复-随记(二)

1. 背景

在【Android】类加载器&热修复-随记一文中了解了类加载,要完成完整的热修复过程,我们需要构建出差量jar包。而这构建差量包分为两个步骤:

  1. 原包,注解解析和插桩;
  2. 变更后,差量包构建;

在这两步过程中会涉及到较多的字节码操作,这里我们需要了解下。我们都听过ASM的大名,但门槛较高,这里选择Javaassist来入门。
在这里插入图片描述
另在Robust的构建插件中也可看见所使用的是Javaassist这个库:
在这里插入图片描述

2. 要点

官方文档:https://www.javassist.org/
学习文档:http://www.javassist.org/tutorial/tutorial.html?spm=395e44f7.4d3ad9aa.0.0.13e45fb4COpEYh

主旨是为了学习Robust,故这里的javaassist版本和该项目保持一致。即:

implementation 'org.javassist:javassist:3.20.0-GA'

下面章节将围绕这个版本进行学习。字节码操作大致分为增、删、改。网上查阅到了这篇文章:javassist使用全解析
,写的挺详细的。这里我们就了解两个能力:

  1. 新增一个类;
  2. 在方法前,插装;

2.1 新增一个类到apk中

在app构建过程中,如何通过javaassist来做到满足某个条件就新增一个类到最终apk中?
可以通过注册一个自定义transfrom:

AppExtension appExtension = project.getExtensions().getByType(AppExtension.class);
appExtension.registerTransform(new JavaAssistTransform(project));

在这个transfrom中处理class文件。比如按照上面博客教程生成一个class:

// "com.mengfou.sample.javaassist.AClass"
private byte[] generateTestClass(ClassBuffer classBuffer) {try {ClassPool pool = ClassPool.getDefault();CtClass ctClass = pool.makeClass(classBuffer.getClassName());CtField paramField = new CtField(pool.get("java.lang.String"), "value", ctClass);paramField.setModifiers(Modifier.PRIVATE);ctClass.addField(paramField, CtField.Initializer.constant("1"));CtConstructor cons = new CtConstructor(new CtClass[]{pool.get("java.lang.String")}, ctClass);cons.setBody("{$0.value=$1;}");ctClass.addConstructor(cons);CtMethod calculate = new CtMethod(pool.get("java.lang.String"), "calculate", new CtClass[]{}, ctClass);calculate.setModifiers(Modifier.PRIVATE);calculate.setBody("{return $0.value + \"_hello\";}");ctClass.addMethod(calculate);File parentPath = new File(project.getBuildDir(), "gen

相关文章:

【Android】类加载器热修复-随记(二)

1. 背景 在【Android】类加载器&热修复-随记一文中了解了类加载,要完成完整的热修复过程,我们需要构建出差量jar包。而这构建差量包分为两个步骤: 原包,注解解析和插桩;变更后,差量包构建;在这两步过程中会涉及到较多的字节码操作,这里我们需要了解下。我们都听过…...

从零开始用react + tailwindcss + express + mongodb实现一个聊天程序(八) 聊天框用户列表

简单画了个聊天框 就是咱们的HomePage.jsx 1.后端接口开发 在server/src/index.js 新增 messagesRoutes 先引入 import messageRoutes from ./routes/message.route.js // 消息接口 app.use(/api/messages, messageRoutes) 在routes文件夹下新建message.route.js 有3个路…...

Linux网络 TCP全连接队列与tcpdump抓包

TCP全连接队列 在 Linux 网络中,TCP 全连接队列(也称为 Accept 队列)是一个重要的概念,用于管理已经完成三次握手,即已经处于 established 状态但尚未被应用程序通过 accept( ) 函数处理的 TCP 连接,避免因…...

水滴tabbar canvas实现思路

废话不多说之间看效果图,只要解决了这个效果水滴tabbar就能做出来了 源码地址 一、核心实现步骤分解 布局结构搭建 使用 作为绘制容器 设置 width=600, height=200 基础尺寸 通过 JS 动态计算实际尺寸(适配高清屏) function initCanvas() {// 获取设备像素比(解决 Re…...

鸿蒙通过用户首选项实现数据持久化

鸿蒙通过用户首选项实现数据持久化 1.1 场景介绍 用户首选项为应用提供Key-Value键值型的数据处理能力,支持应用持久化轻量级数据,并对其修改和查询。当用户希望有一个全局唯一存储的地方,可以采用用户首选项来进行存储。Preferences会将该…...

在Ubuntu中,某个文件的右下角有一把锁的标志是什么意思?

在Ubuntu中,某个文件的右下角有一把锁的标志是什么意思? 在 Ubuntu(或其他基于 GNOME 文件管理器的 Linux 发行版)中,文件或文件夹的右下角出现一把“锁”标志,通常表示 你当前的用户没有该文件/文件夹的写…...

7.1.1 计算机网络的组成

文章目录 物理组成功能组成工作方式完整导图 物理组成 计算机网络是将分布在不同地域的计算机组织成系统,便于相互之间资源共享、传递信息。 计算机网络的物理组成包括硬件和软件。硬件中包含主机、前端处理器、连接设备、通信线路。软件中包含协议和应用软件。 功…...

使用 Docker 部署 RabbitMQ 的详细指南

使用 Docker 部署 RabbitMQ 的详细指南 在现代应用程序开发中,消息队列系统是不可或缺的一部分。RabbitMQ 是一个流行的开源消息代理软件,它实现了高级消息队列协议(AMQP)。本文将详细介绍如何使用 Docker 部署 RabbitMQ&#xf…...

岛屿的数量(BFS)

给你一个由 1(陆地)和 0(水)组成的的二维网格,请你计算网格中)。 岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。 此外,你可以假设该网格的四条边均被水包…...

线上JVM OOM问题,如何排查和解决?

今天咱们来聊聊让无数 Java 开发者头疼的 JVM OOM(Out Of Memory,内存溢出)问题。在面试中,OOM 问题也是面试官的“心头好”,因为它能直接考察你对 JVM 的理解,以及你在实际问题面前的排查和解决能力。 一…...

Linux的缓存I/O和无缓存IO

一、I/O缓存的背景 I/O缓存是指在内存里开辟一块区域,存放用来接收用户输入和用于计算机输出的数据,以减小系统开销和提高外设效率。linux对IO文件的操作分为不带缓存的IO操作和带缓存的IO操作(标准IO操作)。为什么存在C标准I/O库…...

【弹性计算】弹性裸金属服务器和神龙虚拟化(三):弹性裸金属技术

弹性裸金属服务器和神龙虚拟化(三):弹性裸金属技术 1.弹性裸金属技术背景1.1 传统 KVM 虚拟化系统导致 CPU 计算特性损失1.2 传统 KVM 虚拟化系统导致资源争抢不可避免1.3 传统 KVM 虚拟化系统导致 I/O 性能瓶颈 2.弹性裸金属技术实现2.1 VPC…...

【MySQL】(2) 库的操作

SQL 关键字,大小写不敏感。 一、查询数据库 show databases; 注意加分号,才算一句结束。 二、创建数据库 {} 表示必选项,[] 表示可选项,| 表示任选其一。 示例:建议加上 if not exists 选项。 三、字符集编码和排序…...

Hyper-V -docker-vmware 三者的关系

1. Docker 正常运行,需要启动Hyper-V ,打开 hypervisorlaunchtype 2.VMware 正常时,需要关闭Hyper-V ,关闭 hypervisorlaunchtype 2.1资源管理器->CPU 里要开启虚拟化 2.2 服务-停掉HV服务 2.3 控制面板 不勾选 2.4 …...

IP-----双重发布

目录 6.双重发布 1.重发布的作用 2.部署条件 1.必须存在ASBR 2.种子度量值 3.重发布的规则 4.重发布的数量 5.重发布的场景 1.场景和规则 2.直连和静态 3.动态RIP 4.动态OSPF 5.更改开销值 6.重发布的问题1 7.重发布的问题2 1.流量 2.前缀列表 3.偏移列表 4…...

【新立电子】探索AI眼镜背后的黑科技,FPC如何赋能实时翻译与语音识别,点击了解未来沟通的新方式!

在全球化的今天,语言障碍成为人们沟通与交流的一大难题。AI眼镜作为一种新兴的智能设备,正在通过实时翻译与语音识别功能,打破语言壁垒,为人们提供无缝沟通的解决方案。FPC在AI眼镜中的应用,为实时翻译与语音识别功能的…...

LeetCode 热题 100_寻找两个正序数组的中位数(68_4_困难_C++)(二分查找)(先合并再挑选中位数;划分数组(二分查找))

LeetCode 热题 100_寻找两个正序数组的中位数(68_4) 题目描述:输入输出样例:题解:解题思路:思路一(先合并再挑选中位数):思路二(划分数组(二分查找…...

Java多线程与高并发专题——深入ReentrantReadWriteLock

深入ReentrantReadWriteLock 读写锁出现原因 synchronized和ReentrantLock都是互斥锁。如果说有一个操作是读多写少的,还要保证线程安全的话。如果采用上述的两种互斥锁,效率方面很定是很低的。在这种情况下,咱们就可以使用ReentrantReadWr…...

【Python 语法】算法合集

查找二分查找代码大 O 表示法 广度优先搜索代码 狄克斯特拉算法 递归递归调用栈 分而治之(divide and conquer,D&C)贪心教室调度问题背包问题集合覆盖问题 动态规划背包问题旅游行程最优化 遇到问题时, 如果不确定该如何 高效…...

[STM32]从零开始的STM32 BSRR、BRR、ODR寄存器讲解

一、前言 学习STM32一阵子以后,相信大家对STM32 GPIO的控制也有一定的了解了。之前在STM32 LED的教程中也教了大家如何使用寄存器以及库函数控制STM32的引脚从而点亮一个LED,之前的寄存器只是作为一个引入,并没有深层次的讲解,在教…...

如何用Hearthstone-Script解放炉石传说玩家双手?开源自动化工具全解析

如何用Hearthstone-Script解放炉石传说玩家双手?开源自动化工具全解析 【免费下载链接】Hearthstone-Script Hearthstone script(炉石传说脚本) 项目地址: https://gitcode.com/gh_mirrors/he/Hearthstone-Script 你是否也曾为炉石传说…...

软件评测师基础知识专项刷题:软件测试过程

前言软考软件评测师备考之路,基础刷题必不可少。本文围绕软件测试过程模块整理经典习题 核心考点梳理,系列内容长期连载更新,慢慢积累、逐个突破,轻松夯实应试功底。考点测试过程模型1.组织级测试过程组织级测试过程用于开发和管…...

终极指南:如何用BetterGI智能辅助工具彻底解放你的原神游戏体验

终极指南:如何用BetterGI智能辅助工具彻底解放你的原神游戏体验 【免费下载链接】better-genshin-impact 📦BetterGI 更好的原神 - 自动拾取 | 自动剧情 | 全自动钓鱼(AI) | 全自动七圣召唤 | 自动伐木 | 自动刷本 | 自动采集/挖矿/锄地 | 一条龙 | 全连…...

丹青识画系统GitHub协作开发指南:从代码克隆到PR提交全流程

丹青识画系统GitHub协作开发指南:从代码克隆到PR提交全流程 你是不是也遇到过这种情况?团队里几个人一起改代码,最后合并的时候发现冲突一大堆,张三改了李四的代码,王五的提交又把功能搞坏了,光是解决这些…...

寻音捉影·侠客行从零开始:基于ModelScope FunASR的私有化语音检索实践

寻音捉影侠客行:从零开始基于ModelScope FunASR的私有化语音检索实践 1. 什么是“寻音捉影侠客行”? 在信息爆炸的时代,我们每天面对大量语音内容——会议录音、课程回放、采访素材、客服对话……但想从中快速找到一句关键话,却…...

Qwen3.5-9B快速上手:3步启动WebUI(supervisorctl restart)超详细步骤

Qwen3.5-9B快速上手:3步启动WebUI(supervisorctl restart)超详细步骤 1. 开篇介绍 Qwen3.5-9B是一款拥有90亿参数的开源大语言模型,具备强大的逻辑推理、代码生成和多轮对话能力。特别值得一提的是,它的多模态变体Qw…...

OpenClaw安全沙箱:Qwen3-32B镜像的权限隔离实验

OpenClaw安全沙箱:Qwen3-32B镜像的权限隔离实验 1. 为什么需要安全沙箱 当我第一次看到OpenClaw能够直接操作我的电脑文件时,既兴奋又担忧。兴奋的是它能够帮我自动化处理大量重复工作,担忧的是如果AI不小心执行了rm -rf这样的危险命令怎么…...

P1AM CPU库:工业级嵌入式I/O控制框架解析

1. P1AM CPU库技术解析:面向工业自动化场景的嵌入式I/O控制框架1.1 平台定位与工程价值P1AM(ProductivityOpen Automation Module)并非通用型MCU开发板,而是一个专为工业现场总线级I/O扩展设计的嵌入式控制器平台。其核心价值在于…...

时间放大器:从亚稳态到数字训练式的硬件实现解析

1. 时间放大器的核心价值与应用场景 时间放大器(Time Amplifier)这个名词听起来有点科幻,但它的原理其实非常接地气。想象一下你用两根手指同时按下钢琴的两个琴键,如果两次按键的时间差只有几毫秒,普通人耳朵可能分辨…...

RoBERTa 微调:防过拟合终极调参手册

🛡️ RoBERTa 微调:防过拟合终极调参手册核心逻辑:在数据量有限(~2.6k)的情况下,通过限制模型容量(冻结/Dropout)和平滑优化过程(Weight Decay/Label Smoothing&#xff…...