【问题标题】:Choosing different libraries for compilation and runtime为编译和运行时选择不同的库
【发布时间】:2017-04-10 05:08:21
【问题描述】:

我有两个库,每个库都定义了相同的类。但是它们有一些不同的内容(方法/常量)。

例如:

库 1:

package com.test.package;
Class A {
     // only method signatures
     public void methodA() {
     }

     public void methodB() {
     }
}

库 2:

package com.test.package;
Class A {  
     public void methodA() {
          // some logic that MUST be executed to provide backward compatibility
     }
}

我的应用程序使用库 1 和库 2 并在具有 com.test.package.ClassA 的设备中运行,但 com.test.package.ClassA.methodB() 仅存在于框架中的较新版本中。也就是说,我需要使用库 1 来编译我的应用程序,并使用库 2 来执行 methodA() 的不同实现。

我曾尝试在 Android Studio 中使用 .jar 和 .aar 库格式执行此操作,但它们都不适合我。

是否可以在 Android Studio 项目中设置此配置?

我正在构建库 1 和库 2,我无法在库 2 中添加 methodB()。

【问题讨论】:

    标签: android-studio gradle android-gradle-plugin static-libraries aar


    【解决方案1】:

    对于简单的 Java 应用程序,您可以通过取消链接 compileruntime 配置来完成此操作。我设置了一个示例存储库here

    这个想法在this commit中有所展示,但可以描述为手动重置runtime配置,使其不包含compile配置的内容。这样做之后,您可以在 runtime 配置中包含您的运行时库变体。

    应用程序的build.gradle 变为:

    apply plugin: 'application'
    
    mainClassName = 'my.package.MyAppClass'
    
    configurations.runtime.extendsFrom = [] // Reset runtime configuration
    
    dependencies {
        compile 'my.group:my.artifact:2.0'  // Library 1, with the new method
        runtime 'my.group:my.artifact:1.0'  // Library 2, without the method
    }
    

    对于 Android,这可能会稍微复杂一些。问题是 Android 没有 runtime 配置(因为您不会在计算机上执行它,除非您使用的是 Robolectric 或类似的东西)。

    我认为您可能会使用一些解决方法,但最初的建议是创建一个包装库,以抽象出对其他库的依赖。您可以使用最新的库版本(库 1,使用新方法)编译此包装库。然后,您可以在 Android 应用程序中包含包装器库,同时将其设置为非传递依赖项并包含其他库版本:

    dependencies {
        compile 'my.group:my.wrapped.artifact:0.1' {
            transitive = false  // Don't include dependencies of the wrapper
                                // i.e., don't include version 2.0 of the lib.
        }
        compile 'my.group:my.artifact:1.0'
    }
    

    这应该可行,因为通过将依赖项设置为非传递 Gradle 不会递归地包含包装库的依赖项,因此用于编译包装器的版本不包含在 APK 中(理论上)。因此,您可以添加旧版本而不会引起冲突。

    在同一存储库中设置了一个示例,位于Android branch 下。首先,创建了两个 Java 库。然后an Android library is created 环绕编译时库。 example activity is created 显示使用包装库如何使用编译时库。然后,latest commit 显示应用程序如何配置为使用包装库(使用最新库编译)但强制将旧库包含在运行时中。

    希望这会有所帮助 =)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-12
      • 2018-12-07
      • 2018-05-23
      • 2011-03-24
      相关资源
      最近更新 更多