网站首页 > 资源文章 正文
从编译原理看android的编译文件
在android的开发过程中,我们会接触到很多文件类型。今天从编译的角度解释下,这些文件类型都是干什么用的。
一、编译的最初过程
但是我们android的过程中不只2中代码类型文件,都有哪些?都是做什么用的呢?
二、我们先从java项目开始
大家知道Android开发是基于java来做的。所以android和java开发都会有java、class、jar文件类型
1、假如我们写了一个java文件
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World");
}
}
2、用javac命令生成calss文件
javac HelloWorld.java
3、然后用javap命令查看编译后的代码
javap -c HelloWorld
class文件中的内容
Compiled from "HelloWorld.java"
public class com.example.popupsimple.HelloWorld {
public com.example.popupsimple.HelloWorld();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3 // String Hello World
5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
}
如果是java项目的话,我们就可以生成jar,来用于依赖和执行
jar -cvf hello.jar com/example/popupsimple/HelloWorld.class
因为jar是一个以ZIP格式构建,以.jar为文件扩展名的归档文件,我们将后缀修改为zip,之后解压,然后会找到对应的class文件,查看此class文件的字节码和上面的上文的一样
Compiled from "HelloWorld.java"
public class com.example.popupsimple.HelloWorld {
public com.example.popupsimple.HelloWorld();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3 // String Hello World
5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
}
到这里java结束了,但是在Android项目中到这里还没有结束。
三、从android的生成物开始
1、我们反编译一个apk
我们在主项目中写的代码都变成来一个个的dex。
这个是一个全新的文件格式。那他是怎么来的呢?
dx --dex --output=Hello.dex com/example/popupsimple/HelloWorld.class
2、对dex进行反编译
.class public Lcom/example/popupsimple/HelloWorld;
.super Ljava/lang/Object;
.source "HelloWorld.java"
# direct methods
.method public constructor <init>()V
.registers 1
.prologue
.line 3
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
return-void
.end method
.method public static main([Ljava/lang/String;)V
.registers 3
.prologue
.line 5
sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;
const-string v1, "Hello World"
invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V
.line 6
return-void
.end method
四、总结
意外不意外?惊喜不惊喜?
1、一个类的字节码表现形式不一样了!!!
是的,就是不一样。这个就是为啥我们老说,Android是基于jvm开发,但是他虚拟机是Dalvik虚拟机
也就是说,class中的字节码是要在jvm上运行的,而dex中的字节码是要在Dalvik中运行的。因为是不同的虚拟机,所以字节码是不一样的。
有的同学又会问,为啥已经有了jvm,android还要再费劲吧啦地搞一个Dalvik虚拟机呢?
Dalvik基于寄存器的虚拟机 而jvm执行是基于虚拟栈的虚拟机
- dvm速度快!寄存器存取速度比栈快得多,dvm可以根据硬件实现最大的优化,比较适合移动设备。JAVA虚拟机基于栈结构,程序在运行时虚拟机需要频繁地从栈上读取写入数据,这个过程需要更多的指令分派与内存访问次数,会耗费很多CPU时间。
- 指令数小!dvm基于寄存器,所以它的指令是二地址和三地址混合,指令中指明了操作数的地址;jvm基于栈,它的指令是零地址,指令的操作数对象默认是操作数栈中的几个位置。这样带来的结果就是dvm的指令数相对于jvm的指令数会小很多,jvm需要多条指令而dvm可能只需要一条指令。
- jvm基于栈带来的好处是可以做得足够简单,真正的跨平台,保证在低硬件条件下能够正常运行。而dvm操作平台一般指明是ARM系统,所以采取的策略有所不同。需要注意的是dvm基于寄存器,但是这也是个映射关系,如果硬件没有足够的寄存器,dvm将多出来的寄存器映射到内存中。
2、全部的编译过程
五、尾声
1、本文没有在具体的写Dalvik和 ART的区别,有机会后续再补上,感兴趣的也可以自己搜索下。
2、后面会专门来写一写使用到的一些反编译工具
- 上一篇: 分享7个实用的“黑科技”网站,建议赶紧收藏起来!
- 下一篇: “耳机中的双子座”是“你的新AI助手”
猜你喜欢
- 2024-11-01 对一网诈APP的分析(反对网络诈骗)
- 2024-11-01 “耳机中的双子座”是“你的新AI助手”
- 2024-11-01 分享7个实用的“黑科技”网站,建议赶紧收藏起来!
- 2024-11-01 Android中热修复框架AndFix原理解析及案例使用
- 2024-11-01 2023级网络安全岗面试题及面试经验分享
- 2024-11-01 爬虫中的那些反爬虫措施以及解决方法
- 2024-11-01 Smali语法入门教程(smali基本语法)
- 2024-11-01 ROM制作与修改第五课:apk和odex的介绍和合并
- 2024-11-01 谷歌 Play代码破解:研发反侦测不受信任的追踪功能
- 2024-11-01 安卓Activity劫持与反劫持(安卓手机防劫持教程)
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- 电脑显示器花屏 (79)
- 403 forbidden (65)
- linux怎么查看系统版本 (54)
- 补码运算 (63)
- 缓存服务器 (61)
- 定时重启 (59)
- plsql developer (73)
- 对话框打开时命令无法执行 (61)
- excel数据透视表 (72)
- oracle认证 (56)
- 网页不能复制 (84)
- photoshop外挂滤镜 (58)
- 网页无法复制粘贴 (55)
- vmware workstation 7 1 3 (78)
- jdk 64位下载 (65)
- phpstudy 2013 (66)
- 卡通形象生成 (55)
- psd模板免费下载 (67)
- shift (58)
- localhost打不开 (58)
- 检测代理服务器设置 (55)
- frequency (66)
- indesign教程 (55)
- 运行命令大全 (61)
- ping exe (64)
本文暂时没有评论,来添加一个吧(●'◡'●)