当引用但不必要的源/资源未找到时,如何解决产品风格构建错误?

20

我有一个项目,其中包含两个产品风味并带有它们自己的目录:

build.gradle:

android {
    ...
    productFlavors {
            free {
                applicationId "com.sample.free"
                 buildConfigField "boolean", "free", "true"
            }
            paid {
                applicationId "com.sample"
                buildConfigField "boolean", "free", "false"
            }
    }
}

我有一个类(例如PaidOperationClass),它只在paid flavor中使用。因此,我将该类放在src/paid/java目录下。我还有另一个类(例如CommonClass),它被两种flavor都使用。所以我把它放在src/main/java目录下:

src/main/  --> has CommonClass
src/free/
src/paid/  --> has PaidOperationClass

CommonClass中,我有一个如下所示的方法:

if(!BuildConfig.FREE) {
    PaidOperationClass.doSomeStuff();
}

因此,PaidOperationClass被引用(具有导入),但未被免费版本使用。

如果我为付费版本构建应用程序,一切正常。 但是,如果我尝试为免费版本构建应用程序,则构建失败,因为找不到被引用但不必要的类。 如何在没有代码(类/方法)复制的情况下解决此问题(例如在free口味下放置虚拟的PaidOperationClass)? 在构建时是否有任何gradle选项可以忽略此类构建错误?

编辑:我需要一个无需代码复制的gradle解决方案。 可能是基于注释的自定义脚本,它会在编译时删除产品风味的不必要代码。


3
不,你必须在你的代码中修复它。 - Mimmo Grottoli
@MimmoGrottoli 是的,但使用Gradle应该有更简单的方法。 - Devrim
不,没有。Gradle是构建系统,而不是应用程序代码。 - Mimmo Grottoli
@DevrimTuncer,你找到解决方案了吗? - CeccoCQ
@CeccoCQ 不,还没有。但是我正在思考注释的想法。 - Devrim
@DevrimTuncer 我有同样的需求。如果你需要帮助,可以联系我。 - CeccoCQ
4个回答

2

由于导入语句位于CommonClass内部,无法在免费版本中解析PaidOperationClass,因此您无法这样做。

一种实现方式是:

免费版本中创建一个空类:

public class PaidOperationClass{

  public static void doSomeStuff(){
      //do nothing..    
  }
}

1
你正在从free包中引用paid包,无论你是否使用它:
if(!BuildConfig.FREE) {
     PaidOperationClass.doSomeStuff();
}

我建议有两种选择: 1.
如果你有一段从未使用过的代码,为什么还要保留它?将其删除并替换为:
if(!BuildConfig.FREE) {
     // Do something within the imported packages.
}

否则,您必须导入 paid 包。
2. 或者有两个 free 包版本,free_paidfree_no_paid,并在 free_no_paid 中删除对 paid 的引用,在没有 paid 的情况下使用它进行编译,并在使用 paid 进行编译时使用 free_paid 包。

1
另一种解决方案是创建两个CommonClass - 分别在freepaid源集中(但不在main中),其中包含特定于特定风味的代码。例如:src/free/java/.../CommonClass.java:
doSomeStuff() {
  doSomeFreeStuff();    
}

src/paid/java/.../CommonClass.java:

doSomeStuff() {
  doSomePaidStuff();    
}

在这种情况下,位于main源集中的代码可以引用CommonClass#doSomeStuff(),无论构建哪种flavor。只会编译特定flavor的一个CommonClass。换句话说,不使用手动if语句,而是让gradle选择适当的类进行编译。
您还可以将真正通用的代码(与freepaid无关)从CommonClass中提取到抽象类中,即放置在main源集中的BaseCommonClass中,并让CommonClass扩展它。

1
最简单的解决方案可能是创建一个类:IPaidOperations,该类位于/src/main目录中,由PaidOperationClass实现。然后在CommonClass中只需使用接口即可。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接