使用风味使用 MS AppCenter 构建 Flutter android APK 的问题
Posted
技术标签:
【中文标题】使用风味使用 MS AppCenter 构建 Flutter android APK 的问题【英文标题】:Issue building Flutter android APK with MS AppCenter using flavors 【发布时间】:2021-01-10 17:36:36 【问题描述】:我一直在关注一系列文章,试图在 MS Appcenter 上构建 Flutter 应用,使用各种风格来实现应用环境(即 dev/test/live)。
为了实现这一点,我使用this article 中所示的单独的main-<environment>.dart
入口文件方法,并遵循this article 来配置Appcenter。
我在构建 android apk 时遇到问题,因为缺少 main.dart
。我认为将-t
参数传递给构建命令可以处理这个问题?
我将在下面添加构建脚本和日志,但正在执行的颤动命令是这样的:flutter build apk --flavor dev --release -t lib/main_dev_test.dart
flutter build apk
命令似乎可以正常完成,但是在 gradle 任务步骤中构建失败并显示以下错误消息:
Task :app:compileFlutterBuildDevRelease FAILED
12 actionable tasks: 2 executed, 10 up-to-date
Error: Error when reading 'lib/main.dart': No such file or directory
package:hello_world/main.dart: Error: No 'main' method found.
Try adding a method named 'main' to your program.
FAILURE: Build failed with an exception.
* Where:
Script '/Users/runner/work/1/s/flutter/packages/flutter_tools/gradle/flutter.gradle' line: 904
* What went wrong:
Execution failed for task ':app:compileFlutterBuildDevRelease'.
> Process 'command '/Users/runner/work/1/s/flutter/bin/flutter'' finished with non-zero exit value 1
在windows本地运行时的输出:
flutter build apk --flavor dev --release -t lib/main_dev_test.dart
You are building a fat APK that includes binaries for android-arm, android-arm64, android-x64.
If you are deploying the app to the Play Store, it's recommended to use app bundles or split the APK to reduce the APK size.
To generate an app bundle, run:
flutter build appbundle --target-platform android-arm,android-arm64,android-x64
Learn more on: https://developer.android.com/guide/app-bundle
To split the APKs per ABI, run:
flutter build apk --target-platform android-arm,android-arm64,android-x64 --split-per-abi
Learn more on: https://developer.android.com/studio/build/configure-apk-splits#configure-abi-split
Running Gradle task 'assembleDevRelease'...
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
Calling mockable JAR artifact transform to create file: C:\Users\_USERFOLDER_\.gradle\caches\transforms-2\files-2.1\5760bf626ba5c024071f2e9f16ccfcc3\android.jar with input C:\Users\_USERFOLDER_\AppData\Local\Android\Sdk\platforms\android-28\android.jar
Calling mockable JAR artifact transform to create file: C:\Users\_USERFOLDER_\.gradle\caches\transforms-2\files-2.1\08efdfe0d8cf00cccc6a03622959e0ad\android.jar with input C:\Users\_USERFOLDER_\AppData\Local\Android\Sdk\platforms\android-28\android.jar
Calling mockable JAR artifact transform to create file: C:\Users\_USERFOLDER_\.gradle\caches\transforms-2\files-2.1\1a859f032ea56da6fdcf4706b3d23efa\android.jar with input C:\Users\_USERFOLDER_\AppData\Local\Android\Sdk\platforms\android-29\android.jar
Removed unused resources: Binary resource data reduced from 759KB to 728KB: Removed 4%
Running Gradle task 'assembleDevRelease'...
Running Gradle task 'assembleDevRelease'... Done 270.2s (!)
√ Built build\app\outputs\flutter-apk\app-dev-release.apk (21.0MB).
AppCenter 构建变体 - devRelease(在 webUI 上指定)
appcenter-post-clone.sh:
#!/usr/bin/env bash
# place this script in project/android/app/
cd ..
# fail if any command fails
set -e
# debug log
set -x
#print appcenter's output folder
echo "!~! Appcenter output: $APPCENTER_OUTPUT_DIRECTORY"
#print app flavour specified
echo "Building app for $APP_ENV flavour"
entrypoint="placeholder_to_replace.dart"
#set target main<>.dart file
if [ "$APP_ENV" == "dev" ]; then
entrypoint="main_dev_test.dart";
elif [ "$APP_ENV" == "beta" ]; then
entrypoint="main_beta.dart";
elif [ "$APP_ENV" == "prod" ]; then
entrypoint="main_release.dart";
fi
echo "using entrypoint: $entrypoint"
cd ..
# choose a different release channel if you want - https://github.com/flutter/flutter/wiki/Flutter-build-release-channels
# stable - recommended for production
git clone -b stable https://github.com/flutter/flutter.git
export PATH=`pwd`/flutter/bin:$PATH
flutter channel beta
flutter upgrade
flutter doctor
flutter build apk --release --flavor dev -t lib/$entrypoint
# copy the APK where AppCenter will find it
mkdir -p android/app/build/outputs/apk/; mv build/app/outputs/flutter-apk/app-$APP_ENV-release.apk $_
android/app/build.gradle:
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists())
localPropertiesFile.withReader('UTF-8') reader ->
localProperties.load(reader)
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null)
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null)
flutterVersionCode = '1'
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null)
flutterVersionName = '1.0'
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android
compileSdkVersion 28
sourceSets
main.java.srcDirs += 'src/main/kotlin'
lintOptions
disable 'InvalidPackage'
defaultConfig
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.example.hello_world"
minSdkVersion 21
targetSdkVersion 28
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
signingConfigs
release
storeFile rootProject.file("app/android.keystore")
storePassword System.getenv("APPCENTER_KEYSTORE_PASSWORD")
keyAlias System.getenv("APPCENTER_KEY_ALIAS")
keyPassword System.getenv("APPCENTER_KEY_PASSWORD")
buildTypes
release
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.release
flavorDimensions "default"
productFlavors
local
dimension "default"
applicationIdSuffix ".dev"
dev
dimension "default"
applicationIdSuffix ".dev"
beta
dimension "default"
applicationIdSuffix ".beta"
prod
dimension "default"
flutter
source '../..'
dependencies
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
AppCenter 构建输出:
//---OMITTED TOOLING CLONING---
Building flutter tool...
Flutter is already up to date on channel beta
Flutter 1.22.0-12.1.pre • channel beta • https://github.com/flutter/flutter.git
Framework • revision 8b3760638a (8 days ago) • 2020-09-15 17:47:13 -0700
Engine • revision 4654fc6cf6
Tools • Dart 2.10.0 (build 2.10.0-110.3.beta)
+ flutter doctor
Downloading Material fonts... 0.5s
Downloading package sky_engine... 0.2s
Downloading flutter_patched_sdk tools... 0.7s
Downloading flutter_patched_sdk_product tools... 0.6s
Downloading darwin-x64 tools... 1.6s
Downloading libimobiledevice... 0.0s
Downloading usbmuxd... 0.0s
Downloading darwin-x64/font-subset tools... 0.3s
Downloading android-arm-profile/darwin-x64 tools... 0.3s
Downloading android-arm-release/darwin-x64 tools... 0.2s
Downloading android-arm64-profile/darwin-x64 tools... 0.3s
Downloading android-arm64-release/darwin-x64 tools... 0.3s
Downloading android-x64-profile/darwin-x64 tools... 0.3s
Downloading android-x64-release/darwin-x64 tools... 0.3s
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel beta, 1.22.0-12.1.pre, on Mac OS X 10.14.6 18G6020, locale en)
[!] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
! Some Android licenses not accepted. To resolve this, run: flutter doctor --android-licenses
[✓] Xcode - develop for ios and macOS (Xcode 11.3.1)
[!] Android Studio (not installed)
[!] Connected device
! No devices available
! Doctor found issues in 3 categories.
+ flutter build apk --flavor dev --release -t lib/main_dev_test.dart
Running "flutter pub get" in s... 6.9s
You are building a fat APK that includes binaries for android-arm, android-arm64, android-x64.
If you are deploying the app to the Play Store, it's recommended to use app bundles or split the APK to reduce the APK size.
To generate an app bundle, run:
flutter build appbundle --target-platform android-arm,android-arm64,android-x64
Learn more on: https://developer.android.com/guide/app-bundle
To split the APKs per ABI, run:
flutter build apk --target-platform android-arm,android-arm64,android-x64 --split-per-abi
Learn more on: https://developer.android.com/studio/build/configure-apk-splits#configure-abi-split
Running Gradle task 'assembleDevRelease'...
Gradle 5.6.2
//---OMMITTED PACKAGE RESOLVE LINES---
> Task :clean
> Task :app:clean UP-TO-DATE
> Task :barcode_scan:clean UP-TO-DATE
> Task :camera:clean UP-TO-DATE
> Task :device_info:clean UP-TO-DATE
> Task :flutter_secure_storage:clean UP-TO-DATE
> Task :package_info:clean UP-TO-DATE
> Task :path_provider:clean UP-TO-DATE
> Task :permission_handler:clean UP-TO-DATE
> Task :shared_preferences:clean UP-TO-DATE
> Task :sqflite:clean UP-TO-DATE
> Task :app:compileFlutterBuildDevRelease FAILED
Error: Error when reading 'lib/main.dart': No such file or directory
package:hello_world/main.dart: Error: No 'main' method found.
Try adding a method named 'main' to your program.
FAILURE: Build failed with an exception.
* Where:
Script '/Users/runner/work/1/s/flutter/packages/flutter_tools/gradle/flutter.gradle' line: 904
* What went wrong:
Execution failed for task ':app:compileFlutterBuildDevRelease'.
> Process 'command '/Users/runner/work/1/s/flutter/bin/flutter'' finished with non-zero exit value 1
* Try:
12 actionable tasks: 2 executed, 10 up-to-date
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 6s
Error: /Users/runner/work/1/s/android/gradlew failed with return code: 1
at ChildProcess.<anonymous> (/Users/runner/work/_tasks/Gradle_8d8eebd8-2b94-4c97-85af-839254cc6da4/1.128.0/node_modules/vsts-task-lib/toolrunner.js:569:30)
at emitTwo (events.js:106:13)
at ChildProcess.emit (events.js:191:7)
at maybeClose (internal/child_process.js:920:16)
at Socket.<anonymous> (internal/child_process.js:351:11)
at emitOne (events.js:96:13)
at Socket.emit (events.js:188:7)
at Pipe._handle.close [as _onclose] (net.js:509:12)
##[error]Error: /Users/runner/work/1/s/android/gradlew failed with return code: 1
##[section]Finishing: Gradle Task
##[section]Starting: Checkout YardAppFlutter@feature/switchable_build_configurations to s
==============================================================================
Task : Get sources
Description : Get sources from a repository. Supports Git, TfsVC, and SVN repositories.
Version : 1.0.0
Author : Microsoft
Help : [More Information](https://go.microsoft.com/fwlink/?LinkId=798199)
==============================================================================
Cleaning any cached credential from repository: YardAppFlutter (ExternalGit)
##[section]Finishing: Checkout YardAppFlutter@feature/switchable_build_configurations to s
##[section]Starting: Finalize Job
Cleaning up task key
Start cleaning up orphan processes.
Terminate orphan process: pid (1609) (java)
Terminate orphan process: pid (1550) (java)
Terminate orphan process: pid (1428) (adb)
##[section]Finishing: Finalize Job
##[section]Finishing: Build
【问题讨论】:
我也有同样的问题。我的脚本非常相似。我正在寻找一种方法来设置 gradle 构建的入口点,但没有成功。 【参考方案1】:我在使用 AppCenter 时遇到了同样的问题,我遇到了这个 answer,表明问题是由 gradle 中的一些构建步骤引起的,建议在您的项目中使用 lib/main.dart
。
所以我通过使用lib/main.dart
构建生产版本解决了这个问题。唯一要更改的文件是appcenter-post-clone.sh
看看我的appcenter-post-clone.sh
:
#!/usr/bin/env bash
# place this script in project/android/app/
cd ..
# fail if any command fails
set -e
# debug log
set -x
cd ..
# choose a different release channel if you want - https://github.com/flutter/flutter/wiki/Flutter-build-release-channels
# stable - recommended for production
git clone -b stable https://github.com/flutter/flutter.git
export PATH=`pwd`/flutter/bin:$PATH
echo "Building with flavor $FLAVOR"
target="lib/main.dart"
if [ "$FLAVOR" == "qa" ]; then
target="lib/main_qa.dart";
elif [ "$FLAVOR" == "prod" ]; then
target="lib/main.dart";
fi
echo "using entrypoint: $target"
flutter channel stable
flutter doctor
flutter pub get
flutter pub run build_runner build
flutter build apk --release --dart-define=API_KEY=$API_KEY --dart-define=FLAVOR=$FLAVOR --flavor $FLAVOR -t $target
# change apk file name
mv build/app/outputs/flutter-apk/app-$FLAVOR-release.apk build/app/outputs/flutter-apk/wfm.apk
# copy the APK where AppCenter will find it
mkdir -p android/app/build/outputs/apk/; mv build/app/outputs/flutter-apk/wfm.apk $_
【讨论】:
以上是关于使用风味使用 MS AppCenter 构建 Flutter android APK 的问题的主要内容,如果未能解决你的问题,请参考以下文章
iOS Build在Xcode中表现不错,但Appcenter.ms失败了
启用 sonarscanner 时 Appcenter iOS 构建失败
MS AppCenter 和 Azure DevOps(前 VSTS)之间的主要区别是啥?