1.什么是64K方法引用的限制

   65536(64K)是单个dex(Dalvik Executable)字节码文件的可引用的方法数的最大数,包括Android framework、应用的library和自己的方法。解决这个限制的方法就是使Apk编译创建和使用多个dex字节码文件在一个Apk文件中。

2.配置工程可以multidex

    Android5.0之前的multidex设置

      Android5.0(API 21)之前的版本使用Dalvik runtime虚拟机执行App代码,默认情况下,Dalvik限制每个Apk文件只有一个dex字节码文件。通过以下配置可以达到multidex的目的:
        1.添加以下依赖,该依赖的library会包含在primary dex 文件中,且管理对其他dex文件及其代码

dependencies {
compile 'com.android.support:multidex:1.0.1'
}

        2.设置multiDexEnabled为true

defaultConfig {
...
minSdkVersion 21
targetSdkVersion 26
multiDexEnabled true
}

        3.配置Applicaiton,视情况选择以下三种之一

         如果你没有重载Application,在AndroidManifest.xml中配置如

<application
android:name="android.support.multidex.MultiDexApplication" >
...
</application>

         下如果你重载了Applicaiton,选择继承如下类下

public class MyApplication extends MultiDexApplication{}

         如果你重载了Application,并且无法继承MultiDexApplicationAndroid5.0及更改版本的multidex配置

public class MyApplication extends SomeOtherApplication {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
}

    Android5.0(api21)及之后的版本使用ART虚拟机,ART本身支持从Apk文件中加载多个dex文件。在App安装时,ART会执行预编译,扫描classN.dex并把它们编译成一个系统可执行的.oat文件。因此,minSdkVersion为21及以上版本的,不需要配置multidex support library。只需要如下设置

defaultConfig {
...
minSdkVersion 21
targetSdkVersion 26
multiDexEnabled true
}

    这样配置后,Android构建工具会生成一个主dex文件,和classes2.dex、classes3.dex等等文件,在一个Apk文件中。在运行时,multidex APIs使用一个特别的类加载器搜索所有可用的dex文件

3.multidex support library的局限

  multidex support library有以下已知和需要测试的局限

  1.当App在设备数据区启动时,dex文件的安装是很复杂的,如果第二个dex文件很大,可能会可能会导致ANR。你可以使用混淆来减小dex文件的大小和移除无用的代码

  2.当运行在Android5.0之前的版本时,multidex并不能很好的解决linearalloc limit这个问题,该问题在4.0(api14)中引入,但并没有完全解决。如果你想运行在Android4.0之前的版本上,最好多测试。使用混淆会减少甚至解决这个问题。

4.声明需要在primary dex文件中的类

  当构建multidex App的每个dex文件时,构建工具会执行复杂的决策来决定哪些类需要在primary dex文件中App才能正常启动。如果有些类在启动时需要,但没有在primary dex文件中,会有java.lang.NoClassDefFoundError异常
  你可以手动的指定一些类编译在primary dex文件中,通过声明multiDexKeepFile或multiDexKeepProguard属性在build.gradle的buildTypes中
  multiDexKeepFile的使用如下

    1.首先创建文件,比如命名为multidex-config.txt,在该文件中指定包含在primary dex的类,格式为一行一个类,例如:

com/example/MyClass.class
com/example/MyOtherClass.class

    2.在build.gradle中配置该文件

android {
buildTypes {
release {
multiDexKeepFile file('multidex-config.txt')
...
}
}
}

  multiDexKeepProguard参数同样对应一个文件,该文件使用和Proguard一样的格式且支持Proguard所有的语法。需要使用-keep来指定需要的类,如下:

-keep class com.example.MyClass
-keep class com.example.MyClassToo

    指定某个包下的类:

-keep class com.example.** { *; }

     在build.gradle中配置

android {
buildTypes {
release {
multiDexKeepProguard file('multidex-config.pro')
...
}
}
}

5.优化开发构建中的multidex

  使用multidex的配置需要显著增加编译时间,为了减少在开发中编译时间,Android Studio做出了一些优化,在构建总用pre-dexing来复用multidex输出,pre-dexing依赖于ART,只能在Android5.0及以上使用,Gradle3.0插件更有pre-class dexing等优化,建议升级Android Studio到最新版本并用5.0以上的设备测试

使用multidex解决64K方法引用的限制的更多相关文章

  1. Android方法引用超过65535的解决方式

    //在app/build.gradle android { compileSdkVersion buildToolsVersion "24.0.1" defaultConfig { ...

  2. 【转】Android studio 解决64K超出链接数限制问题

    http://my.oschina.net/gabriel1215/blog/602608 目录[-] 使用MultiDex支持库 注意事项 结论 如果你是一个android开发者,你至少听说过的Da ...

  3. 深入理解Java 8 Lambda(语言篇——lambda,方法引用,目标类型和默认方法)

    作者:Lucida 微博:@peng_gong 豆瓣:@figure9 原文链接:http://zh.lucida.me/blog/java-8-lambdas-insideout-language- ...

  4. [转]深入理解Java 8 Lambda(语言篇——lambda,方法引用,目标类型和默认方法)

    以下内容转自: 作者:Lucida 微博:@peng_gong 豆瓣:@figure9 原文链接:http://zh.lucida.me/blog/java-8-lambdas-insideout-l ...

  5. 兔子--R.java丢失原因及解决的方法

    R.jar丢失原因: a:eclipse指向的adk路径有中文,或者是workspace路径有中文 b:xml文件里有错误或者引用的资源不存在 c:xml或者drawable下资源文件不能够有大写字母 ...

  6. 异常:未能载入文件或程序集”DAL”或它的某一个依赖项——解决的方法

    以下是我再使用抽象工厂+反射重构机房时,在Factoy中出现了以下一个问题: 去网上查了一下资料,发现这是一个非常普遍的问题,它出现的原因主要有两种: 第一种: 载入DLL路径错误.解决的方法是调整D ...

  7. 解决NSTimer循环引用Retain Cycle问题

    解决NSTimer循环引用Retain Cycle问题 iOS开发中以下的情况会产生循环引用 block delegate NSTimer 循环引用导致一些对象无法销毁,一定的情况下会对我们横须造成影 ...

  8. Lambda语言篇 —— lambda, 方法引用, 目标类型和默认方法

    本文介绍了Java SE 8中新引入的lambda语言特性以及这些特性背后的设计思想.这些特性包括: lambda表达式(又被成为"闭包"或"匿名方法") 方法 ...

  9. 讲述Sagit.Framework解决:双向引用导致的IOS内存泄漏(上)

    前言: 好久没写文章了,最近先是重构IT恋.又重写IT恋中. Sagit框架也不断的更新,调整,现在感觉已完美了了相当的多. 今天不写教程,先简单分享一下技术内容. 1:见Block必有:#defin ...

随机推荐

  1. js递归算法1+ 2+3.....100的和

    function num(n){    if(n==1) return 1;    return num(n-1)+n;}num(100);

  2. 汉诺塔I

    题目描述 对于传统的汉诺塔游戏我们做一个拓展,我们有从大到小放置的n个圆盘,开始时所有圆盘都放在左边的柱子上,按照汉诺塔游戏的要求我们要把所有的圆盘都移到右边的柱子上,请实现一个函数打印最优移动轨迹. ...

  3. reinterpret_cast

    reinterpret_cast强制类型转换符 用法: new_type a = reinterpret_cast <new_type> (value) 将value的值转成new_typ ...

  4. 从数组中取出N个元素的所有组合——递归实现

    https://www.cnblogs.com/null00/archive/2012/04/27/2473788.html 今天在做POJ 1753时,需要枚举一个数组中所有组合.之前也遇到过类似的 ...

  5. Phone 3rd Recovery

    #解锁之后会低级格式化,请做好相关备份.1.#unlock code#2.adb reboot-bootloader3.fastboot devices4.fastboot oem unlock ** ...

  6. python学习-迭代器,列表解析和列表生成式

    迭代器为类序列对象提供了一个类序列的接口.Python 的迭代无缝的支持序列对象,而且还允许程序猿迭代非序列类型,包括用户定义的对象. 迭代器是一个next()方法的对象,而不是通过索引计数.当需要下 ...

  7. SSRF漏洞浅析

    大部分web应用都提供了从其他的服务器上获取数据的功能,如使用用户指定的URL,web应用可以获取图片,下载文件,读取文件内容等.如果服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与 ...

  8. 2018—自学Selenium+Python 笔记(二)

    此文记录一些python语法不同之处.. 适合有研发基础的童鞋查阅.. 零基础的童鞋就怪怪一个个学吧! 记录也不一定全,随笔一记 多行语句 total=item1+\ item2+\ item3 &q ...

  9. 将lvm逻辑卷分出一部分

    今天公司磁盘报警,查看磁盘发现挂载的/aa空间还很多,而/ee 空间不足,现将/aa上的lvm分出一部分空间.加到/ee上 注:首先要 df  -T  -h 开一下磁盘格式如果是xfs格式的lvm  ...

  10. Qt代码吐槽

    擦,代码注释里写这么多“NB!”是要闹哪样!!