如何通过导入正确的库来避免DEX 64K LIMIT

Jay*_*ing 9 android android-appcompat gradle android-support-library android-multidex

我有这个问题,在编译我使用的所有库时,我在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'
    }
//...
}
Run Code Online (Sandbox Code Playgroud)

迄今解决方案:

  1. 使用Gradle插件 - 我们在一段时间后写了一个非常容易使用的Gradle插件,它列出了包的方法数和总数.您可以在此处找到有关它的更多信息.
  2. www.methodscount.com - 想知道特定库将为您的应用程序添加多少方法?只需在此网站上输入'compile'语句,它就会告诉您它的方法计数,依赖关系,JAR大小和DEX大小.
  3. Android Studio插件 - 这个优秀的插件显示了Android Studio中每个依赖项的方法计数.
  4. 使用MultiDex支持库 如果您使用的是Android Studio,则该过程非常简单.如果不是,我强烈建议迁移,因为Google可能会很快放弃对Eclipse ADT插件和旧的基于Ant的构建系统的支持.

步骤1

在build.gradle中添加MultiDex支持库的依赖项

dependencies { 
... 
   compile 'com.android.support:multidex:' 
   ... 
}
Run Code Online (Sandbox Code Playgroud)

第2步

通过在gradle配置的buildType或productFlavor部分中设置multiDexEnabled标志来启用multi-dexing.

defaultConfig { 
   ... 
multiDexEnabled true 
... 
}
Run Code Online (Sandbox Code Playgroud)

现在,根据您的项目,您有3个选项:

如果您尚未创建自己的Application类,只需将其声明android.support.multidex.MultiDexApplication为您的应用程序类AndroidManifest.xml

   .... 
   android:name="android.support.multidex.MultiDexApplication" 
   ... 
Run Code Online (Sandbox Code Playgroud)

如果您已经拥有自己的Application类,请将其扩展android.support.multidex.MultiDexApplication而不是android.app.Application

如果您的Application类正在扩展其他类并且您不想或不能更改它,请重写attachBaseContext(),如下所示:

public class MyApplication extends FooApplication { 
   @Override 
   protected void attachBaseContext(Context base) { 
      super.attachBaseContext(base); 
      MultiDex.install(this); 
   } 
}
Run Code Online (Sandbox Code Playgroud)

Che*_*byr 11

您可以打开终端并运行命令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
Run Code Online (Sandbox Code Playgroud)


Sav*_*een 7

嘿,你可以尝试我的技巧,它可能对你有用

  1. 首先,你应该避免使用外部库.就像在库中具有相同的依赖关系一样.因此,尝试将该库与Android应用程序代码合并.由于这为方法节省了很多空间.

  2. 使用有用的依赖项和库,如果你想要google play服务,那么只包括有用的服务而不是全部.参见示例

    compile "com.google.android.gms:play-services-location:9.4.0"
    compile "com.google.android.gms:play-services-maps:9.4.0" 
    
    Run Code Online (Sandbox Code Playgroud)

避免这样做

compile 'com.google.android.gms:play-services:9.4.0'
Run Code Online (Sandbox Code Playgroud)
  1. 删除不需要的依赖项.在代码中使用非常可选择的依赖项.

  2. 如果所有的东西都不能很好地工作,那么在你的代码中使用multidex.但它创建了多个dex文件.因此,你的代码将花费很多时间进行编译.

谢谢希望这会对你有所帮助.

  • 是的,这意味着如果您使用了一些模块并且包含与 v7 相同的依赖项,并且您在应用程序端使用了相同的依赖项。因此,最好在代码中使用这些模块。这样你就可以避免库的重复并节省很多 spcae。有时它发生了,但大多数情况下我们都忽略了这件事。 (2认同)