Flutter插件扩展功能插件flutter_flavorizr_extended的使用

发布于 1周前 作者 songsunli 来自 Flutter

Flutter插件扩展功能插件flutter_flavorizr_extended的使用

TLDR;

  • 与原始flutter_flavorizr的不同之处
    • 不会覆盖Android的signingConfig部分。
    • 兼容现有项目,运行时不会因文件引用和基础结构依赖导致错误。
    • 第一次运行后,不再覆盖可能已手动修改的自定义Dart文件。以下处理器在后续运行中被跳过:
      // 'flutter:flavors',
      // 'flutter:app',
      // 'flutter:pages',
      // 'flutter:main',
      // 'flutter:targets',
      

安装

buildspec.yaml中添加以下内容:

dev_dependencies:
  flutter_flavorizr_extended: ^0.0.7

开始使用示例配置

步骤0: 配置pubspec.yaml

假设我们需要4个口味(development, qa, uat, prod):

name: flutter_template_app
description: "A new Flutter project."
publish_to: 'none'
version: 0.1.0

environment:
  sdk: ^3.5.3

dependencies:
  flutter:
    sdk: flutter

dev_dependencies:
  flutter_test:
    sdk: flutter
  flutter_lints: ^5.0.0
  flutter_flavorizr_extended: ^0.0.4

flutter:
  uses-material-design: true

flavorizr:
  flavors:
    development:
      app:
        name: "FlutterTemplateApp"
      android:
        applicationId: "go.template.flutter"
        generateDummyAssets: true
        icon: "assets/images/icons/appicon.png"
        customConfig:
          applicationIdSuffix: "\".development\""
          versionNameSuffix: "\"Dev\"" # 不要忘记用\转义字符串
          signingConfig: signingConfigs.debug
      ios:
        bundleId: "go.template.flutter.development"
        generateDummyAssets: true
        icon: "assets/images/icons/appicon.png"
    qa:
      app:
        name: "FlutterTemplateApp"
      android:
        applicationId: "go.template.flutter.qa"
        generateDummyAssets: true
        icon: "assets/images/icons/appicon.png"
        customConfig:
          applicationIdSuffix: "\".qa\""
          versionNameSuffix: "\"QA\"" # 不要忘记用\转义字符串
          signingConfig: signingConfigs.qa
      ios:
        bundleId: "go.template.flutter.qa"
        generateDummyAssets: true
        icon: "assets/images/icons/appicon.png"
    uat:
      app:
        name: "FlutterTemplateApp"
      android:
        applicationId: "go.template.flutter"
        generateDummyAssets: true
        icon: "assets/images/icons/appicon.png"
        customConfig:
          applicationIdSuffix: "\".uat\""
          versionNameSuffix: "\"UAT\"" # 不要忘记用\转义字符串
          signingConfig: signingConfigs.uat
      ios:
        bundleId: "go.template.flutter.uat"
        generateDummyAssets: true
        icon: "assets/images/icons/appicon.png"
    prod:
      app:
        name: "FlutterTemplateApp"
      android:
        applicationId: "go.template.flutter"
        generateDummyAssets: true
        icon: "assets/images/icons/appicon.png"
        customConfig:
          signingConfig: signingConfigs.release
      ios:
        bundleId: "go.template.flutter"
        generateDummyAssets: true
        icon: "assets/images/icons/appicon.png"
步骤1: 确保图标存在

确保你的应用图标正确放置在指定路径。

步骤2: Android签名配置

确保所有在pubspec.yaml中列出的签名配置都存在。

1: 生成签名密钥

运行以下命令创建用于签名应用的密钥库:

keytool -genkey -V -keystore template_app.jks -storetype JKS -keyalg RSA -keysize 2048 -validity 10000 -alias template_app_key
2: 组织密钥库

在项目目录下创建一个名为keystores的文件夹,并将生成的template_app.jks文件放入其中。

3: 创建key.properties文件

创建一个名为key.properties的文件,内容如下。切勿将此文件推送到公共仓库!

development.keyAlias=template_app_key
development.keyPassword=<Your password>
development.storeFile=../keystores/template_app.jks
development.storePassword=<Your password>

qa.keyAlias=template_app_key
qa.keyPassword=<Your password>
qa.storeFile=../keystores/template_app.jks
qa.storePassword=<Your password>

uat.keyAlias=template_app_key
uat.keyPassword=<Your password>
uat.storeFile=../keystores/template_app.jks
uat.storePassword=<Your password>

prod.keyAlias=template_app_key
prod.keyPassword=<Your password>
prod.storeFile=../keystores/template_app.jks
prod.storePassword=<Your password>
4: 更新app/build.gradle

app/build.gradle中添加以下签名配置部分:

signingConfigs {
    debug {
        if (System.getenv()["CI"]) { // CI=true is exported by Codemagic
            storeFile file(System.getenv()["CM_KEYSTORE_PATH"])
            storePassword System.getenv()["CM_KEYSTORE_PASSWORD"]
            keyAlias System.getenv()["CM_KEY_ALIAS"]
            keyPassword System.getenv()["CM_KEY_PASSWORD"]
        } else {
            keyAlias keyProperties['dev.keyAlias']
            keyPassword keyProperties['development.keyPassword']
            storeFile keyProperties['development.storeFile'] ? file(keyProperties['development.storeFile']) : null
            storePassword keyProperties['dev.storePassword']
        }
    }
    qa {
        if (System.getenv()["CI"]) { // CI=true is exported by Codemagic
            storeFile file(System.getenv()["CM_KEYSTORE_PATH"])
            storePassword System.getenv()["CM_KEYSTORE_PASSWORD"]
            keyAlias System.getenv()["CM_KEY_ALIAS"]
            keyPassword System.getenv()["CM_KEY_PASSWORD"]
        } else {
            keyAlias keyProperties['qa.keyAlias']
            keyPassword keyProperties['qa.keyPassword']
            storeFile keyProperties['qa.storeFile'] ? file(keyProperties['qa.storeFile']) : null
            storePassword keyProperties['qa.storePassword']
        }
    }
    uat {
        if (System.getenv()["CI"]) { // CI=true is exported by Codemagic
            storeFile file(System.getenv()["CM_KEYSTORE_PATH"])
            storePassword System.getenv()["CM_KEYSTORE_PASSWORD"]
            keyAlias System.getenv()["CM_KEY_ALIAS"]
            keyPassword System.getenv()["CM_KEY_PASSWORD"]
        } else {
            keyAlias keyProperties['uat.keyAlias']
            keyPassword keyProperties['uat.keyPassword']
            storeFile keyProperties['uat.storeFile'] ? file(keyProperties['uat.storeFile']) : null
            storePassword keyProperties['uat.storePassword']
        }
    }
    release {
        if (System.getenv()["CI"]) { // CI=true is exported by Codemagic
            storeFile file(System.getenv()["CM_KEYSTORE_PATH"])
            storePassword System.getenv()["CM_KEYSTORE_PASSWORD"]
            keyAlias System.getenv()["CM_KEY_ALIAS"]
            keyPassword System.getenv()["CM_KEY_PASSWORD"]
        } else {
            keyAlias keyProperties['prod.keyAlias']
            keyPassword keyProperties['prod.keyPassword']
            storeFile keyProperties['prod.storeFile'] ? file(keyProperties['prod.storeFile']) : null
            storePassword keyProperties['prod.storePassword']
        }
}
步骤3: 生成所有口味

运行以下命令生成所有口味:

flutter pub run flutter_flavorizr_extended -r initializationRun
步骤4: iOS签名配置

确保应用程序包标识符与App Store中的相同。

打开iOS目录并使用Xcode。你应该能看到自动生成的配置文件:

点击"-"按钮删除原有的Debug, Profile, Release配置,因为我们不需要它们。

步骤5: 最终设置

完成上述所有步骤后,运行以下命令更新配置:

flutter pub run flutter_flavorizr_extended -r updateRun

注意,你可以随时回来重新生成配置,这将不会重写你现有的main*.dart文件。

步骤6: 如果需要更改配置怎么办?

当前Android代码应手动删除。

  1. 删除Android app build.gradle中的以下代码:

  2. 重新运行以下命令:

flutter pub run flutter_flavorizr_extended -r updateRun

更多关于Flutter插件扩展功能插件flutter_flavorizr_extended的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter插件扩展功能插件flutter_flavorizr_extended的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用flutter_flavorizr_extended插件的一个示例。这个插件通常用于管理和扩展Flutter项目的Flavors(多渠道打包),以便于根据不同的环境(例如开发、测试、生产)配置不同的设置。

首先,确保你已经在pubspec.yaml文件中添加了flutter_flavorizr_extended依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_flavorizr_extended: ^latest_version  # 请替换为最新的版本号

然后,运行flutter pub get来安装依赖。

接下来,你需要配置你的flavorizr.yaml文件,这个文件用于定义不同的Flavor配置。以下是一个简单的示例:

flavors:
  dev:
    applicationIdSuffix: ".dev"
    versionNameSuffix: "-dev"
    buildConfigField:
      - key: "API_BASE_URL"
        value: "\"https://dev.api.example.com/\""
  prod:
    applicationIdSuffix: ""
    versionNameSuffix: ""
    buildConfigField:
      - key: "API_BASE_URL"
        value: "\"https://api.example.com/\""

在上面的配置中,我们定义了两个Flavor:devprod,每个Flavor都有自己的applicationIdSuffixversionNameSuffixbuildConfigField

接下来,在你的android/app/build.gradle文件中,添加对Flavorizr插件的支持:

apply from: "$flutterSdk/packages/flutter_tools/gradle/flavorizr.gradle"

android {
    ...
    flavorDimensions "version"

    productFlavors {
        dev {
            dimension "version"
        }
        prod {
            dimension "version"
        }
    }
}

然后,在你的Flutter代码中,你可以通过BuildConfig类访问在flavorizr.yaml文件中定义的字段。例如,你可以这样获取API的基础URL:

import 'package:flutter/foundation.dart' show kReleaseMode;

String getApiBaseUrl() {
  if (kReleaseMode) {
    return BuildConfig.API_BASE_URL_PROD;  // 确保在生成的BuildConfig中有这个字段
  } else {
    return BuildConfig.API_BASE_URL_DEV;  // 确保在生成的BuildConfig中有这个字段
  }
}

void main() {
  print('API Base URL: ${getApiBaseUrl()}');
  runApp(MyApp());
}

注意:实际上,flutter_flavorizr_extended插件可能会自动生成不同的BuildConfig类,这些类会包含你在flavorizr.yaml中定义的字段。但是,由于flutter_flavorizr_extended的具体实现细节可能有所不同,你可能需要检查生成的Android代码来确认字段的确切名称。在某些情况下,你可能需要在flavorizr.yaml中使用特定的语法来确保字段被正确生成。

另外,由于Flutter和插件的生态系统在不断变化,建议查阅flutter_flavorizr_extended的官方文档和示例代码以获取最新的使用指南和最佳实践。

最后,运行以下命令来构建特定Flavor的应用:

flutter build apk --flavor dev
flutter build apk --flavor prod

这将根据指定的Flavor构建你的应用。

回到顶部