问题描述
我想为不同的构建变体创建 2 个版本的 Fragment
,比如整个代码在风格 1 和风格 2 中会有所不同。我想解决这个问题,而不是基于 BuildConfig.FLAVOR
做 if-else代码中的参数。这意味着如果我有 MapFragment
,当构建不同的风格时,我希望有完全相同的名为 MapFragment
的类,但代码不同。我想这样做的原因是我不想从其他版本(风味
在我的应用程序上的任何日志或细节中。这应该像 MapFragment
本地化正在工作或 string.xml
一样工作。有什么办法可以实现吗?
这样做的原因是我正在使用华为地图和 dimens.xml
服务以及 Google Play 地图。问题是华为正在使用一些后台位置服务,然后在 Google Play 上拒绝了我的应用程序。 Google Play 上永远不应该提供这种华为风味,它就像华为商店应用程序的独立副本。
这意味着,如果我从 Google Play(风格 1)构建 ag-connect
,我将不会包含任何 ag-connect 服务或类或来自华为风格的引用/导入,反之亦然。
更新:
当我查看下面的评论时,我尝试创建 sourceSets 并将我的风格重新实现到这些新集合中。但是还是不能编译。
我还需要知道如何将这些风格与类型和来源结合起来。因为我有两个主要来源:谷歌和华为。然后,我需要 4 种版本,例如 googleProd、googleProdTest、googleDev、googleDevTest 和 huawei 的相同版本,并且所有这些都应该具有构建类型调试/发布,以防我想将它们发布到 Google Play 商店进行测试。问题是我需要类似产品副口味的东西。每个 huawei 版本(prod、test、dev、dev-test)将使用 huawei sourceSet(main+huawei),每个 google 版本(prod、test、dev、dev-test)将使用 google sourceSet(main+google)。这意味着主要来源将是两者通用的代码,而 google/huawei 来源具有相同 Fragment 的不同版本。
所以这些应该是最终的 buildVariants:
- googleProd (main+google src)
- googleTest (main+google src)
- googleDev (main+google src)
- googleDevTest (main+google src)
- huaweiProd (main+huawei src)
- huaweiTest (main+huawei src)
- huaweiDev (main+huawei src)
- huaweiDevTest (main+huawei src)
以及所有 8 个版本的发布/调试构建类型。因此总共 16 个变体。
这意味着我需要知道如何将 .apk
src 与 google
、prod
、test
和 dev
风味以及 dev-test
src 合并带有 huawei
、huaweiProd
、huaweiTest
和 huaweiDev
口味,所以我不需要有 4 个相同的 huawei Fragment 和 4 个相同的所有口味的 google 片段。它应该像抽象类/父类一样工作。
huaweiDev-test
代码摇篮:
A problem occurred evaluating project ':app'.
No signature of method: build_1t7zaa85nxlbgjo4n3n9fcb4s.android() is applicable for argument types: (build_1t7zaa85nxlbgjo4n3n9fcb4s$_run_closure1) values: [build_1t7zaa85nxlbgjo4n3n9fcb4s$_run_closure1@56b08118]
解决方法
也许你可以把不同的实现类放在不同的目录中,但包名和父类或接口必须相同,然后在flavor config中重置srcDirs。 https://developer.android.com/studio/build/build-variants#sourcesets
例如:
- 创建风味源目录
app/src/google/java
app/src/huawei/java
- 在 app/build.gradle 中重置 srcDirs
plugins {
id 'com.android.application'
}
android {
compileSdkVersion 30
buildToolsVersion "30.0.3"
defaultConfig {
applicationId "com.example"
minSdkVersion 21
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
debug {
minifyEnabled false
}
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
flavorDimensions("map",'type')
productFlavors {
google {
dimension "map"
}
huawei {
dimension "map"
apply plugin: 'com.huawei.agconnect'
}
shopDev {
dimension "type"
}
shopProd {
dimension "type"
}
shopTest {
dimension "type"
}
}
applicationVariants.all { variant ->
def name = variant.name
println("Starryi: " + name)
if (name.contains('huawei')) {
if (name.contains('ShopDev')) {
variant.buildConfigField("String","APP_FLAVOR_NAME",'\"HUAWEI_SHOP_DEV\"')
} else if (name.contains('ShopTest')) {
variant.buildConfigField("String",'\"HUAWEI_SHOP_TEST\"')
} else if (name.contains('ShopProd')) {
variant.buildConfigField("String",'\"HUAWEI_SHOP_PROD\"')
}
} else if (name.contains('google')) {
if (name.contains('ShopTest')) {
variant.buildConfigField("String",'\"GOOGLE_SHOP_DEV\"')
} else if (name.contains('ShopDev')) {
variant.buildConfigField("String",'\"GOOGLE_SHOP_TEST\"')
} else if (name.contains('ShopProd')) {
variant.buildConfigField("String",'\"GOOGLE_SHOP_PROD\"')
}
}
}
sourceSets {
google {
java.srcDirs('/src/main/java','src/google/java')
}
huawei {
java.srcDirs('/src/main/java','src/huawei/java')
}
}
}
dependencies {
huaweiImplementation 'com.huawei.hms:identity:4.0.1.300'
huaweiImplementation 'com.huawei.hms:location:4.0.3.303'
huaweiImplementation 'com.huawei.hms:maps:4.0.1.301'
}
如果你想完全隔离google sdk和huawei sdk,你可以创建两个不同的库模块,一个用于谷歌地图,另一个用于华为地图(两个地图模块必须具有相同的公共接口,通过某种安排),然后编辑app/build.gradle 使风味取决于适当的模块。 https://developer.android.google.cn/studio/build/dependencies?hl=en#variant_aware https://developer.android.com/studio/build/build-variants#dependencies