我如何将 2 个类似的项目与 Android Build Variant 结合起来?
How can I combine 2 Similar Projects With 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;
}
}
例如,某些可绘制对象在 EU 项目中有所不同
- 或 -
主要项目
@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:我已经尝试了这些步骤。
- 执行维度
- 实施风味
- 为 eu 项目创建了 res,asset,java 文件
- 在 gradle 中为欧盟项目创建了 sourceSet
现在构建变体看起来像这样 mainDevDebug、EuDevDebug、...等
main ...... ones 工作正常但我对 Eu 有错误...... ones
重建或 运行 应用程序时出现错误消息:
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'
}
}
}
这将为您定义两种不同的产品口味,特别是 foo
和 bar
。在进行 gradle 同步后,您会看到这些现在可以作为构建变体使用。
接下来您要做的是创建一个与此类似的文件夹结构:
为 bar
创建一个文件夹,为 foo
创建一个文件夹,并为 main 创建一个文件夹,每个文件夹中的包签名与您的主要结构使用的相匹配。如果您有不同的图像资源,请确保它们位于此处的适当文件夹中。如果您正在努力创建特定类型的 file/folder,我建议您将其复制过来。
main 中的所有内容都将在两种类型的应用程序中使用,因此所有相同的逻辑都将保留在那里。所有可能不同的内容都将驻留在 bar
和 foo
的文件夹中。在我的例子中,一个简单的 class 叫做 Example
:
class Example {
fun giveValue(context: Context): String {
return context.getString(R.string.value)
}
}
这两个 class 的实现在两个文件夹中完全相同,尽管您的可能(并且将会)完全不同。
您还会看到我已将 strings.xml 添加到我的产品风格中(在您的情况下,也许这也是图像资源),我添加了以下字符串:
<resources>
<string name="value">from bar</string>
</resources>
进入 bar
目录下的 strings.xml 和
<resources>
<string name="value">from foo</string>
</resources>
进入foo
目录下的strings.xml
my Example
class 因此只是 returns 无论这个值是什么 基于构建变体
就是这样。
在我的主要 activity:
val result = Example().giveValue(this)
Log.v("testing", result)
因此,根据我使用的构建变体(fooDebug or barDebug
),输出会有所不同。
我们确实有 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;
}
}
例如,某些可绘制对象在 EU 项目中有所不同
- 或 -
主要项目
@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:我已经尝试了这些步骤。
- 执行维度
- 实施风味
- 为 eu 项目创建了 res,asset,java 文件
- 在 gradle 中为欧盟项目创建了 sourceSet
现在构建变体看起来像这样 mainDevDebug、EuDevDebug、...等 main ...... ones 工作正常但我对 Eu 有错误...... ones
重建或 运行 应用程序时出现错误消息:
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'
}
}
}
这将为您定义两种不同的产品口味,特别是 foo
和 bar
。在进行 gradle 同步后,您会看到这些现在可以作为构建变体使用。
接下来您要做的是创建一个与此类似的文件夹结构:
为 bar
创建一个文件夹,为 foo
创建一个文件夹,并为 main 创建一个文件夹,每个文件夹中的包签名与您的主要结构使用的相匹配。如果您有不同的图像资源,请确保它们位于此处的适当文件夹中。如果您正在努力创建特定类型的 file/folder,我建议您将其复制过来。
main 中的所有内容都将在两种类型的应用程序中使用,因此所有相同的逻辑都将保留在那里。所有可能不同的内容都将驻留在 bar
和 foo
的文件夹中。在我的例子中,一个简单的 class 叫做 Example
:
class Example {
fun giveValue(context: Context): String {
return context.getString(R.string.value)
}
}
这两个 class 的实现在两个文件夹中完全相同,尽管您的可能(并且将会)完全不同。
您还会看到我已将 strings.xml 添加到我的产品风格中(在您的情况下,也许这也是图像资源),我添加了以下字符串:
<resources>
<string name="value">from bar</string>
</resources>
进入 bar
目录下的 strings.xml 和
<resources>
<string name="value">from foo</string>
</resources>
进入foo
目录下的strings.xml
my Example
class 因此只是 returns 无论这个值是什么 基于构建变体
就是这样。
在我的主要 activity:
val result = Example().giveValue(this)
Log.v("testing", result)
因此,根据我使用的构建变体(fooDebug or barDebug
),输出会有所不同。