dex分包之--------multidex包的配置使用

目录:
  • 一、前言
  • 二、产生原因
  • 三、MultiDex的简要原理
  • 四、MultiDex的使用

一、前言

首先说一下我遇到的情况,最近接手了一个项目是在已有的项目里进行更新添加一些功能,然后该项目导了N多的包,在我使用Android Studio的run”App”直接安装到手机上运行是正常的,然后正式打包安装后就崩溃了,当时觉得很奇怪,然后一看日志:

trouble writing output: 
Too many field references: 131000; max is 65536. 
You may try using --multi-dex option.

很明显,方法数65536上限了,那为什么直接运行又没问题呢? 

没办法只好查资料: 

Note: While using Instant Run, Android Studio automatically configures your app for multidex when your app's minSdkVersion is set to 21 or higher. Because Instant Run only works with the debug version of your app, you still need to configure your release build for multidex to avoid the 64K limit.

大概意思就是:

如果使用Instant Run,当app的minSdkVersion大于或等于21时,Android Studio会自动配置支持multidex,但是仅debug版本有效,release版仍然需要配置multidex来突破64K限制。

原来当android sdk大于21的时候debug自动支持multidex;好了回到正文multidex分包

二、产生原因

在Android系统中,一个App的所有代码都在一个Dex文件里面。Dex是一个类似Jar的存储了多有Java编译字节码的归档文件。因为Android系统使用Dalvik虚拟机,所以需要把使用Java Compiler编译之后的class文件转换成Dalvik能够执行的class文件。这里需要强调的是,Dex和Jar一样是一个归档文件,里面仍然是Java代码对应的字节码文件。当Android系统启动一个应用的时候,有一步是对Dex进行优化,这个过程有一个专门的工具来处理,叫DexOpt。DexOpt的执行过程是在第一次加载Dex文件的时候执行的。这个过程会生成一个ODEX文件,即Optimised Dex。执行ODex的效率会比直接执行Dex文件的效率要高很多。但是在早期的Android系统中,DexOpt有一个问题,也就是这篇文章想要说明并解决的问题。DexOpt会把每一个类的方法id检索起来,存在一个链表结构里面。但是这个链表的长度是用一个short类型来保存的,导致了方法id的数目不能够超过65536个。当一个项目足够大的时候,显然这个方法数的上限是不够的。尽管在新版本的Android系统中,DexOpt修复了这个问题,但是我们仍然需要对低版本的Android系统做兼容。
为了解决方法数超限的问题,需要将该dex文件拆成两个或多个,为此谷歌官方推出了multidex兼容包,配合AndroidStudio实现了一个APK包含多个dex的功能。

三、MultiDex的简要原理 

我们以APK中有两个dex文件为例,第二个dex文件为classes2.dex。 
兼容包在Applicaion实例化之后,会检查系统版本是否支持 multidex,classes2.dex是否需要安装。 
如果需要安装则会从APK中解压出classes2.dex并将其拷贝到应用的沙盒目录下。 
通过反射将classes2.dex注入到当前的classloader中。 
下面引入一下官方的文档: 
https://developer.android.com/tools/building/multidex.html#about

四、MultiDex的使用

1、在Gradle中配置使用Multidex

由于Android的Gradle插件在Android Build Tool 21.1开始支持使用multidex,所以我们需要使用Android Build Tools 21.1及以上版本,修改app目录下的build.gradle文件,有两点需要修改。

(1)在defaultConfig中添加multiDexEnabled true这个配置项。 
(2)在dependencies中添加multidex的依赖: 
compile ‘com.android.support:multidex:1.0.1’



2、在Gradle中配置好之后,我们还需要在代码中加入支持multidex的功能,有三种方案可选

方案一:在manifest文件中指定Application为MultiDexApplication,如下:


方案二:写一个Application类并继承MultiDexApplication,并在AndroidManifest.xml的application标签中进行注册(在application标签中增加name属性,并添加自己的Application类名即可),如果不是想重写MultiDexApplication中一些方法的话,还是方案一更方便些。如下:


注册如下:


方案三:如果不想按方案二继承,我们可以重写Application的attachBaseContext方法,注意,这个方法比onCreate方法先执行。具体方法是创建一个新类,继承Application,然后重写attachBaseContext方法,并在AndroidManifest.xml的application标签中进行注册(与方案二注册相同)如下:


对于在AndroidManifest.xml中注册,与方案二的注册相同。



本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/447049.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++ primer第六章函数的学习

介绍 首先介绍函数的定义和声明,包括如何传入参数以及函数如何返回结果。C语言允许使用重载函数,即几个不同的函数可以使用向同一个名字。所以接下来介绍重载函数的方法,以及编译器选择如何从函数的若干重载的形式中选取一个与调用模板相互匹…

C语言指针作为函数参数 以及智能指针作为函数参数

总所周知指针作为函数参数传递的时候 传递的是指针的拷贝&#xff08;指针也是变量&#xff09; 这里提供四种指针的传递方法 改到实际的指针。 #include <stdio.h> #include <memory> #include <iostream> using namespace std; void test1(char **string)…

Android Studio打包和引用aar

一、简介 Android 库在结构上与 Android 应用模块相同。它可以提供构建应用所需的一切内容&#xff0c;包括源代码、资源文件和 Android 清单。不过&#xff0c;Android 库将编译到您可以用作 Android 应用模块依赖项的 Android 归档 (AAR) 文件&#xff0c;而不是在设备上运行…

C++ primer第六章6.4函数的学习 之函数的重载

6.4 函数的重载 函数的名字相同但是形参的列表不同&#xff0c;将其称之为重载函数 void print(const char *cp); void print(const int *beg,const int * end); void print(const int ia[],size_t size); 形如上面所展现的这样&#xff0c;当调用这些函数的时候&#xff0c;…

C++有限状态机的实现

//待完善 有限状态机是一个很常用的技术&#xff0c;在流程控制和游戏AI中都比较实用&#xff0c;因为状态机编程简单又很符合直觉。与有限状态机类似的是设计模式中的状态模式。本文是参考《Programming Game AI by Example》 一、 记得最开始工作时候也接触过有限状态机&…

手势希尔排序

void shell_sort(int *data, int length){int gap0;int i0,j0;for(gaplength/2;gap>1;gap/2){//组内插入排序for(igap;i<length;i){int temp data[i];for(ji-gap;j>0&&temp<data[j];jj-gap){data[jgap]data[j];}data[jgap]temp;}} }

Android之android.os.Build

一、类概述&#xff1a;从系统属性中提取设备硬件和版本信息。 二、内部类&#xff1a; 1、Build.VERSION 各种版本字符串 2、Build.VERSION_CODES 目前已知的版本代码的枚举类 三、常量&#xff1a;UNKNOWN 当一个版本属性不知道时所设定的值。其字符串值为 “unknown” 。 …

C++ unsigned char*转化为string的形式

unsigned char*转化为string int main(int argc,char **argv){//unsigned char * 转化为string//参考链接 https://www.itdaan.com/tw/4ff531a5e6651468a5b7c6d95927ba3dunsigned char *foo;unsigned char str[] "Hello world";string strHH;foo str;strHH.append…

KMP算法面试题

面试题&#xff1a;写一个在一个宇符串(n)中寻找一个子串&#xff08;m)第一个位置的函数。 10G的日志中&#xff0c;如何快速地查找关键字&#xff1f;

C++对于程序调试很有用的系统自带的名字

简单介绍 __func__当前调试的函数的名字__FILE__存放文件名的字符串的字面值__LINE__存放当前行号的整型字面值__TIME__存放文件编译时间的字符串的字面值__DATE__存放文件编译日期的字符串的字面值 例子 if(word.size() < threshold){cerr << "Error: " …

Android中List、Set、Map数据结构详解

Android中一般使用的数据结构有java中的基础数据结构List&#xff0c;Set&#xff0c;Map。还有一些Android中特有的几个&#xff0c;SparseArray(使用Map时Key是int类型的时候可以用这个代替)等。 继承关系&#xff1a; Collection<–List<–ArrayList Collection<…

Android设计模式之——单例模式

一、介绍 单例模式是应用最广的模式之一&#xff0c;也可能是很多初级工程师唯一会使用的设计模式。在应用这个模式时&#xff0c;单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个全局对象&#xff0c;这样有利于我们协调系统整体的行为。 二、定义 …

我的职业生涯规划(软件工程)

以后笔记先在语雀整理 方便一点https://www.yuque.com/juhao-pqdor/goeie3 整理一下自己的笔记 弥补一下以前没写博客的遗憾吧 二十载求学路将尽&#xff0c;行文至此&#xff0c;思绪万千。求学之路始于家乡&#xff0c;竿转热河&#xff0c;而今终于石门。一路行之如人饮水…

C++ primer第六章6.5函数的学习 之特殊用途的语言特性

6.5.1 默认实参 将反复出现的数值称为函数的默认实参&#xff0c;调用含有默认实参的时候可以包含该实参也可以不包含比如程序打开页面会有一个默认的宽高&#xff0c;如果用户不喜欢也允许用户自由指定与默认数值不同的数值&#xff0c;具体例子如下图所示 typedef string::s…

Android设计模式之——Builder模式

一、介绍 Builder模式是一步一步创建一个复杂对象的创建型模式&#xff0c;它允许用户在不知道内部构建细节的情况下&#xff0c;可以更精细的控制对象的构造流程。该模式是为了将构建复杂对象的过程和它的部件解耦&#xff0c;使得构建过程和部件的表示隔离开来。 因为一个复…

c++后端开发书籍推荐

推荐书籍: 略读80% 精读50% C&#xff1a; C Primer Plus C和指针&#xff08;入门书 不只是指针&#xff09; C陷阱与缺陷&#xff08;宏相关&#xff09; C专家编程 C&#xff1a; 有专门的视频 C primer C程序设计原理与实践&#xff08;c之父写的 入门经典&#xff09; Ef…

C++ primer第六章6.6函数匹配

函数的匹配 当重载函数的形参数量相等以及某些形参的类型可以由其他的类型转化得来的时候&#xff0c;对于函数的匹配就会变得很难 确定候选函数和可行函数 函数匹配的第一步就是选定本次调用对应的重载函数集&#xff0c;集合中的函数称为候选函数。候选函数具有两个特征&am…

Android设计模式之——原型模式

一、介绍 原型模式是一个创建型的模式。原型二字表明了该模型应该有一个样板实例&#xff0c;用户从这个样板对象中复制出一个内部属性一致的对象&#xff0c;这个过程也就是我们俗称的“克隆”。被复制的实例就是我们所称的“原型”&#xff0c;这个原型也是可定制的。原型模…

C++ primer第六章6.7函数指针

函数指针 函数指针指向的是函数而不是对象。和其他指针一样&#xff0c;函数指针指向某种特定的类型。函数的类型由他的返回类型和形参类型共同决定&#xff0c;而与函数的名字无关。 //比较两个string对象的长度 bool lengthCompare(const string &,const string &);…

Android设计模式之——工厂方法模式

一、介绍 工厂方法模式&#xff08;Factory Pattern&#xff09;&#xff0c;是创建型设计模式之一。工厂方法模式是一种结构简单的模式&#xff0c;其在我们平时开发中应用很广泛&#xff0c;也许你并不知道&#xff0c;但是你已经使用了无数次该模式了&#xff0c;如Android…