关于 Android中的插件化开发,dex分包,热修复(Tinker)的思考(二)

编程入门 行业动态 更新时间:2024-10-07 12:24:27

关于 Android中的<a href=https://www.elefans.com/category/jswz/34/1771202.html style=插件化开发,dex分包,热修复(Tinker)的思考(二)"/>

关于 Android中的插件化开发,dex分包,热修复(Tinker)的思考(二)

插件化开发的主要原理就是动态加载技术。上文已经对动态加载DexClassLoader进行了解析今天要讲的是动态加载技术的亲戚 —— MultiDex。他们的核心原理之一都是dex文件的加载。

先来理解概念
MultiDex

MultiDex是Google为了解决“65535方法数超标”以及“INSTALL_FAILED_DEXOPT”问题而开发的一个Support库 这篇博客主要是配合源码分析MultiDex的工作原理,使用方法,以及提供一些MultiDex优化的方案。

实现:
1、通过反射获取PathClassLoader中的DexPathList中的Element数组(已加载了第一个dex包,由系统加载)
2、通过反射获取DexClassLoader中的DexPathList中的Element数组(将第二个dex包加载进去)
3、将两个Element数组合并之后,再将其赋值给PathClassLoader的Element数组
谷歌提供的MultiDex支持库就是按照这个思路来实现的。下面看具体原理。

前言:Dex的工作机制

Android程序的每一个Class都是由ClassLoader#loadClass方法加载进内存的,更准确来说,一个ClassLoader实例会有一个或者多个DexFile实例,调用了ClassLoader#loadClass之后,ClassLoader会通过类名,在自己的DexFile数组里面查找有没有那个DexFile对象里面存在这个类,如果都没有就抛ClassNotFound异常。ClassLoader通过调用DexFile的一个叫defineClass的Native方法去加载指定的类,这点与JVM略有不同,后者是直接调用ClassLoader#defineCLass方法,反正最后实际加载类的方法都叫defineClass就没错了。
我们知道ClassLoader主要是通过DexFile.loadDex这个静态方法来创建它需要的DexFile实例的,这里创建DexFile的时候,保存了Dex文件的文件路径mFileName,同时调用了openDexFile的Native方法打开Dex文件并返回了一个mCookie的整型变量(我不知道这个干啥用的,我猜它是一个C++用的资源句柄,用于Native层访问具体的Dex文件)。在Native层的openDexFile方法里,主要做了检查当前创建来的Dex文件是否是有效的Dex文件,还是是一个带有Dex文件的压缩包,还是一个无效的Dex文件。
加载Dex文件里的类

加载类的时候,ClassLoader又是通过DexFile#loadClass这个方法来完成的,这个方法里调用了defineClass这个Native方法,看来DexFile才是加载Class的具体API,加载Dex文件和加载具体Class都是通过Native方法完成,ClassLoader有点名不副实。
MultiDex的工作机制

当一个Dex文件太肥的时候(方法数目太多、文件太大),在打包Apk文件的时候就会出问题,就算打包的时候不出问题,在Android 5.0以下设备上安装或运行Apk也会出问题。既然一个Dex文件不行的话,那就把这个硕大的Dex文件拆分成若干个小的Dex文件,刚好一个ClassLoader可以有多个DexFile,这就是MultiDex的基本设计思路。

使用dx进行拆包
这里还有两个两类:一个是自动拆包,一个手动拆包
–multi-dex:多 dex 打包的开关
–main-dex-list=:参数是一个类列表的文件,在该文件中的类会被打包在第一个 dex 中
–minimal-main-dex:只有在–main-dex-list 文件中指定的类被打包在第一个 dex,其余的都在第二个 dex 文件中

打包过程中如何产生多个的DEX包?
如果做到动态加载,怎么决定哪些DEX动态加载呢?
如果启动后在工作线程中做动态加载,如果没有加载完而用户进行页面操作需要使用到动态加载DEX中的class怎么办?
以上疑问,下方链接有解释。
.html
.html
工作流程

MultiDex的工作流程具体分为两个部分,一个部分是打包构建Apk的时候,将Dex文件拆分成若干个小的Dex文件,这个Android Studio已经帮我们做了(设置 “multiDexEnabled true”),另一部分就是在启动Apk的时候,同时加载多个Dex文件(具体是加载Dex文件优化后的Odex文件,不过文件名还是.dex),这一部分工作从Android 5.0开始系统已经帮我们做了,但是在Android 5.0以前还是需要通过MultiDex Support库来支持(MultiDex.install(Context))。
注意:就是Android中在分包之后会有多个dex,但是系统默认会先找到classes.dex文件然后自动加载运行,所以这里就有一个问题,我们需要将一些初始化的重要类放到classes.dex中,不然运行就会报错或者闪退。

首先来看看使用:
1、修改Gradle的配置,支持multidex:

android {compileSdkVersion <

更多推荐

关于 Android中的插件化开发,dex分包,热修复(Tinker)的思考(二)

本文发布于:2024-03-04 11:06:59,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1709101.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:插件   Android   Tinker   dex

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!