🔥🔥🔥 Latest adaptation of Flutter 2.2

I’m Zero. Without further ado, I’ll give you the brain map

  • After the first look, update forever 👏

As long as you pay attention to Flutter, this article is absolutely necessary for you. I strongly recommend ➕ favorites

Multi-channel package introduction

The main function of multi-channel packaging is to meet the operational needs of products, statistics of channels and activity effects. In the past, native (Android, iOS) development apps had various tools to help us complete multi-channel packaging. We also need to be responsible for channel functions during development. Native development tools basically meet the requirements for debugging channel package content, but more configuration is required on Flutter to complete this process. The following sections will introduce the whole process and details from configuration => debugging => packaging.

Multi-channel configuration

Since Flutter V1.17, the Flutter command tool has added the ability to customize the parameters — Dart-define. You can use this command parameter to set the parameters when you pack or run your App.

First determine the Flutter version. Mine is V1.22.6

flutter run --dart-define=APP_CHANNEL=ZeroFlutter
Copy the code

Of course you can pass multiple sets of arguments

flutter run --dart-define=APP_CHANNEL=ZeroFlutter --dart-define=OTHER_VAR=Dart
Copy the code

You need to write this in the Dart code, which must correspond to the command parameters

// main.dart
class EnvironmentConfig {
  static const APP_CHANNEL = String.fromEnvironment('APP_CHANNEL');
  static const OTHER_VAR = String.fromEnvironment('OTHER_VAR');
}
Copy the code

Run to view results

  • To modify theFlutterThe code corresponding to the project
// my_home_page.dart
Text(
  'the App channels:${EnvironmentConfig.APP_CHANNEL}',
  style: Theme.of(context).textTheme.bodyText1,
),
Text(
  'Other parameters:${EnvironmentConfig.OTHER_VAR}',
  style: Theme.of(context).textTheme.bodyText1,
),
Copy the code
  • And then run the project
flutter run --dart-define=APP_CHANNEL=ZeroFlutter --dart-define=OTHER_VAR=Dart
Copy the code
  • View the results



Here you can see that the corresponding parameter content has been displayed, the next is the specific business layer how to use the problem, the following content will also introduce the use scenario, continue to see 👇

Multi-channel debugging

We’ve already seen some of the results, but it’s not possible to run them from the command line all the time. It would be nice if you could debug with the IDE for multiple channels. Here’s how to configure VS Code and Android Studio.

VS Code configuration

  • So let’s create onelaunch.jsonStartup file

  • Then configure the startup parameter project
{
    "version": "0.2.0"."configurations": [{"name": "Flutter"."request": "launch"."type": "dart".// Here is the new command parameter
            "args": [
                "--dart-define"."APP_CHANNEL=Flutter"."--dart-define"."OTHER_VAR=Dart"]},// Configure multiple channels
        {
            "name": "Mi"."request": "launch"."type": "dart"."args": [
                "--dart-define"."APP_CHANNEL=Mi"."--dart-define"."OTHER_VAR= Android light"]]}}Copy the code

Then the configured channel information appears here, and we switch separatelyFlutterMiRun it and see what it looks like



Android Studio configuration

  • Set command parameters first

  • addMiChannel configuration parameters

Let me copy thatFlutterConfigure and change the name toMiAnd change the command parameter toMiThe light of the android



Now that Android Studio’s configuration is almost complete, let’s switch to running and see what it looks like





Here has completed the IDE configuration, [detailed configuration files can be accessed from GitHub in the project], said so much how do not say packaging 📦 things, don’t worry I need to configure a sophisticated equipment for you, behind our packaging is a command of the matter.

Configure the native packaging script

🔥🔥🔥 Latest adaptation of Flutter 2.2

Android

  • To change theGradleconfiguration

Androidmanifest.xml
The Gradle configuration needs to be changed to get the channel command parameters (–dart-define=APP_CHANNEL=ZeroFlutter –dart-define=OTHER_VAR= dart)

// android/app/build.gradle
// set the default value
def dartEnvironmentVariables = [
    APP_CHANNEL: 'main'.OTHER_VAR: 'other',]if (project.hasProperty('dart-defines')) {
    dartEnvironmentVariables = dartEnvironmentVariables + project.property('dart-defines')
        .split(', ')
        .collectEntries { entry ->
            / / 1.22.6 version
            //def pair = URLDecoder.decode(entry).split('=')
            / / 2.2 version
            def pair = new String(entry.decodeBase64(), 'UTF-8').split('=')
            [(pair.first()): pair.last()]
        }
}
Copy the code
  • How to use (rename APK)
// android/app/build.gradle
android{
    // Rename apk
    applicationVariants.all { variant ->
        variant.outputs.all { output ->
            if(variant.buildType.name == "release") {// Get the version
                def versionName = variant.versionName
                def versionCode = variant.versionName
             	// Set a new name
                def newApkName ="app_v${defaultConfig.versionName}_${defaultConfig.versionCode}_channel_${dartEnvironmentVariables.APP_CHANNEL}.apk"
                outputFileName = new File(newApkName)
            }
        }
    }
}
Copy the code
  • Perform packaging
Flutter build apk --dart-define=APP_CHANNEL=ZeroFlutter --dart-define=OTHER_VAR= apK output path Built Build/app/outputs/flutter - apk/app - the apk (15.4 MB). / / open the package after the apk open the build/app/outputs/apk/release /Copy the code



Here you see that the packaged APK has been renamed toApp_v1. 0.0 _1_channel_ZeroFlutter. ApkSo we can publish to different app stores.

iOS

Here, iOS packaging needs to execute the build command first, and then go to Xcode for packaging and uploading

flutter build ios --dart-define=APP_CHANNEL=ZeroFlutter --dart-define=OTHER_VAR=Dart
Copy the code

Package script optimization

At this time, if we execute the Mi channel package command again, we will find that the previously packed APP_v1.0.0_1_channel_zeroflutter. Apk disappeared because it was cleaned, so we move the APK to a channel package folder after each package. Then proceed to the next channel packaging.

Flutter build apk --dart-define=APP_CHANNEL=Mi --dart-define=OTHER_VAR=Copy the code

The optimized script is as follows:

  • Channel packaging script
# fapk_channel.sh
flutter build apk --dart-define=APP_CHANNEL=$1 --dart-define=OTHER_VAR=$2
cd build/app/outputs/apk/release/
cp -R *.apk /Users/zero/apk/$1/
cd /Users/zero/apk/$1/
open .
Copy the code
  • Bulk packaging
Sh ZeroFlutter Dart fapk_channel.sh Mi Android lightCopy the code



The packing is done automatically, and when the script is launched, you can go grab a cup of coffee, and the coffee is packed.

Once packed, we can test channel packs separately and then upload them to the respective app stores

Usage scenarios

Data statistics

On the operation side, it is necessary to make statistics on download, installation, use, daily activity, weekly activity, monthly activity and activity effect of each App store (channel). Therefore, it is necessary to differentiate by channel. The following figure shows the distribution of daily activity channels of our App.



On the development side, we need to distinguish the abnormal situation of each channel, and the corresponding symbol files are also different when packaging. For example, Bugly can be configured in this way to complete the configuration of symbol files of different channels.

// android/app/build.gradle bugly { appId = 'ZeroFlutter' appKey = 'GitHub:https://github.com/yy1300326388' // Here channel configuration parameters can be appChannel = "${dartEnvironmentVariables. APP_CHANNEL}}"Copy the code

For example, if we need to set up the Friendly Alliance channel information, we can directly call the Api setting through the Dart code.

/// Initialize the friendship directly to environmentConfig.app_CHANNEL Parameter of the incoming channel
UmengSdk.initCommon(kUmengAndroidAppkey, kUmengIosAppkey, EnvironmentConfig.APP_CHANNEL);
Copy the code

Then you can see the statistical data in the background, which is convenient for our further operation and development

Channels of distribution

The requirements of each app store are different. Some card case configuration, card copyright information and card permission may require different processing according to different channels. We can add a judgment to deal with different logic, or use mixin

EnvironmentConfig.APP_CHANNEL == 'Mi'
? Text(
  "Xiaomi Channel Display",
  style: Theme.of(context).textTheme.bodyText1,
)
: SizedBox()
Copy the code

Here we run separatelyZeroFlutterMiChannel to see the effect

conclusion

This is the end of this article, we mainly talk about the use of command parameters configuration, as well as in the development process of channel package IDE configuration and debugging skills, finally talk about channel package usage scenarios. This article is the first of a series of articles entitled “Buried Spot Statistics in Flutter – How Data and thinking determine Winners and losers”. You can continue to share the following information about Flutter at ✅. You will be notified as soon as the content is updated.

Buried point statistics in Flutter article planning directory

  • Detailed description of Flutter multi-channel packaging
  • Flutter global route monitoring
  • Flutter global exception capture
  • Flutter’s latest global traceless burial site

Source warehouse

The script and sample code are available on GitHub

  • flutter_multi_channel
  • GitHub homepage, click Follow to learn more

🔗 Reference link

  • Flutter 1.17 — No more Flavors, no more iOS Schemas. Command argument that changes everything
  • Creating flavors for Flutter
  • The Flutter command-line tool

About me

  • 15 to 18 years of useAndroidDo original smart hardware related App research and development
  • In May of ’18, I came into contact with him by chanceFlutterAnd then start self-study, you can seeweather_flutterIt is my introduction to Flutter practice. (I still think it is very suitable for Flutter practice.)
  • In August, 2018, under great pressure (Flutter was not released 1.0 at that time), I started to develop enterprise-level projects with Flutter and developed and maintained more than a dozen Flutter plugin packages (due to the lack of plugin resources at that time).
  • Up to now, I have led and participated in the launch of 4 enterprise-level productsFlutterApp, the accumulated users of an App I am currently in charge of120W+, the use ofFlutterIt was a great experience

👏 please like ➕ and follow ➕ to forward. Please feel free to comment on 👇 if you have any questions. I will reply as soon as possible

Pay attention to column

  • This article has been included in the column at 👇 below, you can follow it directly
  • Read more | The series continues to be updated