MultiDex的介绍和配置并提高构建效率
来源:互联网 发布:免费推广软件 编辑:程序博客网 时间:2024/04/29 22:16
MultiDex
最近优化升级项目,终于报了64K方法限制数的问题,顺便记录一下解决的方案;
64K限制的原因
Android APK文件本质是一个压缩文件,它里面包含了classes.dex文件是可执行的Dalvik(安卓虚拟机)字节码文件,这个 .dex文件中存放的是所有编译后的Java代码。Dalvik可执行文件规范限制了单个dex文件最多能饮用的方法数是65536个,其中还包含了Android Framework、APP引用的第三方函数库以及自身的方法(感觉这是个设计的失误);
使用 MultiDex解决64K限制
Android5.0之前
在5.0之前,系统使用的是Dalvik虚拟机来执行Android应用,Dalvik为每个APK只生成一个dex文件,为了避免超过64K的限制,我们只能将一个dex拆分成若干个dex,类似于classes.dex,classes2.dex,classes3.dex,应用启动后,程序会先加载主dex,然后依次加在其他的dex;Google推出了一个名为MultiDex Support Library的函数库,可以在 /extras/android/support/mulidex/下找到这个库;
Android5.0之后
5.0之后系统开始使用ART的虚拟机来代替Dalvik的虚拟机,ART天然支持APK加载多个dex文件,它可以直接扫描所有的dex文件并将他们编译成一个oat文件,引用直接加载oat而并非去一个一个加载dex文件;
使用 MultiDex配置
MultiDex的配置主要是在Gradle文件中进行的,但是不仅需要配置Module中的Gradle文件,还需要配置项目根目录下的Gradle文件。
首先,我们先来配置Module中的Gradle文件,文件中的代码如下:
apply plugin: 'com.android.application'android { // productFlavors是为了避免每次运行都把DEX重新加载一遍而设置的两套运行配置 productFlavors { dev { minSdkVersion 21 } prod { minSdkVersion 14 } } compileSdkVersion 24 buildToolsVersion "24.0.2" defaultConfig { applicationId "com.example.itgungnir.testmultidex" minSdkVersion 11 targetSdkVersion 24 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" // 设置MultiDex可用 multiDexEnabled true } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } // 保证其他的lib没有被preDex dexOptions { preDexLibraries = false }}dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) compile 'com.android.support:appcompat-v7:24.2.1' testCompile 'junit:junit:4.12' // MultiDex的依赖 compile 'com.android.support:multidex:1.0.1'}
配置完Module下的Gradle文件,接下来配置Project下的Gradle文件。文件中的代码如下:
buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:2.2.0' }}allprojects { repositories { jcenter() }}task clean(type: Delete) { delete rootProject.buildDir}// 保证dex_files文件中指定的文件都加载到Main Dex中afterEvaluate { tasks.matching { it.name.startsWith('dex') }.each { dx -> if (dx.additionalParameters == null) { dx.additionalParameters = [] } dx.additionalParameters += '--multi-dex' dx.additionalParameters += "--main-dex-list=$projectDir/dex_files".toString() }}
可以看到,这里主要添加了afterEvaluate代码块,最后一行中的dex_files是一个.txt文件,其中存放着想要默认加载到MainDex中的所有文件。这个dex_files文件是和这个Gradle文件在同一级目录下,以下是dex_files.txt文件中的代码(大家可以根据需要添加):
android/support/multidex/BuildConfig/classandroid/support/multidex/MultiDex$V14/classandroid/support/multidex/MultiDex$V19/classandroid/support/multidex/MultiDex$V4/classandroid/support/multidex/MultiDex/classandroid/support/multidex/MultiDexApplication/classandroid/support/multidex/MultiDexExtractor$1/classandroid/support/multidex/MultiDexExtractor/classandroid/support/multidex/ZipUtil$CentralDirectory/classandroid/support/multidex/ZipUtil/class
最后,需要在项目的Application文件中注入MultiDex,代码如下:
public class MyApplication extends Application { @Override public void onCreate() { super.onCreate(); } @Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); // 将MultiDex注入到项目中 // attachBaseContext的方法是在onCreate之前执行的。是开发者可以控制应用最早执行的方法 MultiDex.install(this); }}
最后记得在Manifest中配置Application
提高构建效率
在项目中加入MultiDex后,你点了构建按钮后,发现速度大不如从前;如果是超大型的应用,那速度可想而知;为了减少开发阶段由于倒入MultiDex所增加的构建时间,我们可以在工程的主模块build.gradle文件中使用productFlavors来构建两个flavor,一个开发用一个生产用;
android{ productFlavors{ dev{ //开发阶段的嘴笑版本 minSdkVersion 21 } prod{ //app实际的最小版本 minSdkVersion 14 } }}
上面的配置完成以后,可以使用devDebug variant来构建我们的应用,他会结合dev的productFlavor和debug的buildType的配置,也就是最终生成的APK不会使用ProGuard;
接下来我们介绍如何使用devDebug这个Build Variant,可以使用命令行:
./gradlew installDevDebug
在Android Studio中,点击右侧的Build Variant,可以打开对应的module中选择devDebug即可
- MultiDex的介绍和配置并提高构建效率
- 如何正确学习并提高学习效率?
- MultiDex精补篇,进一步知道MultiDex的配置
- MultiDex的配置
- 65535--MultiDex的配置
- 一种减轻服务器负担并提高客户端间通讯效率的网络通讯设计[TCP/UDP合用] | 简单加密
- Jenkins配置自动构建项目并提交到转测的svn服务器
- ++i 和 --i 谁的效率高 ?
- Android MultiDex 构建优化
- 【Android - 进阶】之MultiDex的配置
- 构建百万级高性能Web网站---1 CentOS的安装和网络配置
- 详细介绍构建高性能J2EE应用的十个技巧
- 25种改善网站并提高浏览量的方法
- 如何准确的计算并提高APP用户留存?
- union 和 union all的区别,如个效率高
- 效率很高的url-encode和url-decode函数
- SQL优化--Exists和in的效率哪个高
- SQL优化--Exists和in的效率哪个高
- 周鸿祎谈创业:很多程序员智商都高得很,但我一看就知道他们不会创业成功
- jQuery动态修改html
- 安卓沉浸式状态栏
- 【Unity Shader】浅析Unity shader中RenderType的作用及_CameraDepthNormalsTexture
- jquery插件——cookie
- MultiDex的介绍和配置并提高构建效率
- android5.1源码中预制so和jar包
- java8-lambda操作数组、集合
- Qt 多页面切换stacked widget控件
- cmake和make区别
- 118. Pascal's Triangle
- 域用户计算机不允许使用保存的凭据登录远
- 手把手教你android studio terminal 命令获取SHA1和MD5、SHA256值
- hibernate技术之is not mapped 错误解决方案