Android(安卓)MultiDex 解析与使用
Android MultiDex 解析与使用
背景
随着你的Apk不断的迭代更新,到你的apk到达一定大小的时候,你在编译apk的时候可能会出现下面的错误:
Conversion to Dalvik format failed:Unable to execute dex: method ID not in [0, 0xffff]: 65536
最近的apk编译出现的错误日志如下:
trouble writing output:Too many field references: 131000; max is 65536.You may try using --multi-dex option.
这个编译错误产生的主要原因是因为每个DEX文件中方法数是以一个short类型结构保存,这样就限制了每个DEX的方法数大小。
Dex主要组成:
- Android FrameWork 方法数
- Lib 方法数
- 你自己写的代码方法数
解决方法:
Android5.0以下:
由于Android5.0以下使用的是Dalvik虚拟机,Dalvik虚拟机在Apk运行的时候去load Dex文件,所以我们可以使用Google提供的multiDex的那个jar包进行分包和合包,在Apk启动的时候进行多dex合包过程。Android5.0以上:
Android5.0以上我们默认是实用ART虚拟机,ART虚拟机是直接支持Dex合包生成.oat文件,在apk启动后直接加在oat文件。
MultiDex使用
- 如果你的APk的minSdk是21或者更高,这个时候你只要在build.gradle中进行如下配置:
android { defaultConfig { ... minSdkVersion 21 targetSdkVersion 25 multiDexEnabled true } ...}
- 如果你的APK的minSdk是20及以下,这个时候就要使用multidex support library ,具体配置如下:
android { defaultConfig { ... minSdkVersion 15 targetSdkVersion 25 multiDexEnabled true } ...}dependencies { compile 'com.android.support:multidex:1.0.1'}
重写或者配置Application:
1. 当你没有重写Application的时候,你要在AndroidManifest.xml中进行如下配置:
<?xml version="1.0" encoding="utf-8"?>"http://schemas.android.com/apk/res/android" package="com.example.myapp"> "android.support.multidex.MultiDexApplication" > ...
2.如果你重写了Application,你可以直接用继承MultiDexApplication,具体如下所示:
public class MyApplication extends MultiDexApplication { ... }
也可以不继承MultiDexApplication,直接在Application的初始化中对MultiDex进行初始化
public class MyApplication extends SomeOtherApplication { @Override protected void attachBaseContext(Context base) { super.attachBaseContext(context); Multidex.install(this); }}
上面几个步骤完成了MultiDex的初始化,接下来要完成分包dex的配置
我们可以动态的配置哪些文件加在到第一个dex文件中,具体配置如下:
- 首先我们创建一个文件,在这个文件中配置mainDex中包含的java文件:
- 然后再在build.gradle中配置一下:
com/example/MyClass.classcom/example/MyOtherClass.class
android { buildTypes { release { multiDexKeepFile file('dex.keep') ... } }}
以上就完成了MultiDex的配置工作了,现在65535的问题就基本解决了。
总结
目前我们解决65535主要有如下方法:
1. 缩减代码,减小apk大小,这是治标不治本的方法。
2. 使用多Dex技术,这个技术导致冷加载时常变长,有的时候还会出现一些的崩溃
更多相关文章
- Android实用插件,持续更新
- PackageInstaller 原理简述
- Android(安卓)- JNI加入标准C++文件
- 使用ARouter 时 提示 There is no route matched
- 使用内部(com.android.internal)和隐藏(@hide)API手记
- Android如何将程序打成jar包
- Android(安卓)Studio下OpenCV及JNI开发
- Android缓存机制&一个缓存框架推荐
- Android(安卓)ANR介绍及分析ANR log信息的方法