热修复&插件化(一)-class & dex

作者: Stan_Z | 来源:发表于2019-08-09 22:00 被阅读33次

    这个周末打算开个新系列,总结下热修复与插件化相关知识点,framework做久了,app也不能丢。

    开篇文章先打个基础,针对class文件以及dex文件做个简单对比。

    一、什么是class 、dex

    class: jvm识别、加载并执行的文件格式。
    dex: 能被dvm、art识别、加载并执行的文件格式。

    二、如何生成并执行class 、dex

    class的生成与执行:
    jdk命令
    编译生成Hello.class文件 javac Hello.java
    执行Hello.class文件 java Hello

    dex的生成与执行:
    android sdk命令
    先通过javac生成.class文件
    然后生成dex文件 dex -dex -output hello.dex(生成文件) hello.class(源文件)
    文件push到手机 adb push hello.dex /storage/emulated/0
    执行adb shell dalvikvm -cp /sdcard/hello.dex hello(执行哪个class)

    三、class、dex文件结构解析

    class文件:

    8位字节的二进制流文件,各个数据紧密排列无间隙,每个类或接口都是单独的class。

    字段表:

    类型 描述 备注
    u4 magic 魔数:0xCAFEBABE
    u2 minor_version 小版本号
    u2 major_version 主版本号
    u2 constant_pool_count 常量池大小,从1开始
    cp_info constant_pool[constant_pool_count - 1] 常量池信息
    u2 access_flags 访问标志
    u2 this_class 类索引
    u2 super_class 父类索引
    u2 interfaces_count 接口个数
    u2 interfaces[interfaces_count] 接口类索引信息
    u2 fields_count 字段数
    field_info fields[fields_count] 字段表信息
    u2 methods_count 方法数
    method_info methods[methods_count] 方法表信息
    u2 attributes_count 属性个数
    attribute_info attributes[attributes_count] 属性表信息

    数据项的不同长度分别用u1, u2, u4, u8表示, 分别表示一种数据项在class文件中占据一个字节, 两个字节, 4个字节和8个字节。

    010 Editor 工具 查看class文件

    class文件弊端:内存占用大;堆栈的加栈模式,加载速度慢;文件io操作多,类加载查找慢等。因此不适合移动端。

    dex文件:

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

    链接数据区 动态库

    数据名称 解释
    header dex文件头部,记录整个dex文件的相关属性
    string_ids 字符串数据索引,记录了每个字符串在数据区的偏移量
    type_ids 类似数据索引,记录了每个类型的字符串索引
    proto_ids 原型数据索引,记录了方法声明的字符串,返回类型字符串,参数列表
    field_ids 字段数据索引,记录了所属类,类型以及方法名
    method_ids 类方法索引,记录方法所属类名,方法声明以及方法名等信息
    class_defs 类定义数据索引,记录指定类各类信息,包括接口,超类,类数据偏移量
    data 数据区,保存了各个类的真是数据
    link_data 连接数据区

    其中head记录了dex文件的一些基本信息,以及大致的数据分布:

    字段名称 偏移值 长度 说明
    magic 0x0 8 魔数字段,值为"dex\n035\0"
    checksum 0x8 4 校验码
    signature 0xc 20 sha-1签名
    file_size 0x20 4 dex文件总长度
    header_size 0x24 4 文件头长度,009版本=0x5c,035版本=0x70
    endian_tag 0x28 4 标示字节顺序的常量
    link_size 0x2c 4 链接段的大小,如果为0就是静态链接
    link_off 0x30 4 链接段的开始位置
    map_off 0x34 4 map数据基址
    string_ids_size 0x38 4 字符串列表中字符串个数
    string_ids_off 0x3c 4 字符串列表基址
    type_ids_size 0x40 4 类列表里的类型个数
    type_ids_off 0x44 4 类列表基址
    proto_ids_size 0x48 4 原型列表里面的原型个数
    proto_ids_off 0x4c 4 原型列表基址
    field_ids_size 0x50 4 字段个数
    field_ids_off 0x54 4 字段列表基址
    method_ids_size 0x58 4 方法个数
    method_ids_off 0x5c 4 方法列表基址
    class_defs_size 0x60 4 类定义标中类的个数
    class_defs_off 0x64 4 类定义列表基址
    data_size 0x68 4 数据段的大小,必须4k对齐
    data_off 0x6c 4 数据段基址

    010 Editor 工具 查看dex文件

    dex:区域复用。data数据区对应value。

    class 与dex对比:
    本质都是虚拟机执行文件,dex从class演变的,以适应移动端。
    class存在区域冗余(一个class一个常量池),dex去除冗余并整合,极大减少执行文件体积。


    相关文章

      网友评论

        本文标题:热修复&插件化(一)-class & dex

        本文链接:https://www.haomeiwen.com/subject/oomkjctx.html