如何通过导入正确的库来避免 DEX 64K LIMIT
How to avoid DEX 64K LIMIT by importing the right library
我遇到了这个问题,在编译我使用的所有库时,我在 Dalvik 中溢出了 64k 方法限制。当我导入支持库时,我开始遇到这个问题,因为有些已经包含在其他库中,它最终溢出了限制。
有没有办法验证某个库是否未在当前项目中使用或是否已通过另一个库依赖项导入?
目前,我排除了那些我确定知道的人,但必须手动执行此操作似乎很奇怪。
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:multidex:1.0.1'
compile "com.android.support:percent:${supportLibVersion}"
compile("com.android.support:design:${supportLibVersion}") {
exclude module: 'support-v4'
}
compile("com.android.support:cardview-v7:${supportLibVersion}") {
exclude module: 'support-v4'
}
compile('com.github.nkzawa:socket.io-client:0.4.1') {
exclude group: 'org.json', module: 'json'
}
compile('com.astuetz:pagerslidingtabstrip:1.0.1') {
exclude module: 'support-v4'
}
//...
}
目前的解决方案:
- 使用 Gradle 插件 – 我们写了一个非常容易使用的 Gradle 插件,它按包列出了方法的数量以及总数。您可以在此处找到更多相关信息。
- www.methodscount.com – 想知道某个库会向您的应用程序添加多少方法?只需在此网站上输入“编译”语句,它就会告诉您它的方法数、依赖项、JAR 大小和 DEX 大小。
- Android Studio 插件 – 这个出色的插件显示 Android Studio 中每个依赖项的方法计数。
- 使用 MultiDex 支持库
如果您使用的是 Android Studio,则过程非常简单。如果您不是,我强烈建议迁移,因为 Google 可能很快就会放弃对 Eclipse ADT 插件和旧的基于 Ant 的构建系统的支持。
步骤 1
在 build.gradle
中添加 MultiDex 支持库的依赖项
dependencies {
...
compile 'com.android.support:multidex:'
...
}
步骤 2
通过在 gradle 配置的 buildType 或 productFlavor 部分设置 multiDexEnabled 标志来启用多重索引。
defaultConfig {
...
multiDexEnabled true
...
}
现在根据您的项目,您有 3 个选项:
如果您还没有创建自己的应用程序 class,只需在 AndroidManifest.xml
中将 android.support.multidex.MultiDexApplication
声明为您的应用程序 class
....
android:name="android.support.multidex.MultiDexApplication"
...
如果您已经有自己的应用程序 class,请将其扩展 android.support.multidex.MultiDexApplication
而不是 android.app.Application
如果您的应用程序 class 正在扩展其他应用程序 class 而您不想或不能更改它,请重写 attachBaseContext() ,如下所示:
public class MyApplication extends FooApplication {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
}
您可以打开终端并运行命令gradlew app:dependencies来测试哪些依赖项已经包含在其他依赖项中作为您项目的传递依赖项每个都有各自的版本。
例如,对于我使用的 com.android.support:design 库的一个项目,我得到了以下依赖关系图:
+--- com.android.support:design:23.3.0
| +--- com.android.support:appcompat-v7:23.3.0
| | +--- com.android.support:support-vector-drawable:23.3.0
| | | \--- com.android.support:support-v4:23.3.0
| | | \--- com.android.support:support-annotations:23.3.0
| | +--- com.android.support:animated-vector-drawable:23.3.0
| | | \--- com.android.support:support-vector-drawable:23.3.0 (*)
| | \--- com.android.support:support-v4:23.3.0 (*)
| +--- com.android.support:support-v4:23.3.0 (*)
| \--- com.android.support:recyclerview-v7:23.3.0
| +--- com.android.support:support-v4:23.3.0 (*)
| \--- com.android.support:support-annotations:23.3.0
点击文件然后点击项目结构点击左下角的app的弹出窗口。您将看到多个选项卡,单击 Dependencies 选项卡,然后单击右上角的 plus 选择 Library dependency search你想要的图书馆它会显示你的 IDE
中可用的那些图书馆
defaultConfig
{
multiDexEnabled true
}
dependencies {
compile 'com.android.support:multidex:1.0.0'
}
并将此方法添加到您的应用程序中class
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(newBase);
MultiDex.install(this);
}
嘿,你可以试试我的技巧,它可能对你有用
首先你应该避免使用外部库。就像那个库有相同的依赖关系。因此,尝试将该库与 android 应用程序代码合并。
由于这为方法节省了很多space。
使用有用的依赖项和库,例如如果您想要 google 播放服务,则只包含有用的服务而不是 all.See 示例
compile "com.google.android.gms:play-services-location:9.4.0"
compile "com.google.android.gms:play-services-maps:9.4.0"
避免这种情况
compile 'com.google.android.gms:play-services:9.4.0'
删除代码中不需要的 dependencies.Use 非常可选的依赖项。
如果所有事情都不能很好地工作,那么在你的 code.But 中使用 multidex 它会创建多个 dex files.So,你的代码将花费很多时间进行编译。
谢谢希望这对你有帮助。
虽然使用Multidex Support Library库解决了问题,但并不完美。要做的第一件事应该是确定您的应用程序当前有多少方法,以及每个依赖项添加了多少方法。以前您必须手动执行此操作,但现在有很多工具可用:
- 使用 Gradle 插件 – This is an extremely easy to use Gradle plugin some time back that lists the number of methods by package along with the total number. You can find more information about it here.
- www.methodscount.com – 只需在本网站输入
‘compile’
语句,它会告诉您它的方法数、依赖项、JAR 大小和 DEX 大小。
- Android Studio 插件 – 这个优秀的 plugin 显示 Android Studio 中每个依赖项的方法计数。
Irrespective of what you tool you end up using, use the information it
provides to perform an audit of your app’s dependencies. You should
look for unused libraries or ones that can be minimized or even
replaced with your own simpler solution. If you are not using Proguard
to remove unused code, first enable it and see if it solves the
problem(Check this). Using Proguard
is well… not fun, but once you manage to make
it work properly, it’ll significantly reduce the method count. If all
else fails, you’ll have to use the MultiDex support library.
查看 gradle 任务以删除 Google Play 服务库中未使用的包。
结论
虽然 Multidex Support Library
在大多数情况下修复了 DEX 64K 问题,但它应该被视为最后的手段。在尝试使用它之前,您应该审核您的项目是否存在不需要的依赖项,并使用 ProGuard
删除尽可能多的未使用代码。如果您继续使用它,请确保您在旧设备上测试您的应用程序。
希望对您有所帮助。
我遇到了这个问题,在编译我使用的所有库时,我在 Dalvik 中溢出了 64k 方法限制。当我导入支持库时,我开始遇到这个问题,因为有些已经包含在其他库中,它最终溢出了限制。
有没有办法验证某个库是否未在当前项目中使用或是否已通过另一个库依赖项导入?
目前,我排除了那些我确定知道的人,但必须手动执行此操作似乎很奇怪。
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:multidex:1.0.1'
compile "com.android.support:percent:${supportLibVersion}"
compile("com.android.support:design:${supportLibVersion}") {
exclude module: 'support-v4'
}
compile("com.android.support:cardview-v7:${supportLibVersion}") {
exclude module: 'support-v4'
}
compile('com.github.nkzawa:socket.io-client:0.4.1') {
exclude group: 'org.json', module: 'json'
}
compile('com.astuetz:pagerslidingtabstrip:1.0.1') {
exclude module: 'support-v4'
}
//...
}
目前的解决方案:
- 使用 Gradle 插件 – 我们写了一个非常容易使用的 Gradle 插件,它按包列出了方法的数量以及总数。您可以在此处找到更多相关信息。
- www.methodscount.com – 想知道某个库会向您的应用程序添加多少方法?只需在此网站上输入“编译”语句,它就会告诉您它的方法数、依赖项、JAR 大小和 DEX 大小。
- Android Studio 插件 – 这个出色的插件显示 Android Studio 中每个依赖项的方法计数。
- 使用 MultiDex 支持库 如果您使用的是 Android Studio,则过程非常简单。如果您不是,我强烈建议迁移,因为 Google 可能很快就会放弃对 Eclipse ADT 插件和旧的基于 Ant 的构建系统的支持。
步骤 1
在 build.gradle
中添加 MultiDex 支持库的依赖项dependencies {
...
compile 'com.android.support:multidex:'
...
}
步骤 2
通过在 gradle 配置的 buildType 或 productFlavor 部分设置 multiDexEnabled 标志来启用多重索引。
defaultConfig {
...
multiDexEnabled true
...
}
现在根据您的项目,您有 3 个选项:
如果您还没有创建自己的应用程序 class,只需在 AndroidManifest.xml
android.support.multidex.MultiDexApplication
声明为您的应用程序 class
....
android:name="android.support.multidex.MultiDexApplication"
...
如果您已经有自己的应用程序 class,请将其扩展 android.support.multidex.MultiDexApplication
而不是 android.app.Application
如果您的应用程序 class 正在扩展其他应用程序 class 而您不想或不能更改它,请重写 attachBaseContext() ,如下所示:
public class MyApplication extends FooApplication {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
}
您可以打开终端并运行命令gradlew app:dependencies来测试哪些依赖项已经包含在其他依赖项中作为您项目的传递依赖项每个都有各自的版本。
例如,对于我使用的 com.android.support:design 库的一个项目,我得到了以下依赖关系图:
+--- com.android.support:design:23.3.0
| +--- com.android.support:appcompat-v7:23.3.0
| | +--- com.android.support:support-vector-drawable:23.3.0
| | | \--- com.android.support:support-v4:23.3.0
| | | \--- com.android.support:support-annotations:23.3.0
| | +--- com.android.support:animated-vector-drawable:23.3.0
| | | \--- com.android.support:support-vector-drawable:23.3.0 (*)
| | \--- com.android.support:support-v4:23.3.0 (*)
| +--- com.android.support:support-v4:23.3.0 (*)
| \--- com.android.support:recyclerview-v7:23.3.0
| +--- com.android.support:support-v4:23.3.0 (*)
| \--- com.android.support:support-annotations:23.3.0
点击文件然后点击项目结构点击左下角的app的弹出窗口。您将看到多个选项卡,单击 Dependencies 选项卡,然后单击右上角的 plus 选择 Library dependency search你想要的图书馆它会显示你的 IDE
中可用的那些图书馆 defaultConfig
{
multiDexEnabled true
}
dependencies {
compile 'com.android.support:multidex:1.0.0'
}
并将此方法添加到您的应用程序中class
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(newBase);
MultiDex.install(this);
}
嘿,你可以试试我的技巧,它可能对你有用
首先你应该避免使用外部库。就像那个库有相同的依赖关系。因此,尝试将该库与 android 应用程序代码合并。 由于这为方法节省了很多space。
使用有用的依赖项和库,例如如果您想要 google 播放服务,则只包含有用的服务而不是 all.See 示例
compile "com.google.android.gms:play-services-location:9.4.0" compile "com.google.android.gms:play-services-maps:9.4.0"
避免这种情况
compile 'com.google.android.gms:play-services:9.4.0'
删除代码中不需要的 dependencies.Use 非常可选的依赖项。
如果所有事情都不能很好地工作,那么在你的 code.But 中使用 multidex 它会创建多个 dex files.So,你的代码将花费很多时间进行编译。
谢谢希望这对你有帮助。
虽然使用Multidex Support Library库解决了问题,但并不完美。要做的第一件事应该是确定您的应用程序当前有多少方法,以及每个依赖项添加了多少方法。以前您必须手动执行此操作,但现在有很多工具可用:
- 使用 Gradle 插件 – This is an extremely easy to use Gradle plugin some time back that lists the number of methods by package along with the total number. You can find more information about it here.
- www.methodscount.com – 只需在本网站输入
‘compile’
语句,它会告诉您它的方法数、依赖项、JAR 大小和 DEX 大小。 - Android Studio 插件 – 这个优秀的 plugin 显示 Android Studio 中每个依赖项的方法计数。
Irrespective of what you tool you end up using, use the information it provides to perform an audit of your app’s dependencies. You should look for unused libraries or ones that can be minimized or even replaced with your own simpler solution. If you are not using
Proguard
to remove unused code, first enable it and see if it solves the problem(Check this). UsingProguard
is well… not fun, but once you manage to make it work properly, it’ll significantly reduce the method count. If all else fails, you’ll have to use the MultiDex support library.
查看 gradle 任务以删除 Google Play 服务库中未使用的包。
结论
虽然 Multidex Support Library
在大多数情况下修复了 DEX 64K 问题,但它应该被视为最后的手段。在尝试使用它之前,您应该审核您的项目是否存在不需要的依赖项,并使用 ProGuard
删除尽可能多的未使用代码。如果您继续使用它,请确保您在旧设备上测试您的应用程序。
希望对您有所帮助。