【问题标题】:Exclude class from resulting dex file从生成的 dex 文件中排除类
【发布时间】:2015-01-18 20:42:48
【问题描述】:

我有问题。我的项目结构如下:
P
|-SubP1
|-SubP2

两个包中都有两个存根类android.media.IRemoteDisplay。它们在实现上有所不同,但这不是问题 - 当我在 Android 上运行应用程序时,它们将被系统类取代。

但是,有一个问题 - 我无法构建项目,因为 dexMerger 失败 - 它说有两个冲突的类。我可以理解这个错误 - 毕竟,确实有两个相互冲突的类:)

但是当我尝试像这样在 build.gradle 中排除这些文件时:

sourceSets {
    main {
        java {
            srcDir 'src'
            exclude '**/android/media/**'
        }
    }
}

编译失败,因为它找不到 android.media.IRemoteControlDisplay 类(并且它是嵌套类)。

我怎样才能仍然使用这些类,但从生成的 DEX 文件中排除它们?

不要质疑从已编译项目中排除该类是否正确 - 这是正确的做法,我已经这样做了,但是手动 - 通过将 SubP1 和 SubP2 预编译到 jar 中然后从这些 jar 文件中手动删除 IRemoteController.class,然后将这些 jar 包含在 P 中。

我也会对这个解决方案感到满意:
1. 构建 SubP1
2. 从 SubP1.jar 中删除 IRemoteControlDisplay.class
3. 构建 SubP2
4. 从 SubP2.jar 中删除 IRemoteControlDisplay.class
5.将SubP1.jar和SubP2.jar作为依赖添加到P
6. 构建 P
如果可以,请告诉我。

【问题讨论】:

  • 如果你不将它包含在 DEX 中,你的应用程序将强制关闭,因为它找不到它想要使用的类。
  • 你为什么要排除整个文件夹,而不仅仅是那个特定的类/文件?
  • 欧根,我知道我在做什么。该应用程序不会强制崩溃,因为 IRemoteControlDisplay 是系统包 android.media 中存在的一个类。您通常无法访问它,但我需要访问它,我通过创建具有相同方法签名的存根类来做到这一点。因此,通过排除它,应用程序将调用系统实现。顺便说一句,我已经做到了 - 编译 jars 并从那里删除 .class 文件,然后将这些 jars 包含在项目中。但现在我想让它更加自动化。
  • Jim,因为在我的项目中,整个包只包含一个文件,所以是一样的:)
  • 如果它只有一个文件,为什么您的错误提示缺少另一个文件?如果目录中只有一个文件,它如何排除任何其他文件?

标签: android gradle android-studio dex


【解决方案1】:

终于,我做到了。

我需要的是一个 runtime 依赖而不是 compilation-time 依赖。因此,我为 SubP1 创建了名为 SubSubP1 的子模块(例如)将 android.media.IRemoteDisplay 移动到 SubSubP1 中,并为 SubP2 创建了子模块 SubSubP2,并对存根类做了同样的事情。然后我声明了 SubP1 和 SubP2 的依赖关系如下:

dependencies {
    provided project(':SubP1:SubSubP1')
}

dependencies {
    provided project(':SubP2:SubSubP2')
}

这就成功了! Gradle 没有编译类,而是假设它们将在运行时加载。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多