Практика многоканальной упаковки Flutter

Flutter

задний план

  При нативной разработке часто требуются разные пакеты по разным каналам, в основном в следующих сценариях:

  • Среда разработки, тестовая среда, производственная среда и т. д.

  Соответствующие требования разных сред также отличаются, поэтому требуется типировать разные пакеты в соответствии с требованиями для удобной разработки и тестирования.

  • различные рынки приложений и т. д.

Поскольку в Китае много рынков приложений, разные рынки приложений могут иметь разные статистические требования, поэтому разработчикам необходимо выпустить установочный пакет для каждого рынка приложений и добавить в установочный пакет разные логотипы, чтобы отличать каждое приложение. удобно считать различные эффекты приложения на рынке приложений.

   Поэтому всякий раз, когда выпускается новая версия, операция будет предоставлять список каналов, и разработчики будут генерировать такое же количество пакетов каналов в соответствии с этими каналами. С увеличением количества каналов, чтобы повысить эффективность упаковки каналов, родились исследования методов многоканальной упаковки.

   Эта проблема также связана с разработкой проекта Flutter, Здесь мы в основном говорим о том, как настроить пакет разработки и производственный пакет, а также быстро набрать и запустить соответствующий пакет канала.

   Здесь я объясню конфигурацию со стороны Android, IOS и Flutter соответственно.

Конфигурация Android

Для Android нам нужно только настроить productFlavors в модуле приложения gradle Здесь мы определяем два варианта, dev и production, под android в build.gradle.

[...]

android {
   
    [...]

    flavorDimensions "app"

    productFlavors {
        dev {//development
            dimension "app"
            resValue "string", "app_name", "多渠道打包${defaultConfig.versionCode}"   // 设置默认的app_name
            applicationId "${defaultConfig.applicationId}.dev"
            manifestPlaceholders = [
                    QQ_APP_ID: "xxx",
                    CHANNEL_NAME: "dev",
                    LOCATION_APP_KEY : "xxx", /// 高德地图key
            ]
        }
        production{
            dimension "app"
        }
    }

}

[...]

Конфигурация очень проста, здесь можно установить различные суффиксы приложения applicationId, Вы также можете установить app_name, CHANNEL_NAME для разных вкусов.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.xx.xx">

    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:usesCleartextTraffic="true"
        android:name="io.flutter.app.FlutterApplication"
        android:label="@string/app_name"
        android:icon="@mipmap/ic_launcher">
        <activity
            android:name=".MainActivity"
            android:theme="@style/LaunchTheme"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection"
            android:hardwareAccelerated="true"
            android:windowSoftInputMode="adjustResize">
            <!-- This keeps the window background of the activity showing
                 until Flutter renders its first frame. It can be removed if
                 there is no splash screen (such as the default splash screen
                 defined in @style/LaunchTheme). -->
            <meta-data
                android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
                android:value="true" />

            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        <!--        多渠道打包           -->
        <meta-data
            android:name="UMENG_CHANNEL"
            android:value="${CHANNEL_NAME}" />
    </application>
</manifest>

конфигурация iOS

Для ios нам нужно только создать соответствующий файл конфигурации для каждого варианта в папке ios/Flutter, точно так же, как предопределенные по умолчанию Debug.xcconfig и Release.xcconfig во Flutter, потому что официальному производственному пакету не нужно менять имя пакета. и имя приложения, поэтому здесь создаются только два файла, dev_debug.xcconfig и dev_release.xcconfig.

И настройте bundle_suffix и name_suffix в xcconfig, соответствующие версии dev.

#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"
bundle_suffix=.dev
name_suffix=${FLUTTER_BUILD_NUMBER}

и добавьте определенную переменную в файл Info.plist

Затем создайте соответствующую схему для каждого вкуса

Не забудьте проверить общий доступ в диалоговом окне

Теперь выберите проект Runner и добавьте нужную конфигурацию в качестве файла конфигурации, созданного ранее.

Обратите внимание, что для каждого варианта есть две конфигурации с именами Release-[flavorName] и Debug-[flavorName]. Будьте осторожны, чтобы не повторять имя здесь.

Чтобы iOS-приложение использовало правильную конфигурацию при упаковке и публикации, необходимо отредактировать здесь схему и установить нужную конфигурацию сборки:

Конфигурация флаттера

Переименуйте main.dart в main_common.dart, определите здесь общую конфигурацию и рабочие части, затем создайте файлы main_dev.dart и main_production.dart, введите main_common и установите различные конфигурации в файлах main_dev.dart и main_production.dart в качестве необходимого параметра.

Тестовые ключи для сетевых прокси, сторонних библиотек и т.п. можно задать в main_dev.dart.

import 'dart:io';

import 'package:dio/adapter.dart';
import 'package:flutter_common_utils/http/http_manager.dart';

import 'main_common.dart';

/// @desc 开发、测试环境入口
/// @time 2019-07-17 15:08
/// @author Cheney
Future<Null> main() async {
  await initConfig();

  //debug 抓包
  (HttpManager().client.httpClientAdapter as DefaultHttpClientAdapter)
      .onHttpClientCreate = (client) {
    client.findProxy = (uri) {
      return "PROXY http://10.1.10.111:8080";
    };
    client.badCertificateCallback =
        (X509Certificate cert, String host, int port) {
      return true;
    };
  };

  ///第三方库 测试 key
}

Настройте официальный ключ сторонней библиотеки и т. д. в main_production.dar.

import 'main_common.dart';

/// @desc 正式环境入口
/// @time 2019-07-17 15:08
/// @author Cheney
Future<Null> main() async {
  await initConfig();

  ///第三方库 正式 key todo

  initMaterialApp();
}

Начальная общая конфигурация в main_common:

import 'dart:async';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_common_utils/http/http_manager.dart';
import 'package:flutter_common_utils/log_util.dart';
import 'package:flutter_common_utils/sp_util.dart';
import 'package:oktoast/oktoast.dart';

import 'main.dart';

/// @desc 入口公共部分
/// @time 2019-07-17 15:08
/// @author Cheney
Future<Null> initConfig() async {
  await SpUtil().init();

  //日志输出
  LogUtil.init(isDebug: true);

  //初始化存储管理
//  await StorageUtil.getInstance();
}

///初始化 App
void initMaterialApp() {
  HttpManager().init(
    baseUrl: "xxx",
    interceptors: [],
  );

  runApp(OKToast(child: HomeApp()));
}

Таким образом, его можно запустить в разных каналах из командной строки:

flutter build --flavor dev -t lib/main-dev.dart

flutter build --flavor production -t lib/main-production.dart

Если вы хотите запустить пакет подканала непосредственно в большой IDE, вам нужно отредактировать конфигурацию, чтобы создать две соответствующие конфигурации запуска:

Здесь создаются два элемента конфигурации запуска флаттера, main_dev, main_production.

Выберите соответствующий main_dev.dart, dart_production.dart, созданный выше, в точке входа Dart.

Выберите соответствующий вариант (разработка, производство) в разделе «Сборка».

На этом этапе вы можете запустить соответствующие файлы main_dev и main_production.

наконец

  Если у вас возникнут проблемы во время использования, оставьте сообщение ниже, чтобы сообщить об этом.

Использованная литература:

учебные материалы

Пожалуйста, поднимите палец вверх! Потому что ваши лайки - моя самая большая поддержка, спасибо!