Android使用MultiDex处理64K限制
来源:互联网 发布:20世纪90年代网络繁荣 编辑:程序博客网 时间:2024/05/15 19:17
随着Android平台的不断发展,Android应用的规模也越来越大。当你的程序以及程序所使用的库达到一定大小,build时可能会产生错误,这表示你的程序已经达到Android应用架构的极限。
老版本构建工具报错:
Conversion to Dalvik format failed:Unable to execute dex: method ID notin[0,0xffff]:65536
新版本构建工具报错:
trouble writing output : Too many field references : 131000 ;max is 65536. You may try using -- multi - dex option .
这两个错误都提到65535
,这个数字表示Dalvik字节码文件(也就是DEX文件)中可包含的方法的总数,因为Dalvik虚拟机中以short
类型来索引DEX文件中的方法。
如果你的应用出现了这个错误,首先恭喜你,你的应用肯定有很大的代码量。文章接下来就介绍如何解决该问题,让你的应用拥有更大的代码量和更丰富的功能。
在Android5.0之前平台中使用MultiDex
因为Android5.0之前的系统是使用Dalvik虚拟机来执行应用程序。默认情况下,Dalvik虚拟机将每个APK限制在单个classes.dex
字节码文件中。我们可以使用MultiDex支持库来解决单个Dex文件的限制。
MultiDex的原理:将MultiDex支持库的代码放在主Dex文件中,把超额的方法放在附加Dex文件中,MultiDex支持库负责管理附加Dex文件中的方法,主Dex的函数通过MultiDex支持库去间接调用附加Dex文件中的方法。
Android5.0及以上版本的MultiDex
Androd5.0之后使用了名为ART(Android Runtime)的运行时环境,它本身就支持“APK中包含多个dex文件”。
ART在应用安装时执行预编译,将Dalvik字节码翻译成本机二进制机器码从而加快应用执行速度:在预编译过程中会扫描dex文件,并将多个dex文件(dalvik字节码)编译成单个.oat
文件(二进制机器码)。关于ART的更多信息,可以参考Android官方文档。
解决65K限制的方法。
1. 避免64K问题——减少方法数
- 在程序中应尽量避免使用重量型的库,比如Google的Guava,Apache的Commons等。大多数JavaEE中的库都不适合在Android中使用。
- 使用ProGuard删除未使用的代码,保证应用的发布版本体积尽可能小巧。ProGuard的使用会在后面的文章中提到。
2. 配置MultiDex构建多dex应用
首先确保你使用的Build Tools是21.1及以上版本,因为这样才可以使用Gradle的安卓插件来支持multidex。
步骤如下:
更改Gradle配置以启用MultiDex,示例如下:
android { compileSdkVersion 21 buildToolsVersion "21.1.0" defaultConfig { ... minSdkVersion 14 targetSdkVersion 21 ... // 构建时生成多个dex multiDexEnabled true } ...}dependencies {// 添加MultiDex支持库的依赖compile 'com.android.support:multidex:1.0.0'}
multiDexEnabled
属性可以设置在defaultConfig
,buildType
或者productFlavor
中。修改应用清单以使用MultiDexApplication类
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.android.multidex.myapplication"> <application ... android:name="android.support.multidex.MultiDexApplication"> ... </application></manifest>
如果你的应用需要在Application中进行初始化,可以继承MultiDexApplication类。示例代码如下:
package cn.hff.App;import android.support.multidex.MultiDexApplication;// 集成MultiDexApplication类public class App extends MultiDexApplication{ @Override public void onCreate() { //initialize ... }}
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.android.multidex.myapplication"> <application ... android:name="cn.hff.App"> ... </application></manifest>
事实上MultiDexApplication源码很简单:
public class MultiDexApplication extends Application { public MultiDexApplication() { } protected void attachBaseContext(Context base) { super.attachBaseContext(base); MultiDex.install(this); }}
所以对于上面的
App
我们还可以这么写:package cn.hff.App;import android.app.Application;// 直接集成Application类public class App extends Application{ @Override public void onCreate() { //initialize ... } protected void attachBaseContext(Context base) { super.attachBaseContext(base); // 在应用中安装MultiDex支持库 MultiDex.install(this); }}
完成以上配置后,Android构建工具会根据需要将字节码文件打包成一个主Dex文件(classes.dex)和多个附加Dex文件(classes2.dex、classes3.dex…)。
开发过程中对MultiDex程序构建的优化
配置MultiDex后应用构建的时间明显增长,因为构建系统需要判断主Dex文件中应该包含哪些类、辅助Dex文件中应该包含哪些类,这个过程非常复杂。构建MultiDex应用于构建常规应用通常需要更多的时间,这可能会降低你的开发速度。
为了减短MultiDex应用的构建时间,我们可以在Gradle的productFlavors
属性中配置两种输出模式:开发模式和发行模式。
开发模式中我们可以将minSdkVersion
设置为21(也就是Android5.0),这样应用可以使用ART的格式,从而更快的生成MultiDex的Apk。
发行模式中我们可以将minSdkVersion
设置为应用实际需要兼容的最低SDK版本,这个设置可以兼容更低版本的Android平台,但相应地需要更长的构建时间。
一下是Gradle文件中相应的配置。
android { productFlavors { // 定义开发模式和发行模式 dev { // 开发模式设置 minSDKVersion = 21 从而允许Android Gradle插件预 // 先将每个模块打包成dex并生成一个可以在Android5.0上测试的APK文件, // 这样不需要在Dex合并上耗费过多的时间 minSdkVersion 21 } prod { // 应用实际需要兼容的最低SDK版本 minSdkVersion 14 } } ... buildTypes { release { // 发行版运行ProGuard对方法数进行压缩 runProguard true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } }}dependencies { compile 'com.android.support:multidex:1.0.0'}
参考文章:
Gradle插件用户指南:
- https://developer.android.com/studio/build/index.html
- https://developer.android.com/studio/build/multidex.html
- Android使用MultiDex处理64K限制
- Android应用使用Multidex突破64K方法数限制
- Android应用使用Multidex突破64K方法数限制
- Android 项目开发填坑记 - 使用 MultiDex 解决 64K 限制
- Android 项目开发填坑记 - 使用 MultiDex 解决 64K 限制
- Android应用使用Multidex突破64K方法数限制
- Android应用使用Multidex突破64K方法数限制
- Android应用使用Multidex突破64K方法数限制
- 使用MultiDex 解决64K限制
- android MultiDex配置突破64K方法数限制
- MultiDex解决64K限制的问题
- Android MultiDex 解决 64K 限制,方法数超过65535解决方法
- Android Studio Multidex 解决方法数超65k限制
- Android Studio Multidex 解决方法数超65k限制
- Android MultiDex使用
- 使用MultiDex解决65535限制问题
- Android 使用android-support-multidex解决Dex超出方法数的限制问题
- Android 使用android-support-multidex解决Dex超出方法数的限制问题
- Ubuntu下安装并配置maven
- 1. Steps to set up java web project with IDEA
- 第二次MySQL与Jsp学习笔记
- com.android.volley.toolbox.DiskBasedCache.streamToBytes异常
- POSIX 条件变量
- Android使用MultiDex处理64K限制
- Linux下crond、crontab命令
- docker容器间网络通信
- 学习笔记:复习单调队列
- linux下的select简直太奇葩了:1024限定的不只是监听的个数,还是文件描述符的最大值,注意,是值
- Java经典算法40例(一)
- 匿名内部类
- spring profile激活处理
- Docker 安装配置 in Ubuntu