赞
踩
Dalvik 虚拟机运行的是 Dex 文件 ; Dex 文件并不是最终 DVM 运行的文件 , Dex 文件还需要再次优化为 Odex 文件 , 这才是最终运行在 DVM 上的文件 ;
安装 APK 完毕后 , 运行时 , 或者 使用类加载器加载 Dex 文件时 , 才会生成 Odex 文件 ;
Odex 文件会存放在 /data/dalvik-cache 目录下 ;
Dalvik 虚拟机中运行的是 Dex 文件 , Java 虚拟机运行的是 Jar 文件 ;
示例代码 :
public class Student { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public void ageIncrease(){ synchronized(this) { this.age++; } } }
public class User {
private int age = 0;
public synchronized void increase() {
this.age++;
}
}
打包 Jar 文件 :
使用如下命令 , 将 Class 字节码文件打成 Jar 包 :
jar cvf main.jar Student.class User.class
输出结果 :
D:\002_Project\004_Java_Learn\Main\out\production\Main>jar cvf main.jar Student.class User.class
已添加清单
正在添加: Student.class(输入 = 889) (输出 = 478)(压缩了 46%)
正在添加: User.class(输入 = 356) (输出 = 251)(压缩了 29%)
打包 Dex 文件 :
首先配置下环境变量 , 将编译工具目录配置到环境变量中 , 这里选择使用 30.0.3 版本的编译工具 ( build-tools ) ;
D:\001_Develop\001_SDK\Sdk\build-tools\30.0.3
配置到环境变量 Path 中 ;
执行
dx --dex --output main.dex main.jar
命令 , 打包 Dex 文件 , 命令行输出 :
打包后的 main.dex 文件 ;
使用如下命令 , 反编译 Dex 文件 :
dexdump -d -l plain main.dex
输出 Dex 文件的内容 :
D:\002_Project\004_Java_Learn\Main\out\production\Main>dexdump -d -l plain main.dex Processing 'main.dex'... Opened 'main.dex', DEX version '035' Class #0 - Class descriptor : 'LStudent;' Access flags : 0x0001 (PUBLIC) Superclass : 'Ljava/lang/Object;' Interfaces - Static fields - Instance fields - #0 : (in LStudent;) name : 'age' type : 'I' access : 0x0002 (PRIVATE) #1 : (in LStudent;) name : 'name' type : 'Ljava/lang/String;' access : 0x0002 (PRIVATE) Direct methods - #0 : (in LStudent;) name : '<init>' type : '()V' access : 0x10001 (PUBLIC CONSTRUCTOR) code - registers : 1 ins : 1 outs : 1 insns size : 4 16-bit code units 0001b8: |[0001b8] Student.<init>:()V 0001c8: 7010 0800 0000 |0000: invoke-direct {v0}, Ljava/lang/Object;.<init>:()V // method@0008 0001ce: 0e00 |0003: return-void catches : (none) positions : 0x0000 line=1 locals : 0x0000 - 0x0004 reg=0 this LStudent; Virtual methods - #0 : (in LStudent;) name : 'ageIncrease' type : '()V' access : 0x0001 (PUBLIC) code - registers : 2 ins : 1 outs : 0 insns size : 12 16-bit code units 0001d0: |[0001d0] Student.ageIncrease:()V 0001e0: 1d01 |0000: monitor-enter v1 0001e2: 5210 0000 |0001: iget v0, v1, LStudent;.age:I // field@0000 0001e6: d800 0001 |0003: add-int/lit8 v0, v0, #int 1 // #01 0001ea: 5910 0000 |0005: iput v0, v1, LStudent;.age:I // field@0000 0001ee: 1e01 |0007: monitor-exit v1 0001f0: 0e00 |0008: return-void 0001f2: 0d00 |0009: move-exception v0 0001f4: 1e01 |000a: monitor-exit v1 0001f6: 2700 |000b: throw v0 catches : 1 0x0001 - 0x000b <any> -> 0x0009 positions : 0x0000 line=22 0x0001 line=23 0x0007 line=24 0x0008 line=25 0x0009 line=24 locals : 0x0000 - 0x000c reg=1 this LStudent; #1 : (in LStudent;) name : 'getAge' type : '()I' access : 0x0001 (PUBLIC) code - registers : 2 ins : 1 outs : 0 insns size : 3 16-bit code units 000204: |[000204] Student.getAge:()I 000214: 5210 0000 |0000: iget v0, v1, LStudent;.age:I // field@0000 000218: 0f00 |0002: return v0 catches : (none) positions : 0x0000 line=14 locals : 0x0000 - 0x0003 reg=1 this LStudent; #2 : (in LStudent;) name : 'getName' type : '()Ljava/lang/String;' access : 0x0001 (PUBLIC) code - registers : 2 ins : 1 outs : 0 insns size : 3 16-bit code units 00021c: |[00021c] Student.getName:()Ljava/lang/String; 00022c: 5410 0100 |0000: iget-object v0, v1, LStudent;.name:Ljava/lang/String; // field@0001 000230: 1100 |0002: return-object v0 catches : (none) positions : 0x0000 line=6 locals : 0x0000 - 0x0003 reg=1 this LStudent; #3 : (in LStudent;) name : 'setAge' type : '(I)V' access : 0x0001 (PUBLIC) code - registers : 2 ins : 2 outs : 0 insns size : 3 16-bit code units 000234: |[000234] Student.setAge:(I)V 000244: 5901 0000 |0000: iput v1, v0, LStudent;.age:I // field@0000 000248: 0e00 |0002: return-void catches : (none) positions : 0x0000 line=18 0x0002 line=19 locals : 0x0000 - 0x0003 reg=0 this LStudent; 0x0000 - 0x0003 reg=1 age I #4 : (in LStudent;) name : 'setName' type : '(Ljava/lang/String;)V' access : 0x0001 (PUBLIC) code - registers : 2 ins : 2 outs : 0 insns size : 3 16-bit code units 00024c: |[00024c] Student.setName:(Ljava/lang/String;)V 00025c: 5b01 0100 |0000: iput-object v1, v0, LStudent;.name:Ljava/lang/String; // field@0001 000260: 0e00 |0002: return-void catches : (none) positions : 0x0000 line=10 0x0002 line=11 locals : 0x0000 - 0x0003 reg=0 this LStudent; 0x0000 - 0x0003 reg=1 name Ljava/lang/String; source_file_idx : 7 (Student.java) Class #1 - Class descriptor : 'LUser;' Access flags : 0x0001 (PUBLIC) Superclass : 'Ljava/lang/Object;' Interfaces - Static fields - Instance fields - #0 : (in LUser;) name : 'age' type : 'I' access : 0x0002 (PRIVATE) Direct methods - #0 : (in LUser;) name : '<init>' type : '()V' access : 0x10001 (PUBLIC CONSTRUCTOR) code - registers : 2 ins : 1 outs : 1 insns size : 7 16-bit code units 000264: |[000264] User.<init>:()V 000274: 7010 0800 0100 |0000: invoke-direct {v1}, Ljava/lang/Object;.<init>:()V // method@0008 00027a: 1200 |0003: const/4 v0, #int 0 // #0 00027c: 5910 0200 |0004: iput v0, v1, LUser;.age:I // field@0002 000280: 0e00 |0006: return-void catches : (none) positions : 0x0000 line=1 0x0003 line=2 locals : 0x0000 - 0x0007 reg=1 this LUser; Virtual methods - #0 : (in LUser;) name : 'increase' type : '()V' access : 0x20001 (PUBLIC DECLARED_SYNCHRONIZED) code - registers : 2 ins : 1 outs : 0 insns size : 12 16-bit code units 000284: |[000284] User.increase:()V 000294: 1d01 |0000: monitor-enter v1 000296: 5210 0200 |0001: iget v0, v1, LUser;.age:I // field@0002 00029a: d800 0001 |0003: add-int/lit8 v0, v0, #int 1 // #01 00029e: 5910 0200 |0005: iput v0, v1, LUser;.age:I // field@0002 0002a2: 1e01 |0007: monitor-exit v1 0002a4: 0e00 |0008: return-void 0002a6: 0d00 |0009: move-exception v0 0002a8: 1e01 |000a: monitor-exit v1 0002aa: 2700 |000b: throw v0 catches : 1 0x0001 - 0x0007 <any> -> 0x0009 positions : 0x0000 line=5 0x0007 line=6 0x0009 line=5 locals : 0x0000 - 0x000c reg=1 this LUser; source_file_idx : 8 (User.java) D:\002_Project\004_Java_Learn\Main\out\production\Main>
第 #0
号 Class 类 , 类描述符是 LStudent;
, 父类 Ljava/lang/Object;
Processing 'main.dex'...
Opened 'main.dex', DEX version '035'
Class #0 -
Class descriptor : 'LStudent;'
Access flags : 0x0001 (PUBLIC)
Superclass : 'Ljava/lang/Object;'
该类中有 2 2 2 个字段 , 分别是 name 和 age ;
Instance fields -
#0 : (in LStudent;)
name : 'age'
type : 'I'
access : 0x0002 (PRIVATE)
#1 : (in LStudent;)
name : 'name'
type : 'Ljava/lang/String;'
access : 0x0002 (PRIVATE)
构造函数方法 :
Direct methods -
#0 : (in LStudent;)
name : '<init>'
type : '()V'
access : 0x10001 (PUBLIC CONSTRUCTOR)
code -
registers : 1
ins : 1
outs : 1
insns size : 4 16-bit code units
增加年龄方法 :
public void ageIncrease(){
synchronized(this) {
this.age++;
}
}
对应
Virtual methods -
#0 : (in LStudent;)
name : 'ageIncrease'
type : '()V'
access : 0x0001 (PUBLIC)
code -
registers : 2
ins : 1
outs : 0
insns size : 12 16-bit code units
其它方法省略 ;
第
2
2
2 个类 编号 #1
, 是 User 类 , 类描述符 LUser;
, 有 age
字段 ;
Class #1 -
Class descriptor : 'LUser;'
Access flags : 0x0001 (PUBLIC)
Superclass : 'Ljava/lang/Object;'
Interfaces -
Static fields -
Instance fields -
#0 : (in LUser;)
name : 'age'
type : 'I'
access : 0x0002 (PRIVATE)
构造方法反编译内容如下 :
Direct methods -
#0 : (in LUser;)
name : '<init>'
type : '()V'
access : 0x10001 (PUBLIC CONSTRUCTOR)
code -
registers : 2
ins : 1
outs : 1
insns size : 7 16-bit code units
void increase()
方法对应反编译内容 :
Virtual methods -
#0 : (in LUser;)
name : 'increase'
type : '()V'
access : 0x20001 (PUBLIC DECLARED_SYNCHRONIZED)
code -
registers : 2
ins : 1
outs : 0
insns size : 12 16-bit code units
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。