2017-05-08 23 views
0

我试图在Android Studio中进行条件构建,在这里我可以通过删除任何多余的库依赖关系来减少生成的APK的大小,如果它们不需要特定分发。如何在Android中有条件地编译JAR?

我有一些代码,大致接近于以下内容:

public class MyClass { 

    /* Static Declarations. */ 
    public static final boolean USE_LIBRARY = false; 

    public void doSomething() { 
     // Are we using the library?  
     if(MyClass.USE_LIBRARY) { 
      // Do something with the library that we'd define in my build.gradle. 
      com.some.gradle.library.MyLibrary.doSomethingWithLibrary(); 
     } 
     else { 
      // Do something else. 
     } 
    } 

} 

如果我从我的摇篮依赖删除com.some.gradle.library,我收到指示上面的代码不能被编译编译错误。正如你所看到的,只要USE_LIBRARY保持不真实,我们绝不需要参考MyLibrary;甚至没有实例化,因为它没有提到进口;这些只在运行时被侵犯。

我应该注意到,在实践中,USE_LIBRARY是一个程序生成的常量,与应用程序的BuildConfig.java有关。

当然,编译器可以确定这个代码可以优化吗?这是一种预处理器检查,我可以解决吗?

回答

1

找到了解决方案。我所采取的上述方法可能是,前提是您可以保证在运行时没有库代码可以交互;这包括确保您的任何运行时类extend都不属于任何父节点或implement接口,它们是库的一部分。我能够通过使用ClassyShark验证代码已被删除。

的“绝招”是,当你要导出的库声明库组件为provided为要构建变种假装库提供给您,并作为compile的。

即使用两生成异体libraryVariantemptyVariant,其经由编程开关buildConfigField 'boolean', 'USE_LIBRARY', 'X'USE_LIBRARY值。那么你可以定义你的依赖关系如下:

dependencies { 
    // Actually package the library with the compiled APK. 
    libraryVariantCompile "com.some.gradle.library:-1" 
    // Ignore the library; just please the linting process. 
    emptyVariantProvided "com.some.gradle.library:-1" 
} 
2

我想在Android Studio中做一个条件构建,在那里我可以通过删除任何多余的库依赖关系来减小生成的APK的大小,如果他们不需要特定的分布。

步骤#1:为该“特定分配”定义产品风味。为了这个答案的目的,我将这个foo。您还需要其他产品口味用于其他发行版。

步骤#2:更改您的compile语句,该语句将此JAR拉到fooCompile语句,因此它只会在foo版本上使用。

步骤#3:在每个产品口味的来源组(例如,src/foo/java/)中有MyClass的一个版本,其中foo中的那个引用该库,而其他的则不是。

+0

这听起来很有希望。我有阶段1和阶段2,但我不知道第三个甚至是一个选项!我会让你知道我如何继续,谢谢。 –

1

我想你可能会混淆Java运行时和编译时过程的行为。

在运行期间,您的代码可以有条件地执行,并且库调用可以被忽略,但是在编译期间会处理所有代码。

通过在编译时引用库,编译时需要依赖关系。

但是,有一个名为Proguard的实用工具,它是Android构建系统的一部分,它可以从apk中删除未使用的字节码。此外,请检查@CommonsWare答案,如果您不是在不同版本中使用该库,那么构建类型允许您创建单独的版本,而无需该库

+0

感谢您的澄清。麻烦的是,即使是proguard似乎也无法消除这个库! –