Android系统在安装应用时,往往需要优化Dex,而由于处理工具DexOpt对id数目的限制,导致其处理的数目不能超过65536个,因此在Android开发中,需要使用到MultiDex来解决这个问题,MultiDex可以配合Android Studio实现一个apk包含多个dex的功能,现在就让我们来看看MultiDex究竟是怎么一回事?

1、MultiDex的工作原理

关于这个问题,以APK中有两个dex文件为例,第二个dex文件为classes2.dex。


Android应用安装中,兼容包在Applicaion实例化之后,会检查系统版本是否支持
multidex,classes2.dex是否需要安装,如果需要安装则会从APK中解压出classes2.dex并将其拷贝到应用的沙盒目录下。通
过反射将classes2.dex注入到当前的classloader中。

2、APP的函数方法超过65K

随着Android设备的发展,App包含的功能将越来越完善,其大小势必会变得越来越大。当在开发App的时候由于报的大小和引用库的原因,编译项目时候通常会遇到下面这个错误:

Conversion
<spanclass="hljs-keyword">to</span> Dalvik format failed:
Unable<span class="hljs-keyword">to</span> execute
dex:<span class="hljs-function"><span
class="hljs-keyword">method</span><span
class="hljs-title">ID</span>
<spanclass="hljs-title">not</span>
<spanclass="hljs-title">in</span> [0,
0<spanclass="hljs-title">xffff</span>]:</span>
<spanclass="hljs-number">65536</span>

当然,也有一些系统设备会出现以下log信息,不过反馈的都是同一个问题:

trouble
writingoutput: Too many field references:
<spanclass="hljs-number">131000</span>;
<spanclass="hljs-built_in">max</span> is
<spanclass="hljs-number">65536.</span> You may
<spanclass="hljs-keyword">try</span>
<spanclass="hljs-keyword">using</span>
<spanclass="hljs-comment">--multi-dex option.</span>

这两个错误条件显示一个共同的数字:65536。这个数字,它表示的是你在一个dex包中的函数方法超过了65535个。

如果你已经构建了一个AndroidApp时,并收到了这个错误,那么表示你有很多代码!为什么会出现这个问题,而这个问题又怎么解决呢?且看下面分析。

3、关于65K方法限制

Android开发人员应该都清楚,Android的所有可执行文件都存在dex文件中,其中包含已编译的代码来运行你的应用程序。Dalvik虚拟机对可执行dex文件的规格是有方法限制的,即一个单一的dex文件的方法总数最多为65536,包括:

引用的Android Framework方法、library的方法及编程中写入代码的方法等。

怎么突破限制呢?很简单,就是多生成几个dex文件,而这个多个dex文件,就是multidex方案配置。

Multidex支持Android 5.0之前使用Dalvik Runtime执行程序代码的版本。默认情况下,限制应用到一个单一的classes.dex。

Dalvik字节码文件没APK,为了绕过这个限制,你可以使用multidex支持库,成为你的应用程序的主要部分,以及对DEX文件进行管理并获得额外的dex文件和它们所包含的代码。

4、避免65K限制

当确定使用multidex的分包策略时,除了确保你的代码是优秀的代码以外,还需要做到以下两个步骤:

去掉一些未使用的import和library

使用ProGuard去掉一些未使用的代码

5、用Gradle配置使用Multidex

Android 的 Gradle插件在 Android Build Tool 21.1开始就支持使用multidex了。

在应用程序中设置multidex配置,需要对对程序做以下修改:

修改Gradle的配置,支持multidex

修改你的manifest。让其支持multidexapplication类

修改Gradle的build如下:

android
{ compileSdkVersion <spanclass="hljs-number">21</span>
buildToolsVersion <spanclass="hljs-string">"21.1.0"</span>
defaultConfig { <spanclass="hljs-keyword">...</span>
minSdkVersion <span class="hljs-number">14</span>
targetSdkVersion <spanclass="hljs-number">21</span>
<spanclass="hljs-keyword">...</span> // Enabling multidex
support. multiDexEnabled true } <span
class="hljs-keyword">...</span> } dependencies { compile
<spanclass="hljs-string">'com.android.support:multidex:1.0.0'</span>}

在manifest文件中,添加MultidexApplication Class的引用,IT蓝豹为你演示:

<?xmlversion=<span

class="hljs-string">"1.0"</span>encoding=<spanclass="hljs-string">"utf-8"</span>?><manifest

xmlns:android=<spanclass="hljs-string">"http://schemas.android.com/apk/res/android"</span>

package=<spanclass="hljs-string">"com.example.android.multidex.myapplication"</span>>
<application <spanclass="hljs-keyword">...</span>
android:name=<spanclass="hljs-string">"android.support.multidex.MultiDexApplication"</span>>
<spanclass="hljs-keyword">...</span> </application>
</manifest>

当然,如果重写了 Application,就对自定义Application的继承方式做一个修改。

6、Multidex的方式的局限性

在上面的介绍中,multidex看起来感觉很棒,虽然如此,但multidex还是存在一些局限性,具体如下:

(1)如果DEX文件太大,安装分割dex文件是一个复杂的过程,可能会导致应用程序无响应(ANR)的错误。在这种情况下,你应该尽量的减小dex文件的大小和删除无用的逻辑,而不是完全依赖于multidex。

(2)
在Android 4.0设备(API Level 14)之前,由于Dalvik linearalloc
bug(问题22586),multidex很可能是无法运行的。如果希望运行在Level
14之前的Android系统版本,请先确保完整的测试和使用。

(3)应用程序使用了multiedex配置的,会造成使用比较大的内存。当然,可能还会引起dalvik虚拟机的崩溃(issue 78035)。

(4)对于应用程序比较复杂的,存在较多的library的项目。multidex可能会造成不同依赖项目间的dex文件函数相互调用,找不到方法。

以上便是关于MultiDex的原理及使用方法的简单介绍,如果在Android开发中,遇到65K方法限制,可以尝试使用MultiDex来解决。

本文作者:《IT蓝豹》:www.itlanbao.com

在android开发中使用multdex的方法-IT蓝豹为你整理的更多相关文章

  1. 003android初级篇之【转】Android开发中颜色的定义方法

    正好用到颜色的定义,但脑子里没有记住具体,转载一篇加强印象 1.使用Color类的常量,如: int color = Color.BLUE; // 创建一个蓝色 是使用Android提供的颜色 int ...

  2. Android开发中退出程序几种方法

    参考:http://johncookie.iteye.com/blog/890734 Android程序有很多Activity,比如说主窗口A,调用了子窗口B,子窗口B又调用子窗口C,back返回子窗 ...

  3. Android开发中,那些让您觉得相见恨晚的方法、类或接口

    Android开发中,那些让你觉得相见恨晚的方法.类或接口本篇文章内容提取自知乎Android开发中,有哪些让你觉得相见恨晚的方法.类或接口?,其实有一部是JAVA的,但是在android开发中也算常 ...

  4. 在Android开发中,定时器一般有以下3种实现方法

    在Android开发中,定时器一般有以下3种实现方法: 原文地址http://www.360doc.com/content/12/0619/13/87000_219180978.shtml 一.采用H ...

  5. android开发中关于继承activity类中方法的调用

    android开发中关于继承activity类中的函数,不能在其他类中调用其方法. MainActivity.java package com.example.testmain; import and ...

  6. 在Android开发中,定时执行任务的3种实现方法

    在Android开发中,定时执行任务的3种实现方法: 一.采用Handler与线程的sleep(long)方法(不建议使用,Java的实现方式)二.采用Handler的postDelayed(Runn ...

  7. 在Android开发中替换资源图片不起作用的解决方法

    现象 在android开发中,经常会需要替换res\drawable中的图片,打开res\layout下的文件预览布局页面发现图片已经被替换,但在模拟器或者真实机器上运行时发现该图片并没有被替换,还是 ...

  8. Android开发中Parcelable接口的使用方法

    在网上看到很多Android初入门的童鞋都在问Parcelable接口的使用方法,小编参考了相关Android教程,看到里面介绍的序列化方法主要有两种分别是实现Serializable接口和实现Par ...

  9. Android学习探索之Java 8 在Android 开发中的应用

    前言: Java 8推出已经将近2年多了,引入很多革命性变化,加入了函数式编程的特征,使基于行为的编程成为可能,同时减化了各种设计模式的实现方式,是Java有史以来最重要的更新.但是Android上, ...

随机推荐

  1. 1.ARM的基础知识

    ARM简述 ARM公司既不生产芯片也不销售芯片,它只出售芯片技术授权.ARM技术具有很高的性能和功效,因而容易被厂商接受.同时,合作伙伴的增多,可获得更多的第三方工具.制造和软件支持,这又会使整个系统 ...

  2. Dialog_ _dialog系统样式讲解 及 透明背景

    AlertDialog.Builder builder = new AlertDialog.Builder(DialogActivity.this,AlertDialog.THEME_TRADITIO ...

  3. java中Collection和Collections的区别

    1.Collection: 它是java集合类的一个通用接口,所有集合类都实现的它 2.Collections: 它是一个封装集合类常用工具方法的类,不能被示例化,只支持静态调用

  4. 使用Ninject进行DI(依赖注入)

    Ninject是一个快如闪电.超轻量级的基于.Net平台的依赖注入框架.它能够帮助你把应用程序分离成一个个松耦合.高内聚的模块,然后用一种灵活的方式组装起来.通过使用Ninject配套你的软件架构,那 ...

  5. Oracle_RAC数据库GI的PSU升级(11.2.0.4.0到11.2.0.4.8)

    Oracle_RAC数据库GI的PSU升级(11.2.0.4.0到11.2.0.4.8) 本次演示为升级oracle rac数据库,用GI的psu升级,从11.2.0.4.0升级到11.2.0.4.8 ...

  6. ECS挂载数据盘

    1.先在阿里控制台挂载硬盘: 2.df -h 确认没有分区 3.fdisk -l 4.fdisk /dev/xvdb 分区 根据提示m-n-p-1-Enter-Enter-w 5.fdisk -l 查 ...

  7. MonkeyRunner测试一MonkeyRunner的使用

    最近搭建MonkeyRunner开发环境,安装PyDev时,饱受折磨,现在终于搞定.因为一些原因,用了JDK1.6,在线安装插件PyDev成功后,Windows-Preferences里找不到PyDe ...

  8. C#运算符大全_各种运算符号的概述及作用

    一.[]方括号 ([]) 用于数组.索引器和属性,也可用于指针. 1.数组类型是一种后跟 [] 的类型:int[] fib = new int[100]; //创建一个有100元素的数组若要访问数组的 ...

  9. 利用Flex组件birdeye绘制拓扑关系图

    birdeye绘制拓扑关系图 1.flex简单介绍 Flex 是一个高效.免费的开源框架,可用于构建具有表现力的 Web应用程序,这些应用程序利用Adobe Flash Player和Adobe AI ...

  10. SQLServer查询所有库表结构信息

    1.查询数据库中的所有数据库名: SELECT Name FROM Master..SysDatabases ORDER BY Name 2.查询某个数据库中所有的表名: SELECT Name FR ...