美文网首页Flutter学习
Flutter && gradlew 命令 && shell打包

Flutter && gradlew 命令 && shell打包

作者: 三也视界 | 来源:发表于2021-08-30 02:10 被阅读0次

    无论是持续性编译还是平时开发,都离不开命令。Android有gradlew命令,flutter也有对应的命令,对于shell脚本命令,我们也经常用到。这篇博文只是简单整理,方便以后查阅。

    对于部分
    Shell(Bash)多命令顺序执行方法详解

    gradlew命令

    我们知道 Android打包使用的是gradlew命令,先来看一下gradlew命令

    gradlew命令都可以使用简写,例如:

    ./gradlew assembleRelease 简写为:./gradlew aR

    gradlew前面加./表示当前目录,具体查看以下博文:路径中的'.'和'..'还有'./'和'../'都是什么意思,所以这里需要切换到flutter的Android根目录之下,才能找到gradlew命令

    image.png
    # 查看所有任务
    
    ./gradlew tasks --all
    
    # 对某个module [moduleName] 的某个任务[TaskName] 运行.
    
    /gradlew:moduleName:taskName
    
    # 查看项目的依赖都依赖了哪些库。
    
    gradlew :app:dependencies 
    
    #只编译清单文件,并查看具体日志,快速定位清单文件报错
    
    gradlew :app:processDebugManifest --stacktrace:
    
    # 查看构建版本
    
    ./gradlew -v
    
    # 清除build文件夹
    
    ./gradlew clean
    
    # 检查依赖并编译打包
    
    ./gradlew build
    
    # 编译并安装debug包
    
    ./gradlew installDebug
    
    # 编译并打印日志
    
    ./gradlew build --info
    
    # 调试模式构建并打印日志
    
    ./gradlew build --info --debug --stacktrace
    
    # 强制更新最新依赖,清除构建并构建
    
    ./gradlew clean --refresh-dependencies build
    

    注意build命令把 debug、release环境的包都打出来的

    如果需要指定构建使用如下命令

    指定构建目标命令

    # 编译并打Debug包
    
    ./gradlew assembleDebug./gradlew aD
    
    # 编译并打Release的包
    
    ./gradlew assembleRelease./gradlew aR
    

    构建并安装调试命令

    # 编译并打Debug包
    
    ./gradlew assembleDebug
    
    # 编译app module 并打Debug包
    
    ./gradlew install app:assembleDebug
    
    # 编译并打Release的包(生成的aar包就在`.android/Flutter/build/outputs/aar/`目录下)
    
    ./gradlew assembleRelease
    
    #  Release模式打包并安装
    
    ./gradlew installRelease
    
    # 卸载Release模式包
    
    ./gradlew uninstallRelease
    

    多渠道打包

    assemble还可以和productFlavors结合使用,如果出现类似 Task'install'isambiguousinroot project 这种错误,请查看配置的多个渠道然后修改命令为./gradlew install[productFlavorsName] app:assembleDebug来用命令构建调试

    # Release模式打包并安装
    
    ./gradlew installRelease
    
    # 卸载Release模式包
    
    ./gradlew uninstallRelease
    
    # Release模式全部渠道打包
    
    ./gradlew assembleRelease
    
    # Release模式 test 渠道打包
    
    ./gradlew assembleTestRelease
    
    # debug release模式全部渠道打包
    
    ./gradlew assemble
    
    #查看包依赖
    
    ./gradlew dependencies
    
    # 编译时的依赖库
    
    ./gradlew app:dependencies --configuration compile
    
    # 运行时的依赖库
    
    ./gradlew app:dependencies --configuration runtime
    

    依赖管理
    传递依赖特性

    dependencies {
        transitive true
    }
    

    手动配置transitive属性为false,阻止依赖的下载

    强制

    configurations.all{
    // transitive false// 强制指定版本
      resolutionStrategy{
          force'org.hamcrest:hamcrest-core:1.3'// 强制不编译
          all*.excludegroup:'org.hamcrest',
          module:'hamcrest-core'
      }
    }
    

    动态依赖特性

    dependencies {
      // 任意一个版本
      compile group:'b',name:'b',version:'1.+'
      // 最新的版本
      compile group:'a',name:'a',version:'latest.integration'
    }
    

    查看详细依赖信息

    #使用离线模式
    
    ./gradlew aDR --offline
    
    #守护进程
    
    ./gradle build --daemon
    
    #并行编译模式
    
    ./gradle build --parallel --parallel-threads=N
    
    #按需编译模式
    
    ./gradle build --configure-on-demand
    
    #不使用snapshot依赖仓库 前提是离线可以使用时
    
    ./gradlew clean aDR
    
    

    通过增加--dwarf_stack_traces,--print-snapshot-sizes,--obfuscate命令压缩体积

    ./gradlew clean assembleRelease -Pextra-gen-snapshot-options="--dwarf_stack_traces,--print-snapshot-sizes,--obfuscate"
    

    flutter 命令

    前面说完gradlew命令,我们回过头来研究flutter。

    flutter create

    在指定的目录中,创建新的flutter项目,如果没有指定目录,则在当前目录下创建项目

    flutter create ~/flutter #在家目录下的flutter目录项目
    flutter create . #在当前目录下创建
    

    flutter -v

    查看APP所有日志的输出,对于调试是非常有用处,在调试时需要配合run命令使用

    flutter -v run
    

    flutter -d

    切换在不同设备上运行app,如果没有指定设备,默认将会使用设备列表的第一个设备,这对于计算机连接多个设备时非常有用,可以使用设备名称或者设备id作为参数

    flutter run -d NX569J #设备名称
    flutter run -d devices_id #设备id
    

    flutter analyze

    编辑Flutter代码时,使用分析器检查代码是非常重要,默认是分析整个项目的代码,你也可以通过使用analysis_options.yaml文件来排除不需要的代码分析

    analyzer:
      exclude:
        - flutter/**
    

    analysis_options.yaml

    有时候你可能需要代码分析一直在运行,可以使用--watch选项

    flutter analyze --watch
    

    当运行分析命令flutter都执行一次pub get命令,如果不需要运行,可以执行以下命令

    flutter analyze --no-pub 
    

    flutter attach

    相当于命令flutter run命令,不同之处在很多执行都是自己手动,比如热重载,

    flutter bash-completion

    在执行该命令时会输出一的配置脚本,脚本可以实现命令行提示的自动完成,可用于zsh,bash的配置,将脚本添加到~/.bashrc或者~/.zshrc

    if type complete &>/dev/null; then
      __flutter_completion() {
        local si="$IFS"
        IFS=$'\n' COMPREPLY=($(COMP_CWORD="$COMP_CWORD" \
                               COMP_LINE="$COMP_LINE" \
                               COMP_POINT="$COMP_POINT" \
                               flutter completion -- "${COMP_WORDS[@]}" \
                               2>/dev/null)) || return $?
        IFS="$si"
      }
      complete -F __flutter_completion flutter
    elif type compdef &>/dev/null; then
      __flutter_completion() {
        si=$IFS
        compadd -- $(COMP_CWORD=$((CURRENT-1)) \
                     COMP_LINE=$BUFFER \
                     COMP_POINT=0 \
                     flutter completion -- "${words[@]}" \
                     2>/dev/null)
        IFS=$si
      }
      compdef __flutter_completion flutter
    elif type compctl &>/dev/null; then
      __flutter_completion() {
        local cword line point words si
        read -Ac words
        read -cn cword
        let cword-=1
        read -l line
        read -ln point
        si="$IFS"
        IFS=$'\n' reply=($(COMP_CWORD="$cword" \
                           COMP_LINE="$line" \
                           COMP_POINT="$point" \
                           flutter completion -- "${words[@]}" \
                           2>/dev/null)) || return $?
        IFS="$si"
      }
      compctl -K __flutter_completion flutter
    fi
    
    

    flutter build

    构建应用程序的apk,appbundle,aot,ios,IOS应用需要在Mac osx上构建

    flutter build apk
    

    flutter channel

    切换flutter不同的版本,在执行flutter channel会输出不同分支信息,默认使用stable分支

    flutter channel # 输出channel
    flutter channel dev # 切换到dev channel
    

    flutter clean

    删除build/.dart_tool/目录,清除缓存信息,避免之前不同版本代码的影响

    flutter config

    可以用于指定gradle,android sdk,android studio的目录或者开启,禁用analytics选项,analytics选项用于flutter工具的报告

    flutter config --gradle-dir /gradle/
    

    flutter devices

    列出已经连接到计算机的设备

    flutter devices
    NX569J                    • 192.168.43.1:5555 • android-arm64 • Android 7.1.2 (API 25)
    Android SDK built for x86 • emulator-5554     • android-x86   • Android 9 (API 28) (emulator)
    
    

    flutter doctor

    检查开发工具链是否完整安装,对于安装环境非常有用处,检查andorid licenses需要连接外网,请科学上网

    flutter doctor
    
    Doctor summary (to see all details, run flutter doctor -v):
    [✓] Flutter (Channel stable, v1.2.1, on Linux, locale en_US.UTF-8)
    [✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
    [✓] Android Studio (version 3.3)
    [✓] VS Code (version 1.33.1)
    [✓] Connected device (2 available)
    
    • No issues found!
    
    

    flutter pub outdated

    查询展示依赖包可更新的版本信息

    Showing outdated packages.
    [*] indicates versions that are not the latest available.
    
    Package Name     Current     Upgradable  Resolvable  Latest   
    
    direct dependencies:
    cupertino_icons  *0.1.3      *0.1.3      1.0.3       1.0.3    
    fixnum           *0.10.11    *0.10.11    1.0.0       1.0.0    
    package_info     *0.3.2+1    *0.3.2+1    2.0.2       2.0.2    
    protobuf         *0.13.16+1  *0.13.16+1  2.0.0       2.0.0    
    
    transitive dependencies:
    meta             *1.3.0      *1.3.0      *1.3.0      1.7.0    
    
    transitive dev_dependencies:
    async            *2.6.1      *2.6.1      *2.6.1      2.8.2    
    charcode         *1.2.0      *1.2.0      *1.2.0      1.3.1    
    matcher          *0.12.10    *0.12.10    *0.12.10    0.12.11  
    test_api         *0.3.0      *0.3.0      *0.3.0      0.4.3    
    
    4  dependencies are constrained to versions that are older than a resolvable version.
    

    flutter pub upgrade --major-versions

    快速自动更新app依赖

    Resolving dependencies...
      async 2.6.1 (2.8.2 available)
      boolean_selector 2.1.0
      characters 1.1.0
      charcode 1.2.0 (1.3.1 available)
      clock 1.1.0
      collection 1.15.0
    > cupertino_icons 1.0.3 (was 0.1.3)
      fake_async 1.2.0
    > fixnum 1.0.0 (was 0.10.11)
      flutter 0.0.0 from sdk flutter
      flutter_test 0.0.0 from sdk flutter
      matcher 0.12.10 (0.12.11 available)
      meta 1.3.0 (1.7.0 available)
    > package_info 2.0.2 (was 0.3.2+1)
      path 1.8.0
    > protobuf 2.0.0 (was 0.13.16+1)
      sky_engine 0.0.99 from sdk flutter
      source_span 1.8.1
      stack_trace 1.10.0
      stream_channel 2.1.0
      string_scanner 1.1.0
      term_glyph 1.2.0
      test_api 0.3.0 (0.4.3 available)
      typed_data 1.3.0
      vector_math 2.1.0
    Downloading protobuf 2.0.0...
    Changed 4 dependencies!
    5 packages have newer versions incompatible with dependency constraints.
    Try `flutter pub outdated` for more information.
    
    Changed 4 constraints in pubspec.yaml:
      package_info: ^0.3.2+1 -> ^2.0.2
      fixnum: ^0.10.9 -> ^1.0.0
      protobuf: ^0.13.4 -> ^2.0.0
      cupertino_icons: ^0.1.2 -> ^1.0.3
    

    flutter drive

    执行flutter ui测试,该工具类似与web端的Selenium,WebDriver,Protractor.你可以指定不同模式进行测试,可以是debug,profile,release,flavor模式,flavor模式可以指定平台规范,你还可以指定在不同的平台测试,甚至可以指定页面路由

    flutter drive --debug --target-platform android-x86
    

    flutter emulators

    列出,创建,启动模拟器,默认是列出模拟器

    flutter emulators --launch flutter_emulator #启动
    flutter emulators # 列出
    flutter emulators --create Pixel_API_28 # 创建
    

    flutter format

    按照dart代码规范格式项目代码文件,flutter format .是当前项目所有文件,也可以指定目录或者文件

    flutter format dartfile
    

    flutter verion

    列出或者切换flutter版本,默认是列出所有版本

    flutter version
    flutter version v1.5.8
    

    flutter upgrade

    更新flutter代码,实质就是git代码更新拉取,下载flutter sdk是git仓库的打包

    flutter test

    运行flutter单元测试,可以使用--start-paused模式等待调试器的连接,--concurrency可以指定并发任务数默认值是6

    flutter test --concurrency=8
    

    flutter install

    安装app到一个已经连接的设备

    flutter install
    

    flutter screenshot

    截取当前屏幕,默认是将图片输出到家目录下,使用-o指定输出目录

    flutter screenshot -o /home/work
    

    flutter packages

    获取,测试,更新依赖包,flutter pub 将会传递剩余参数到dart工具的pub

    flutter packages get
    

    首先打开flutter的安装目录,进入flutter_tools-》gradle打开flutter.gradle


    image.png

    shell打包脚本

    Android打包

    多渠道

    多渠道打包常规方式有两种,Flavor 和 --dart-define,后者是 Flutter1.17新增的命令行可选参数,比Flavor配置更简单,非常适合用于环境配置

    channel_dev.dart

    class EnvironmentConfig{
      static const APP_CHANNEL = String.fromEnvironment('APP_CHANNEL',defaultValue:"default");
      static const APP_STORE_NAME = String.fromEnvironment('APP_STORE_NAME');
    }
    

    将渠道传给第三方埋点统计平台,比如友盟和bugly

    FlutterUmengPlus.init(androidAppKey:"XXXXXXX", iOSAppKey:"XXXXXX", channel:"${EnvironmentConfig.APP_CHANNEL}",logEnable: false,);
    

    android =》app=〉build.gradle添加以下信息

    /// 获取渠道参数使用,这里设置一下默认值
    def dartEnvironmentVariables = [
            APP_CHANNEL: 'default',
            APP_STORE_NAM: 'yatsar',
            APP_STORE_URL:''
    ]
    ///拦截dart-defines 获取外部输入值,添加到dartEnvironmentVariables
    if (project.hasProperty('dart-defines')) {
        dartEnvironmentVariables = dartEnvironmentVariables + project.property('dart-defines')
                .split(',')
                .collectEntries { entry ->
                    def pair = URLDecoder.decode(entry, "utf-8").split('=')
                    [(pair.first()): pair.last()]
                }
    }
    

    android{}下更改apk名字

     // 重命名 apk
        applicationVariants.all { variant ->
            variant.outputs.all { output ->
                if(variant.buildType.name == "release"){
                    // 获取版本
                    def versionName = variant.versionName
                    def versionCode = variant.versionName
                    // 设置新名称
                    def newApkName ="app_v${defaultConfig.versionName}_${defaultConfig.versionCode}_channel_${dartEnvironmentVariables.APP_CHANNEL}.apk"
                    outputFileName = new File(newApkName)
                }
            }
        }
    
    单个市场打包脚本fapk_channel.sh
    echo "正在打包$1市场渠道,请耐心等待。。。"
    cd C:/Users/Administrator/StudioProjects/flutter_beauty/
    flutter clean
    echo "flutter clean end: $?"
    if [$? -ne 0];then
        echo "clean faild"
    else
        echo "clean success"
    fi
    
    flutter build apk  --dart-define=APP_CHANNEL=$1  --dart-define=APP_STORE_NAME=$2
    cd build/app/outputs/flutter-apk/
    
    date_time=$(date "+%Y%m%d")
    
    build_dir=C:/myApp/output/$date_time/$1
    
    if [ ! -d "$build_dir" ];then
         mkdir -p $build_dir
    fi
    
    time=$(date "+%Y%m%d%H%M%S")
    
    cp -R *release.apk  $build_dir/$1_$time.apk
    

    进行打包某个渠道的时候只要输入命令即可

    fapk_channel.sh HUAWEI  华为
    
    全部市场打包脚本fapk_all_channel.sh
    echo "打包全部市场渠道市场渠道,请耐心等待。。。"
    
    fapk_channel.sh MyApp 腾讯应用宝;
    fapk_channel.sh 360  360手机助手;
    fapk_channel.sh Baidu 百度手机助手;
    fapk_channel.sh Yatsar Yatsar
    fapk_channel.sh HUAWEI  华为;
    fapk_channel.sh OPPO OPPO;
    fapk_channel.sh VIVO VIVO;
    fapk_channel.sh Mi 小米;
    fapk_channel.sh SamSung 三星应用市场
    

    iOS打包

    iOS打包比较复杂一些,需要用到一个打包的脚本,这个脚本在Flutter SDK里,路径为packages/flutter_tools/bin,有一个叫xcode_backend.sh的脚本,首先分析这个脚本:

    if [[ $# == 0 ]]; then
      # Backwards-compatibility: if no args are provided, build.
      BuildApp
    else
      case $1 in
        "build")
          BuildApp ;;
        "thin")
          ThinAppFrameworks ;;
        "embed")
          EmbedFlutterFrameworks ;;
      esac
    fi
    

    可以看到这个脚本有三个功能,分别是:

    1. build
    2. thin
    3. embed

    把这个脚本拷贝到工程的目录,运行

    1. 第一步
    $/bin/sh xcode_backend.sh build
    
    

    然后你会发现有报错,如下:

    ERROR: Unknown FLUTTER_BUILD_MODE: .
    Valid values are 'Debug', 'Profile', or 'Release' (case insensitive).
    This is controlled by the FLUTTER_BUILD_MODE environment varaible.
    If that is not set, the CONFIGURATION environment variable is used.
    
    

    这是因为少了一些环境变量,要把这些变量加上:

    export FLUTTER_BUILD_MODE="" //有三个值:Debug  Profile   Release
    export FLUTTER_ROOT="" //Flutter SDK的目录
    export FLUTTER_APPLICATION_PATH=""  //工程目录
    export SOURCE_ROOT="${FLUTTER_APPLICATION_PATH}/.ios/Flutter"  //Flutter iOS代码的目录
    export FLUTTER_TARGET="lib/main.dart"  //dart代码
    export FLUTTER_BUILD_DIR="build" //build生成的路径
    export ARCHS="armv7 arm64" //Flutter打包的Framework要支持的平台
    
    1. 第二步
    $/bin/sh xcode_backend.sh thin
    
    

    同样也要加上环境变量:

    export SOURCE_ROOT=".../.ios/Flutter" //Flutter iOS代码的目录
    export ARCHS="armv7 arm64" //Flutter打包的Framework要支持的平台
    export TARGET_BUILD_DIR="${SOURCE_ROOT}" //build生成的路径
    export app_path="${TARGET_BUILD_DIR}/Flutter" //Flutter打包的Framework所在的路径
    export frameworks_dir="${app_path}"  //Flutter打包的Framework所在的路径
    
    

    综上,要加的环境变量如下:

    export FLUTTER_BUILD_MODE="" //有三个值:Debug  Profile   Release
    export FLUTTER_ROOT="" //Flutter SDK的目录
    export FLUTTER_APPLICATION_PATH=""  //工程目录
    export SOURCE_ROOT="${FLUTTER_APPLICATION_PATH}/.ios/Flutter"  //Flutter iOS代码的目录
    export FLUTTER_TARGET="lib/main.dart"  //dart代码
    export FLUTTER_BUILD_DIR="build" //build生成的路径
    export ARCHS="armv7 arm64" //Flutter打包的Framework要支持的平台
    export TARGET_BUILD_DIR="${SOURCE_ROOT}" //build生成的路径
    export app_path="${TARGET_BUILD_DIR}/Flutter" //Flutter打包的Framework所在的路径
    export frameworks_dir="${app_path}"  //Flutter打包的Framework所在的路径
    
    

    运行的命令如下:

    $/bin/sh xcode_backend.sh build
    $/bin/sh xcode_backend.sh thin
    

    生成产物在.../.iOS/Flutter中查看,如果想修改生成产物的路径,修改脚本里derived_dir的值,如下:

      local derived_dir="${SOURCE_ROOT}/Flutter/Flutter"
      if [[ -e "${project_path}/.ios" ]]; then
        derived_dir="${project_path}/.ios/Flutter/Flutter"
      fi
    
    flutter --suppress-analytics build aot --output-dir=build/aot --target-platform=ios --target=lib/main.dart --release --ios-arch=arm64 --extra-gen-snapshot-options="--dwarf_stack_traces,--print-snapshot-sizes,--print_instructions_sizes_to=build/aot.json"
    

    相关文章

      网友评论

        本文标题:Flutter && gradlew 命令 && shell打包

        本文链接:https://www.haomeiwen.com/subject/dvhejctx.html