【Android热修复与插件化 二】class&dex文件详解

一. class文件结构深入解析(生成&执行&内部结构)

1. 如何生成一个class文件?

class文件是能够被JVM识别,加载并执行的文件格式。说白了,它就是一种文件格式,就像mp4、jpg、txt等文件格式一样。
只有java源代码能编译成class文件吗?
下图几种语言也能编译成class文件。

2. 如何生成一个class文件?

一般来说,有两种方式生成class文件:

  • IDE会自动帮我们build出class文件
  • 手动通过javac去生成class文件(IDE也是通过javac生成的)

3. class文件的作用

记录一个类文件的所有信息。

4. class文件格式详解(重点)

  • 一种8位字节的二进制流文件(与音视频文件一样)
  • 各个数据按顺序紧密的排列,无间隙(不像有些文件,为了读取上的方便,会做一些填充,比如每80字节是一行)
  • 每个类、枚举、接口都单独占据一个class文件

下面我们来讲解一下class文件结构
这里写图片描述
我们逐行来讲解每个字段的作用。

  • magic字段。它是无符号4字节类型。它的作用是一个摘要段,好比文件的md5加密,用来判断class文件是否有被篡改。
  • minor_version字段。它指明class文件最早可以支持的jdk版本。
  • major_version字段。表示当前class文件是由那个jdk版本生成的。
  • constant_pool_count字段。表示class文件中常量池的数量,通常来说,只有一个常量池。
  • constant_pool字段[核心]。这个字段代表真正的常量池,它是cp_info类型。也就是说,是一个结构体类型。constant_pool的取值范围如下:
    CONSTANT_Integer_info:int类型
    CONSTANT_Long_info:long类型
    CONSTANT_String_info:String类型
    CONSTANT_Class_info:类相关信息
    CONSTANT_Fieldref_info:类中成员变量相关信息
    CONSTANT_Methodref_info:类中方法相关信息

  • access_flag字段。表示class文件的作用域,比如public,private等。如下图,access_flags可以取如下值。
    这里写图片描述

  • this_class字段。在java源文件中没有定义this关键字,而jdk在生成class文件时补充了这个字段。
  • super_class字段。跟this_class原理类似。
  • interfaces_count字段。表明当前class文件实现了多少个接口,且只会记录直接实现的接口数量。
  • interfaces字段。表明当前class文件直接实现的接口数量。
  • fields_count字段。表明当前class文件所有成员变量个数。
  • fields字段。是field_info类型。表明成员变量类型、名称等。记录当前class文件所有成员变量。
  • methods_count字段。
  • methods字段。
  • attribute_count字段。属性个数。
  • attributes字段。

5. class文件弊端

  • 内存占用大,不适合移动端
  • 堆栈的加栈模式,加载速度慢
  • 文件IO操作多,类查找慢

二. dex文件结构深入解析(生成&执行&内部结构)

1. 什么是dex文件?

能够被DVM识别,加载并执行的文件格式

2. 如何生成一个dex文件?

  • 通过IDE自动build生成
  • 手动通过dx命令生成dex文件

那么,如何用dx命令生成dex文件,并在手机上运行呢?

  1. 找到 sdk目录/build-tools/sdk版本,如我的路径:
    /Users/colinambitious/Library/Android/sdk/build-tools/26.0.22.
    在此文件夹下可以找到dx文件,将此目录设为环境变量。
  2. 写一个Test.java文件

    public class Test{
    public static void main(String args[]){
        System.out.println("Hello World.");
    }
    }
  3. 使用以下命令,编译成class文件:
    javac -target 1.6 -source 1.6 Test.java

  4. 使用adb命令,将生成的class文件push到手机上
    adb push Test.dex /storage/emulated/0
  5. 使用adb shell命令,远程连接到手机
    adb shell
  6. 运行该dex文件
    dalvikvm -cp ./Test.dex Test

3. dex文件的作用

记录整个工程中所有类文件的信息,

4. dex文件格式详解(重点)

  • 一种8字节的二进制流文件
  • 各个数据按顺序紧密排列,无间隙
  • 整个应用所有java源文件都在一个dex中

我们来结合下面这张图来讲解。
这里写图片描述
dex文件总共有三个部分:文件头、索引区、数据区。

  • 文件头header。主要记录了dex文件信息。
  • 索引区。包含了字符串索引、类型索引、方法原型索引、域索引、方法索引。
  • 数据区。包含了索引区索引的内容。

三. class文件与dex文件对比

  • 本质上class文件和dex文件都是一样的(java源文件演变而来),而dex文件又是从class文件演变而来的。
  • class文件存在许多冗余信息,dex去除冗余。因为,class文件一个类就有一个常量池,dex文件中所有数据都是存储在同一个数据区的。

从下面这张图可以看出,jar包中每一个class都有header、constant pool等,而dex把这些所有class的信息整合到了一起。
这里写图片描述

猜你喜欢

转载自blog.csdn.net/colinandroid/article/details/80648636
今日推荐