将 2 个类似项目与 Android Build Variant 结合

问题描述

我们确实有 2 个类似的应用项目。第一个是我的国家,第二个是欧盟。它们 %90 相同可能更多。我们确实希望将这两个项目合二为一,并使用构建变体在它们之间切换。那可能吗 ?如果是,你能告诉我我该怎么做吗?

主要项目

@OnClick(R.id.image_view)
    public void onClicked(View view) {
        if (isXEnabled) {
            ImageView.setimageResource(R.drawable.inactive);
            ImageView.setContentDescription(getString(R.string.passive));
            presenter.sendCommand();
            isEnabled = false;
        } else {
            ImageView.setimageResource(R.drawable.active);
            ImageView.setContentDescription(getString(R.string.active));
            presenter.disableFeature();
            isEnabled = true;
        }
    }

欧盟项目

@OnClick(R.id.image_view)
    public void onClicked(View view) {
        if (isXEnabled) {
            ImageView.setimageResource(R.drawable.EuInactive);
            ImageView.setContentDescription(getString(R.string.EUpassive));
            presenter.sendCommand();
            isEnabled = false;
        } else {
            ImageView.setimageResource(R.drawable.active);
            ImageView.setContentDescription(getString(R.string.EUactive));
            presenter.disableFeature();
            isEnabled = true;
        }
    }

例如一些 drawable 在欧盟项目上是不同的

- 或 -

主要项目

@OnClick(R.id.image_view)
    public void onClicked(View view) {
        if (isXEnabled) {
            ImageView.setimageResource(R.drawable.inactive);
            ImageView.setContentDescription(getString(R.string.passive));
            presenter.sendCommand();
            isEnabled = false;
            DoSomething();
        } else {
            ImageView.setimageResource(R.drawable.active);
            ImageView.setContentDescription(getString(R.string.active));
            presenter.disableFeature();
            isEnabled = true;
        }
    }

欧盟项目

@OnClick(R.id.image_view)
    public void onClicked(View view) {
        if (isXEnabled) {
            ImageView.setimageResource(R.drawable.inactive);
            ImageView.setContentDescription(getString(R.string.passive));
            presenter.sendCommand();
            isEnabled = false;
            DoSomethingElse();
        } else {
            ImageView.setimageResource(R.drawable.active);
            ImageView.setContentDescription(getString(R.string.active));
            presenter.disableFeature();
            isEnabled = true;
        }
    }

在这个例子中,我们确实添加了不同的行,其他一切都相似。

有近千个这种差异和近五百个完全相同的类和两百个新类。

总而言之,我如何在一个项目中使用构建变体来管理这两个项目

编辑 2 :我已经尝试过这些步骤。

1- 实现维度 2-实现风味 3- 为欧盟项目创建 res,asset,java 文件 4- 在 gradle 中为欧盟项目创建 sourceSet

现在构建变体看起来像这个 mainDevDebug,EuDevDebug,...等 主要......那些工作正常,但我对欧盟有一个错误.......那些

重建或运行应用程序时的错误消息

Could not determine the dependencies of task ':app:compileEuTestDebugJavaWithJavac'.
> Could not resolve all task dependencies for configuration ':app:EuTestDebugCompileClasspath'.
   > Could not resolve project :com.xx.core.main.core.
     required by:
         project :app
      > No matching configuration of project :com.xx.core.main.core was found. The consumer was configured to find an API of a component,as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug',attribute 'project' with value 'Eu',attribute 'default' with value 'Test',attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm' but:
          - None of the consumable configurations have attributes.

解决方法

从您发布的代码和评论来看,我相信您可以通过产品口味 read more here 实现您的目标。

在您的 APP 级 build.gradle 中,您可以执行以下操作:

android {  
    flavorDimensions 'default'
    productFlavors {

        foo{
            dimension 'default'
        }

        bar{
            dimension 'default'
        }

    }
}

这将为您定义两种不同的产品风味,特别是 foobar。完成 gradle 同步后,您将看到现在可以将这些作为构建变体使用。

enter image description here

接下来您要做的是创建一个类似于以下内容的文件夹结构: enter image description here

bar 创建一个文件夹,为 foo 创建一个文件夹,并将该文件夹保留为 main,每个文件夹内的包签名与您的主要结构所使用的相匹配。如果您有不同的图像资源,请确保它们位于此处的适当文件夹中。如果您正在努力创建特定类型的文件/文件夹,我建议您将其复制过来。

main 中的所有内容都将用于两种类型的应用程序,因此所有相同的逻辑都将保留在那里。所有可能不同的内容都将驻留在 barfoo 的文件夹中。就我而言,一个名为 Example:

的简单类
class Example {

    fun giveValue(context: Context): String {
        return context.getString(R.string.value)
    }
}

这两个类的实现在两个文件夹中完全相同,尽管您的可能(并且将会)完全不同。

您还会看到我已将 strings.xml 添加到我的产品风格中(在您的情况下,这可能也是图像资源),我已添加以下字符串:

<resources>
    <string name="value">from bar</string>
</resources>

进入bar目录下的strings.xml和

<resources>
    <string name="value">from foo</string>
</resources>

进入foo目录下的strings.xml

我的 Example 类因此只返回该值基于构建变体

就是这样。

在我的主要活动中:

  val result = Example().giveValue(this)
        Log.v("testing",result) 

因此,根据我使用的构建变体(fooDebug or barDebug),输出会有所不同。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...