🎨 Renderers — 基础类型字面量渲染器
baksmali 的
Renderers包提供 8 个独立的静态工具类,将 Java 基本类型值格式化为 smali 字面量文本。
| 包路径 | org.jf.baksmali.Renderers |
|---|---|
| 源码目录 | Renderers/ |
| 类数量 | 8 个(每种基本类型一个) |
📋 渲染器清单
| 类名 | 源码链接 | 输入类型 | 输出示例 |
|---|---|---|---|
LongRenderer | LongRenderer.java | long | 0x1234567890L、-0xAL |
IntegerRenderer | IntegerRenderer.java | int | 0x1、-0xFF |
FloatRenderer | FloatRenderer.java | float | 3.14f、NaNf、Infinityf |
DoubleRenderer | DoubleRenderer.java | double | 3.14、NaN、-Infinity |
BooleanRenderer | BooleanRenderer.java | boolean | true、false |
ByteRenderer | ByteRenderer.java | byte | 0x1t、-0x10t |
CharRenderer | CharRenderer.java | char | 'A'、'\n'、'�' |
ShortRenderer | ShortRenderer.java | short | 0x64s、-0x1s |
🧠 关键实现
LongRenderer — 最复杂的渲染逻辑
java
public static void writeTo(IndentingWriter writer, long val) throws IOException {
if (val<0) {
writer.write("-0x");
writer.printUnsignedLongAsHex(-val);
writer.write('L');
} else {
writer.write("0x");
writer.printUnsignedLongAsHex(val);
writer.write('L');
}
}
public static void writeSignedIntOrLongTo(IndentingWriter writer, long val) throws IOException {
if (val<0) {
writer.write("-0x");
writer.printUnsignedLongAsHex(-val);
if (val < Integer.MIN_VALUE) {
writer.write('L'); // 超出 int 范围才加 L 后缀
}
} else {
writer.write("0x");
writer.printUnsignedLongAsHex(val);
if (val > Integer.MAX_VALUE) {
writer.write('L');
}
}
}writeSignedIntOrLongTo() 用于处理宽字面量指令(const-wide),当值在 int 范围内时省略 L 后缀,使输出更简洁。
CharRenderer — 转义处理
char 值的渲染需要处理控制字符、特殊字符的转义,确保输出的 smali 文件中字符字面量是合法的 Java/smali 语法。
🔗 关系
📌 小结
Renderers 包遵循"单一职责"原则——每个渲染器只负责一种类型,所有渲染器都采用纯静态无状态设计,无需实例化。它们在 EncodedValueAdaptor 的 switch 分发中统一调用,也在 InstructionMethodItem.writeLiteral() 中直接使用,是 baksmali 输出层的最底层工具。
LiteralTools(smali 包)负责反向操作——将 smali 文本字面量解析回 Java 数值,两者构成完整的序列化/反序列化对。