#!/usr/bin/env bash # ============================================================ # 短视频 App Android APK 编译脚本(Linux 服务器用) # # 用法: # chmod +x build_apk.sh # ./build_apk.sh # # 首次使用前:修改下方「可配置参数」区域即可,无需改其他逻辑。 # 环境要求:JDK 17 + Flutter SDK(Linux) + Android SDK 命令行工具 # 详见 docs/04-部署运行文档.md # ============================================================ set -euo pipefail # ==================== 可配置参数 ==================== # 项目 app 目录(默认:脚本所在目录下的 app/) APP_DIR="$(cd "$(dirname "$0")" && pwd)/app" # Flutter SDK 路径 FLUTTER_HOME="/opt/flutter" # Android SDK 路径(系统已设 ANDROID_HOME 环境变量时优先生效) ANDROID_SDK="${ANDROID_HOME:-$HOME/android-sdk}" # 构建类型:release / debug / profile BUILD_MODE="release" # API 直连地址;留空 = 走 DNS TXT 域名发现(正式发布推荐留空) # 联调示例:API_BASE="https://api.example.com/api/v1" API_BASE="" # 编译产物拷贝目录(留空 = 只输出在 app/build 目录,不拷贝) OUTPUT_DIR="" # =================================================== log() { printf '\033[1;32m[build]\033[0m %s\n' "$*"; } die() { printf '\033[1;31m[错误]\033[0m %s\n' "$*" >&2; exit 1; } export PATH="$FLUTTER_HOME/bin:$ANDROID_SDK/platform-tools:$PATH" export ANDROID_HOME="$ANDROID_SDK" # ---------- 环境检查 ---------- command -v java >/dev/null 2>&1 \ || die "未找到 java,请先安装 JDK 17(如 apt install -y openjdk-17-jdk)" [ -x "$FLUTTER_HOME/bin/flutter" ] \ || die "未找到 Flutter SDK:$FLUTTER_HOME,请修改脚本中的 FLUTTER_HOME" [ -d "$ANDROID_SDK" ] \ || die "未找到 Android SDK:$ANDROID_SDK,请修改脚本中的 ANDROID_SDK" # Java 17 校验(gradle 要求) JAVA_MAJOR=$(java -version 2>&1 | head -1 | sed -E 's/.*version "([0-9]+).*/\1/') [ "$JAVA_MAJOR" -ge 17 ] 2>/dev/null \ || die "Java 版本过低($JAVA_MAJOR),需要 JDK 17+" # JAVA_HOME 未设置时按 java 可执行文件位置推断 [ -n "${JAVA_HOME:-}" ] \ || export JAVA_HOME="$(dirname "$(dirname "$(readlink -f "$(command -v java)")")")" log "Java: $(java -version 2>&1 | head -1)" log "JAVA_HOME: $JAVA_HOME" log "Flutter: $(flutter --version 2>/dev/null | head -1)" log "Android SDK: $ANDROID_SDK" cd "$APP_DIR" # local.properties 记录的是上一台编译机的路径,sdk.dir 失效时删除让 Flutter 重新生成 if [ -f android/local.properties ]; then SDK_DIR=$(grep '^sdk.dir=' android/local.properties | cut -d= -f2- || true) [ -n "$SDK_DIR" ] && [ -d "$SDK_DIR" ] || rm -f android/local.properties fi # 同意 Android 许可(已同意则静默跳过) yes | flutter doctor --android-licenses >/dev/null 2>&1 || true # ---------- 编译 ---------- log "拉取依赖..." flutter pub get log "开始编译 $BUILD_MODE APK..." if [ -n "$API_BASE" ]; then flutter build apk --"$BUILD_MODE" --dart-define="API_BASE=$API_BASE" else flutter build apk --"$BUILD_MODE" fi APK="$APP_DIR/build/app/outputs/flutter-apk/app-$BUILD_MODE.apk" [ -f "$APK" ] || die "编译结束但未找到产物:$APK" VERSION=$(grep -E '^version:' pubspec.yaml | awk '{print $2}') SIZE=$(du -h "$APK" | cut -f1) log "编译成功:$APK($SIZE,版本 $VERSION)" if [ -n "$OUTPUT_DIR" ]; then mkdir -p "$OUTPUT_DIR" DEST="$OUTPUT_DIR/videoapp-$VERSION-$BUILD_MODE.apk" cp "$APK" "$DEST" log "已拷贝到:$DEST" fi if [ -n "$API_BASE" ]; then log "此包直连:$API_BASE" else log "此包走 DNS TXT 域名发现(请确认 txt.256kb.top 记录已指向你的 API 入口)" fi