如何为风味变体创建两个不同版本的代码

问题描述

我想为不同的构建变体创建 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:

  1. googleProd (main+google src)
  2. googleTest (main+google src)
  3. googleDev (main+google src)
  4. googleDevTest (main+google src)
  5. huaweiProd (main+huawei src)
  6. huaweiTest (main+huawei src)
  7. huaweiDev (main+huawei src)
  8. huaweiDevTest (main+huawei src)

以及所有 8 个版本的发布/调试构建类型。因此总共 16 个变体。

这意味着我需要知道如何将 .apk src 与 googleprodtestdev 风味以及 dev-test src 合并带有 huaweihuaweiProdhuaweiTesthuaweiDev 口味,所以我不需要有 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

例如:

  1. 创建风味源目录
app/src/google/java
app/src/huawei/java

  1. 在 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'
}
  1. 在构建变体窗口中选择 enter image description here

如果你想完全隔离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

相关问答

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