uniapp打包app进阶


一、背景

简易:需不需要懂android知识
速度:打包出一个APK的速度

云打包

简易:❤❤❤❤❤
速度:❤

离线打包

简易:❤❤
速度:❤❤❤❤❤

总结:
云打包虽然快,但需要排队,太影响开发效率。
离线打包,打包速度1分钟左右,但需要安装相应环境和懂一点安卓知识,项目涉及的模块和原生插件都需要手动配置。

二、需求

通过Docker镜像来一键打包,配置完之后,前端人员只需要点击jenkin来打包,且支持一份代码打包多个APK出来,分发各个甲方。

三、环境

  1. uniapp的vue3脚手架

PS: 这里不使用HBuild-cli来打包,原因: 1.官方的bug维护太慢 2.cli在占用时,再次执行cli命令直接不执行

四、开始

● 基础配置

# 运行一个ubuntu镜像(24.04)
docker run -it --name uniapp_app_build -p 9300:8080 ubuntu /bin/bash

# apt安装软件包
apt update
apt install sudo
apt install vim

# ubuntu设置中文
locale -a // 查看支持的字符编码
sudo vim ~/.bashrc // 添加export LANG=C.utf-8
source ~/.bashrc

● 安装Jenkins

# 安装JDK17
sudo apt install openjdk-17-jdk
java -version

# 安装Jenkins
sudo apt install curl
curl -fsSL https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key | sudo tee /usr/share/keyrings/jenkins-keyring.asc > /dev/null
echo deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] https://pkg.jenkins.io/debian-stable binary/ | sudo tee /etc/apt/sources.list.d/jenkins.list > /dev/null
sudo apt update
sudo apt install jenkins

cd /home/ubuntu/jenkins
sudo apt install wget
wget https://get.jenkins.io/war/latest/jenkins.war

sudo java -jar jenkins.war

# 查看jenkin初始密码
cat /root/.jenkins/secrets/initialAdminPassword

● 测试jenkins

1、回到本地访问jenkins:http://127.0.0.1:9300 (账号root,密码1234567890)  
2、新建任务=>构建一个自由风格的软件项目=>配置=>新增构建步骤=>输入下面命令=>执行成功即可

cat /etc/os-release
java -version

● 安装Node (非必须,可跳过)

curl https://get.volta.sh | bash
export VOLTA_HOME="$HOME/.volta"
export PATH="$VOLTA_HOME/bin:$PATH"
source ~/.bashrc
volta install node@22.12.0
node -v
npm i -g pnpm
pnpm config set registry https://registry.npmmirror.com/
pnpm get

● 安装Gradle

1. 官网https://gradle.org/releases/, 下载gradle8.11.1
# 拷贝到容器里
docker cp E:\gradle-8.11.1-all.zip uniapp_app_build:/home/ubuntu/gradle

# 解压
sudo apt install unzip
unzip -O CP936 gradle-8.11.1-all.zip

# 配置Gradle环境变量
sudo vim ~/.bashrc // 添加下面两个export
# export GRADLE_HOME=/home/ubuntu/gradle/gradle-8.11.1
# export PATH=$GRADLE_HOME/bin:$PATH

source ~/.bashrc
gradle -version

● 安装AS打包环境

1. 官网https://developer.android.google.cn/studio,往下滚找到Command line tools,下载linux版本(这里用的commandlinetools-linux-13114758_latest.zip)
# 拷贝到容器里
docker cp E:\commandlinetools-linux-13114758_latest.zip uniapp_app_build:/home/ubuntu/android_studio

# 解压
unzip -O CP936 commandlinetools-linux-13114758_latest.zip

# 测试
cd /home/ubuntu/android_studio/cmdline-tools/bin
./sdkmanager --list --channel=0

# 使用该命令报错
# Error: Could not determine SDK root.
# Error: Either specify it explicitly with --sdk_root= or move this package into its expected location: /cmdline-tools/latest/
# 报错了,无法找到sdk根目录,提示说有两种解决办法:一是用–sdk_root指定路径,二是把文件夹移动到指定路径。

# 修复报错
mkdir latest
mv bin/ lib/ NOTICE.txt source.properties -t latest/
cd latest/bin/
./sdkmanager --list --channel=0

# 安卓对应的平台和构建工具
# 我的Android项目使用的是compileSdkVersion 35,buildToolsVersion “35.0.0”
./sdkmanager "build-tools;35.0.0" "platforms;android-35"

# 设置环境变量
sudo vim ~/.bashrc // 添加下面两个export
# export ANDROID_HOME=/home/ubuntu/android_studio/cmdline-tools/latest
# export PATH=$ANDROID_HOME/bin:$PATH

source ~/.bashrc
sdkmanager --version
sdkmanager --licenses

● 离线打包壳

# 拷贝到容器里 (将本地的打包壳放到容器里,如果没有就按官网的配一下)
docker cp E:\HBuilder-Integrate-AS uniapp_app_build:/home/ubuntu/AppPackageShell

# 修改下面文件
# 修改 gradle-wrapper.properties 的 distributionUrl 为 file:///home/ubuntu/gradle/gradle-8.11.1-all.zip
# 修改 local.properties 的 sdk.dir 为 /home/ubuntu/android_studio
# 修改 build.gradle 的 getVersionFromJson 的路径为 src/main/assets/apps/__UNI__9999999/www/manifest.json

# 删除旧的apk
cd /simpleDemo/build/outputs/apk/release
rm -rf simpleDemo-release.apk

# 开始打包
./gradlew clean
./gradlew build
./gradlew assembleRelease
# 打包成功即可(注意这里的输出目录是simpleDemo/build/outputs/apk/release,和AS直接打包的输出路径不同的)

● jenkins配置git和node

# 配置git
sudo apt install git
git --version
which git
# jenkins -> Manage Plugins -> 添加git插件

# 配置node
# jenkins -> Manage Plugins -> 添加NodeJS插件
# setting -> 全局工具设置 -> NodeJS 安装 -> 别名:node22,勾选自动安装,版本选nodejs22.12.0

图片

● jenkins打包配置
图片
图片
图片

# 安装依赖
npm config set registry https://registry.npmmirror.com/
npm i pnpm -g
pnpm config set registry https://registry.npmmirror.com/
pnpm i

# 打包-删除旧的
rm -rf dist
# 打包-APP离线打包资源
npm run build:app-android
# 压缩为wgt
cd ./dist/build/app
zip -r ../../项目名称.wgt ./*
# APP离线打包资源拉到AS的壳
rm -rf /home/ubuntu/AppPackageShell/HBuilder-Integrate-AS/simpleDemo/src/main/assets/apps/__UNI__9999999/www/*
mv ./dist/build/app/* /home/ubuntu/AppPackageShell/HBuilder-Integrate-AS/simpleDemo/src/main/assets/apps/__UNI__9999999/www/

# 删除旧的APK
cd /home/ubuntu/AppPackageShell/HBuilder-Integrate-AS/simpleDemo/build
rm -rf outputs

# 打包APK
cd /home/ubuntu/AppPackageShell/HBuilder-Integrate-AS
./gradlew assembleRelease
#移动APK和wgt到/home/ubuntu/outputs 
mv /home/ubuntu/AppPackageShell/HBuilder-Integrate-AS/simpleDemo/build/outputs/apk/release/*.apk /home/ubuntu/outputs 
mv /root/.jenkins/workspace/jenkins的任务名称/dist/*.wgt /home/ubuntu/outputs 
# 请求接口,上传到服务器
# response=$(curl -s -X POST -F "files=@/root/.jenkins/workspace/jenkins的任务名称/dist/项目名称.wgt" -H 'Accept: application/json' https://xxxxxx.com/xxxxx/upload)
# echo "Response: $response"

至此结束,即可使用jenkins来一键打包,当有多个apk要打,就复制壳,改改jenkin即可

其它问题

  1. 将容器打成镜像,大概有6G,看看如何缩减一下。
  2. 打成镜像会丢失jenkins配置哦,看看如何弄弄就好。
  3. 打成镜像之后,下面方式启动就好
    docker run -it –name uniapp_app_build_v1 -v /e/docker_build_uniapp_apk/outputs:/home/ubuntu/outputs -p 9300:8080 uniapp_app_build:v1 /bin/bash -c “java -jar /home/ubuntu/jenkins/jenkins.war & tail -f /dev/null”

优化

● uniapp离线打包,build.grade动态设置版本号

def getVersionFromJson(type) {
    def versionFile = file('/src/main/assets/apps/__UNI__96926FC/www/manifest.json')
    if (!versionFile.exists()) {
        throw new GradleException("version.json not found")
    }

    def versionJson = new groovy.json.JsonSlurper().parseText(versionFile.text)

    println "versionJson: ${versionJson}"
    println "versionJson.version.name: ${versionJson.version.name}"
    println "versionJson.version.code: ${versionJson.version.code}"

    if ("versionName" == type) {
        return versionJson.version.name
    } else if ("versionCode" == type) {
        return versionJson.version.code.toInteger()
    }
}

android {
    defaultConfig {
        versionName getVersionFromJson("versionName")
        versionCode getVersionFromJson("versionCode")
    }
}

● uniapp离线打包,设置打包APK名称

android {
    android.applicationVariants.all{ variant ->
        variant.outputs.all{
            def createTime = new Date().format("YYYYMMddhhmm", TimeZone.getTimeZone("GMT+08:00"))
            def fileName = "Driver_v${defaultConfig.versionName}_${createTime}.apk"
            outputFileName = fileName
        }
    }
}

文章作者: Alex
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Alex !
  目录