插件化开发之-gradle分包
来源:互联网 发布:rsyslog linux 编辑:程序博客网 时间:2024/05/29 11:40
插件化开发的由来
android5.0之前,dalvik采用了一个short型数据来表示一个dex所含有的方法数个数,而short类型最大值为65535,因此方法数最大为65535.随着项目的不断增大,当项目中的方法数超过dalvik所能识别的最大方法数时,编译就会失败,为了解决这个问题,插件化开发就诞生了。
何为分包?
以下是没有进行分包的apk目录:
可以看到普通的apk目录中只含有一个classes.dex文件,这里面是项目的java代码部分。而之所以出现65535问题,其实就是因为classes.dex文件中的方法数过多,因此通过分包可以将一个classes.dex文件拆分为多个dex文件。
通过gradle分包之后:
通过gradle分包之后就会将classes.dex拆分为多个dex文件。
gradle分包流程
- 在build.gradle文件中加入依赖:
compile 'com.android.support:multidex:1.0.1'(它有两个版本)
在build.gradle中加入:` defaultConfig {
applicationId “com.testandroid”
minSdkVersion 19
targetSdkVersion 25
versionCode 1
versionName “1.0”*multiDexEnabled true*;//设置分包
}`
3.自定义一个Application,在attachBaseContext()中加入:
protected void attachBaseContext(Context base) { super.attachBaseContext(base); MultiDex.install(this); }
或者将自定义Application直接继承MultiDexApplication;也或者不需要自定义Application,直接在配置文件中将设置:
<application android:name="android.support.multidex.MultiDexApplication" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" >
完成这四部,然后编译,就可以实现分包了。
android类加载机制
首先我们要知道android中类加载的机制,不同于java加载类,android中加载类主要类加载器及其结构关系如下:
图1:
类加载主要涉及到三个类加载器:BootClassLoader、DexClassLoader、PathClassLoader.
- BootClassLoader:最顶级类加载器,由c++实现,跟java中的BootStrapClassLoader类似。
- DexClassLoader : 加载路径需要在创建DexClassLoader时传入,也就是加载任何路径下的apk/dex/jar(即未安装的apk文件)
- PathClassLoader : 加载/data/app目录下的apk文件,也就是加载已经安装好了的apk
android类加载器加载流程:加载一个类时,首先由PathClassLoader类加载器来加载,然后它会委托给它的父加载器BootClassLoader来加载,如果BootClassLoader没有找到加载对象,那么就由PathClassLoader来加载,如果它也没有找到家在对象,就会报出异常。
MultiDex动态加载分dex
上面我们知道通过分包后dex文件被拆分为多个dex,因此分包后主dex如何加载分dex中的文件是个问题,这里就是分包后的关键-动态加载分dex。
androidstudio通过gradle分包后,动态加载分dex主要依赖google提供的Multidex,它是android4.4之后引入的一个专门用来实现动态加载dex的。
查看图1我们知道:BaseDexClassLoader维护了一个pathList,它是一个DexPathList类型。BaseDexClassLoader.findClass()方法调用了pathList.findClass(),而DexPathList里面维护了一个Element[] dexElements,它存储了dex文件。再看pathList.findClass(),它里面遍历加载了dexElements。因此BaseDexClassLoader其实就是加载了dexElements。又因为PathClassLoader和DexClassLoader都是BaseClassLoader的子类,因此他们的findClass()其实都是在加载dexElements。所以 可以通过将DexClassLoader的加载路径加入到PathClassLoader中去,实现动态加载多个分dex。
而MultiDex的实现原理就是依照这个思路:首先通过反射得到pathList这个字段,然后通过get方法获取到pathList,然后继续通过反射得到dexElements属性,将dexElemnts路径用object[]存起来,最后将DexClassLoader的object[]合并到PathClassLoader的object[]中去。这样就实现了将DexClassLoader的加载路径加到PathClassLoader加载路径中去,因为DexClassLoader可以加载到分dex文件,因此当PathClassLoader尝试去加载时,就会加载到分dex。
- 插件化开发之-gradle分包
- 插件化开发之-Ant分包
- Android 指定Dex分包的Gradle插件
- 插件化系列开发之八--replugin源码解析之replugin-plugin-gradle(插件的gradle插件)
- 插件化系列开发之七--replugin源码解析之replugin-host-gradle(宿主的gradle插件)
- Gradle 插件开发
- gradle插件开发
- gradle 分包管理layout
- gradle之ssh插件
- 关于 Android中的插件化开发,dex分包,热修复(Tinker)的思考(一)
- 关于 Android中的插件化开发,dex分包,热修复(Tinker)的思考(二)
- 拥抱 Android Studio 之五:Gradle 插件开发
- 拥抱 Android Studio 之五:Gradle 插件开发
- Gradle构建之自定义Gradle插件
- Android Studio Gradle 插件开发
- AndroidStudio下开发gradle插件
- Android layout用 gradle分包
- Gradle之java插件入门
- python中yield的用法
- EntityFramework Model有外键时,Json提示循环引用 解决方法
- letcode278[easy]--First Bad Version
- 时间复杂度的计算问题
- 洛谷P3391
- 插件化开发之-gradle分包
- 案例-小球自由落体运动
- 算法——跳跃搜索
- 全排列生成的迭代算法
- JAVA CAS原理深度分析
- Linux基础-0002-linux特殊权限
- PLA1.2被拒 Guideline5.2.1被拒 马甲包被拒
- get到一篇关于Sublime text3 的好文章,安利一下
- ES 在HIVE中创建表存储数据