博客
关于我
MultiDex从基础原理到实践优化
阅读量:790 次
发布时间:2019-03-24

本文共 1428 字,大约阅读时间需要 4 分钟。

Android MultiDex技术深度解析

背景知识

Class文件与Dex文件

Android系统将类文件(jar或apk)进行压缩和优化,生成dex文件。dex文件的核心优势在于去除了传统Class文件的冗余信息,适合移动设备的执行环境。

Android系统支持两种虚拟机:Dalvik VM和ART VM。在Android4.4及以上版本,ART VM采用预编译机制,而Dalvik VM则采用即时编译。从Android5.0开始,MultiDex技术正式支持在应用中使用多个dex文件。

方法数超限问题与解决思路

MultiDex技术的主要目的就是解决类数量有限导致的方法数超限问题。默认情况下,只能生成一个dex文件,无法处理包含大量类和方法的应用程序。

基本用法

与版本相关的使用

  • Android5.0及以上:通过多个dex文件实现类方法的加载,符合系统优化要求。从Android5.0开始,系统自动支持MultiDex,但需要自定义Application类并在attachBaseContext方法中手动安装。

  • Android5.0之前:需要自行处理MultiDex安装,主要通过反射操作PathClassLoader的pathList字段,将多个dex文件整合到类加载器中。

原理解析

编译期原理

  • Java文件通过javac编译生成Class文件。

  • Dex工具将多个Class文件压缩和优化,生成dex文件。从Android5.0开始,支持多dex文件处理。

  • 运行期原理

    • Dalvik VM:运行时将dex文件解压到特定目录,并从中逐个加载需要的类。

    • ART VM:系统层面优化了Dex文件的处理,所有DEX文件预先编译为oat文件,提升运行效率。

    运行期详细流程

  • Dex文件解压:APK中的dex文件解压到data/data目录。

  • Dex安装:通过反射操作PathClassLoader的pathList字段,将所有需要的dex文件添加到ClassLoader的元素列表中。

  • 进阶实践

    代码热修复

    • 生成补丁包:通过javac和dx工具生成补丁dex文件。核心步骤包括编译源代码及参考库文件,并将得到的Class文件生成patch.dex。

    • 运行时注入补丁:通过自定义的反射工具类,获取ClassLoader的pathList字段,将补丁包 dex文件注入到ClassLoader的元素列表中,优先级高于原有 dex文件。

    示例代码实现

  • 创建待修复类ToBeFixed.java。

  • 编写反射工具类ReflectUtil.java,用于获取Class字段和方法。

  • 实现HotFixManager.java,负责运行时注入补丁包。主要操作包括获取手机的外部存储目录,获取ClassLoader的pathList字段,通过反射获取并添加额外的 dex文件元素。

  • 自定义App.java,继承自Application类,并在attachBaseContext方法中调用HotFixManager.installFixedDex()。

  • 高级优化

    MultiDex相关问题及优化

  • 解决ANR问题:优化Dex解压与dexopt的运行流程,使其在短时间内完成,避免阻塞主线程。

  • 打申弃:通过减少 dex文件数量和优化 dex文件结构,提升应用启动速度和性能。

  • 通过上述技术架构和实现,能够高效解决类和方法数量限制,实现代码热修复和性能优化,提升用户体验。

    转载地址:http://kikuk.baihongyu.com/

    你可能感兴趣的文章
    mysql select, from ,join ,on ,where groupby,having ,order by limit的执行顺序和书写顺序
    查看>>
    MySQL Server 5.5安装记录
    查看>>
    mysql server has gone away
    查看>>
    mysql slave 停了_slave 停止。求解决方法
    查看>>
    MySQL SQL 优化指南:主键、ORDER BY、GROUP BY 和 UPDATE 优化详解
    查看>>
    MYSQL sql语句针对数据记录时间范围查询的效率对比
    查看>>
    mysql sum 没返回,如果没有找到任何值,我如何在MySQL中获得SUM函数以返回'0'?
    查看>>
    mysql Timestamp时间隔了8小时
    查看>>
    Mysql tinyint(1)与tinyint(4)的区别
    查看>>
    mysql union orderby 无效
    查看>>
    mysql v$session_Oracle 进程查看v$session
    查看>>
    mysql where中如何判断不为空
    查看>>
    MySQL Workbench 使用手册:从入门到精通
    查看>>
    mysql workbench6.3.5_MySQL Workbench
    查看>>
    MySQL Workbench安装教程以及菜单汉化
    查看>>
    MySQL Xtrabackup 安装、备份、恢复
    查看>>
    mysql [Err] 1436 - Thread stack overrun: 129464 bytes used of a 286720 byte stack, and 160000 bytes
    查看>>
    MySQL _ MySQL常用操作
    查看>>
    MySQL – 导出数据成csv
    查看>>
    MySQL —— 在CentOS9下安装MySQL
    查看>>