Class文件、Dex文件、resources.arsc文件结构解读

Class文件解析

  1. class文件是能够被JVM识别,加载并在java虚拟机中执行的文件格式。.java通过编译器可以生成.class文件,具体来说通过javac命令编译得到,.class文件是二进制的形式,但是可以同过反编译得到类似java文件的形式,如图


    image.png
  2. 利用010Editor打开


    class文件十六进制代码
  • 可以看到,开头的是Cafebabe 用于快速判断一个文件是不是有可能为class文件,以及这个class文件有没有受损之后的每一个字节是何作用,知乎有篇博文解释的很棒,此处就不再ctrl C,crtl V了。只是要注意搭配这几张图食用会更佳:博客地址:https://zhuanlan.zhihu.com/p/23068093
    2.1. Class文件结构,其中u4代表四个字节,即八个十六进制位
    class文件结构

    2.2. 常量池的类型图
    注意到,像tag=1的常量字符串,长度是可变的,大小通过length字段决定。


    2.3. 各个字段的对应关系,就当目录了
常量池对应字段整理

2.4 当我自己javac 博文所讲的方法后,发现常量池中少了几个字段,为localvriable,this和第十三个常量。以下是我编译的类信息:


Foo

经过查阅得知:

LineNumberTable属性用于描述Java源码行号与字节码行号(字节码的偏移量)之间的对应关系。它并不是运行时必需的属性,但默认会生成到cass文件之中,在 Javac中使用none或-g;nes选项来取消或要求生成这项。如果选择不生成 LineNumberTable属性,对程序运行产生的最主要影响就是当抛出异常时,堆栈中将不会昰示出错的行号,并且在调试程序的时候,也无法按照源码行来设置断点

Dex文件解析

dex文件的十六进制代码

对比Class文件可以发现,在010editor中,dex文件多了dex.bt窗口,可以清晰的通过类比找到对应的十六进制数,而其具体的文件结构如下所示:

Dex文件的结构

dex文件的结构

下面将对各个部分进行解释

  1. Header包括:magicnumber、dex文件校验和、signature字段、文件大小、头部大小、指定cpu信息、linksize(链接段的大小)、linkoff(文件的偏移)、mapOff(DexMapList的文件偏移)、stringIdsSize 和 stringIdsOff字段(字符串的个数和位置偏移)、typeIdsSize和typeIdsOff(类的类型的数量和位置偏移)、protoIdsSize和protoIdsOff(dex文件中方法原型的个数和位置偏移)、fieldIdsSize和fieldIdsOff(字段名的信息)、methodIdsSize和methodIdsOff(方法所在的类、方法的声明以及方法名)、classDefsSize和classDefsOff(类的定义的相关信息)
  2. 各种Ids索引
  3. data: 数据真实存在的位置
  4. link_data: 静态链接 文件中使用的数据,用于指明上述信息存放的位置
    具体的内容参照这篇博客:https://www.jianshu.com/p/5658b5fd5806

特点:

当java程序编译成class后,还需要使用dx工具将所有的class文件整合到一个dex文件,目的是其中各个类能够共享数据,在一定程度上降低了冗余,同时也是文件结构更加经凑,实验表明,dex文件是传统jar文件大小的50%左右

Dex与Class的对比图

class文件和dex文件的解析

ps:一般来讲,一个应用程序都对应着一个.dex文件,就像openhub这样:


openhub解压

然而由于分包等原因,很多大型工程的.dex文件可以有多个,例如下图将微信apk解压:
微信apk解压

arsc文件解析

Resource.arsc是Apk打包过程中产生的一个资源索引文件,主要的作用为记录资源的id和文件路径的关系。

arsc文件的结构

资源文件的索引

在上篇博文https://www.jianshu.com/writer#/notebooks/32769734/notes/80776168中有讲到,R.java中存储了资源文件的索id,而arsc文件的作用则是保存实际的路径或资源值。例如getDrawable(R.drawable.img)在编译后成了getDrawable(0x7f06013c),其存储在R.java之中。其格式如下所示:

image.png

面试问题:

  1. 为什么dex拆分成多个?
    方法最多的个数是65536,超过了以后则分多个dex
  2. 如何根据id获取对应png的bitmap
  • 通过arsc将id 解析成对应的资源路径
  • 通过bitmapfactory将资源路径中的资源取出
    注(bitmap和drawable的关系,Drawable 是一个抽象的概念, 而 Bitmap 是其存在的实体之一)

你可能感兴趣的:(Class文件、Dex文件、resources.arsc文件结构解读)