android在打包的时候会存在一个限制,classes.dex不可以超过65536(0xffff)个方法,如果超过了65536在安装的时候就会报错,无法进行安装Install Run。
在早期没有太多开源库的时候,这个问题还不是那么容易碰到,因为我们所自己写程序,要达到这个量级还是很困难的,我们简单的估算一下,一个方法假定平均代码行数为三,要达到上面的限制就要65536*3= 196,608,19万行这已经是一个相当庞大的应用了,试想一下,我们所开发过的项目有几个能达到这个量级呢?
不过现在要达到这个量级就变的很简单了,因为有很多的开源库提供给我们引用,比如图片框架,网络框架,数据库框架,还有各种为了方便开发所引入的异步框架,消息推送框架,注解框架,这些框架的引用很容就让我们所打出的dex包超过65536限制。
而对于框架所提供的功能真的都是我们所需要的吗?事实上我们很多时候都只是为了使用其部分功能,而引用了整个项目,对于这种情况,我们应该怎么解决呢?
1. 如果可以的话,对于使用了很少功能的框架,自己可以封装一套简版,然后把引用去掉。
2. 如果没有办法自己封装一套的话,我们可以通过 ProGuard 移除未使用的代码。
通过上面这两点,一般我们能够达到排除65536这个问题,而且这种解决方式也是一种比较好的解决方式,因为上面的方式可以让我们的应用编译起来更快,生成的包也更小。不过对于通过上面方式依然解决不了的,android中也提供了其它的解决方法。
1. android api 20以上版本
只需要在module的build.gradle文件的defaultconfig中添加multiDexenabled true
android {
defaultConfig {
...
minSdkVersion 21
targetSdkVersion 25
multiDexEnabled true
}
...
}
这是因为在android 5.0之后,android采用ART替代了JIT运行时,ART原生支持对apk中dex分包加载。ART在应用安装时,对应用进行预编译将dex文件转化.oat,在运行时直接运行,而JIT则是在运行时进行编译执行。
2. android api20以下版本
对于android20以下版本,原生的没有带分包功能,需要我们引入分包库,并在application中添加必要的代码。引包代码如下:
android {
defaultConfig {
...
minSdkVersion 15
targetSdkVersion 25
multiDexEnabled true
}
...
}
dependencies {
compile 'com.android.support:multidex:1.0.1'
}
在引入multidex包之后,我们需要对我们的application类进行以下操作
1.如果我们自己没有实现application类,则将multidex中的application子类作为我们应用的application,代码如下:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp">
<application
android:name="android.support.multidex.MultiDexApplication" >
...
</application>
</manifest>
2. 如果我们有实现自己的application类,则让我们的application继承自MultiDexApplication类。
3. 假如我们无法让自己的application类去继承MultiDexApplication类,我们可以在我们的application类中添加以下代码:
public class MyApplication extends SomeOtherApplication {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(context);
Multidex.install(this);
}
}
通过以上方法,分包工具就会帮我们把应用程序打包成多个dex文件。
参考链接: