在 Docker 容器中构建 Android 项目

在为 Android 平台开发项目时,即使是最小的项目,迟早您都必须处理开发环境。 除了Android SDK之外,还需要有最新版本的Kotlin、Gradle、platform-tools、build-tools。 如果在开发人员的机器上使用 Android Studio IDE 更大程度地解决了所有这些依赖关系,那么在 CI/CD 服务器上,每次更新都会变得令人头疼。 如果在 Web 开发中,Docker 已经成为环境问题的标准解决方案,那么为什么不在 Android 开发中尝试用它来解决类似的问题......

对于那些不知道 Docker 是什么的人 - 如果它非常简单,那么这是一个用于创建所谓的工具。 “容器”包含最小的操作系统内核和必要的软件集,我们可以将其部署到任何我们想要的地方,同时维护环境。 我们的容器中到底包含什么内容由 Dockerfile 决定,然后将其组装成一个可以在任何地方启动并具有幂等性的镜像。

他的网站上对 Docker 的安装过程和基础知识进行了精彩的描述 官方网站。 因此,稍微往前看,我们就有了这样一个 Dockerfile

# Т.к. основным инструментом для сборки Android-проектов является Gradle, 
# и по счастливому стечению обстоятельств есть официальный Docker-образ 
# мы решили за основу взять именно его с нужной нам версией Gradle
FROM gradle:5.4.1-jdk8

# Задаем переменные с локальной папкой для Android SDK и 
# версиями платформы и инструментария
ENV SDK_URL="https://dl.google.com/android/repository/sdk-tools-linux-3859397.zip" 
    ANDROID_HOME="/usr/local/android-sdk" 
    ANDROID_VERSION=28 
    ANDROID_BUILD_TOOLS_VERSION=28.0.3

# Создаем папку, скачиваем туда SDK и распаковываем архив,
# который после сборки удаляем
RUN mkdir "$ANDROID_HOME" .android 
    && cd "$ANDROID_HOME" 
    && curl -o sdk.zip $SDK_URL 
    && unzip sdk.zip 
    && rm sdk.zip 
# В следующих строчках мы создаем папку и текстовые файлы 
# с лицензиями. На оф. сайте Android написано что мы 
# можем копировать эти файлы с машин где вручную эти 
# лицензии подтвердили и что автоматически 
# их сгенерировать нельзя
    && mkdir "$ANDROID_HOME/licenses" || true 
    && echo "24333f8a63b6825ea9c5514f83c2829b004d1" > "$ANDROID_HOME/licenses/android-sdk-license" 
    && echo "84831b9409646a918e30573bab4c9c91346d8" > "$ANDROID_HOME/licenses/android-sdk-preview-license"    

# Запускаем обновление SDK и установку build-tools, platform-tools
RUN $ANDROID_HOME/tools/bin/sdkmanager --update
RUN $ANDROID_HOME/tools/bin/sdkmanager "build-tools;${ANDROID_BUILD_TOOLS_VERSION}" 
    "platforms;android-${ANDROID_VERSION}" 
    "platform-tools"

我们将其保存到 Android 项目所在的文件夹中,并使用以下命令开始构建容器

docker build -t android-build:5.4-28-27 .

参数 -t 设置容器的标签或名称,通常由其名称和版本组成。 在我们的例子中,我们将其称为 android-build,并在版本中指定了 gradle、android-sdk 和 platform-tools 版本的组合。 未来,我们使用这样的“版本”,可以更方便地通过名字来搜索我们需要的图片。

构建通过后,我们就可以在本地使用我们的镜像了,我们可以使用命令下载它 码头推 到公共或私有映像存储库,以便将其下载到其他计算机。

作为示例,让我们构建一个本地项目。 为此,请在项目文件夹中运行命令

docker run --rm -v "$PWD":/home/gradle/ -w /home/gradle android-build:5.4.1-28-27 gradle assembleDebug

让我们弄清楚它的含义:

码头运行 - 图像启动命令本身
-R M - 意味着停止容器后,它会删除其生命周期中创建的所有内容
-v“$PWD”:/home/gradle/ - 将当前的 Android 项目文件夹挂载到容器的内部文件夹 /home/gradle/
-w /home/gradle - 设置容器的工作目录
android-build:5.4.1-28-27 - 我们收集的容器的名称
gradle assemble调试 - 构建团队本身,负责组装我们的项目

如果一切顺利,那么几秒钟/分钟后你会看到类似的内容 在 8 米 3 秒内成功构建! 在 app/build/output/apk 文件夹中将会有一个组装的应用程序。

同样,您可以执行其他 gradle 任务 - 检查项目、运行测试等。 主要优点是,如果我们需要在任何其他机器上构建项目,我们不需要担心安装整个环境,下载必要的映像并在其中运行构建就足够了。

容器不存储任何更改,每个程序集都是从头开始启动的,这样一方面保证了程序集的身份,无论在哪里启动,另一方面每次都必须下载所有依赖项并再次编译所有代码,这有时会花费大量时间。 因此,除了通常的“冷”启动之外,我们还可以选择在保持所谓的状态的同时启动组装。 “cache”,我们通过简单地将 ~/.gradle 文件夹复制到项目的工作文件夹来保存它,并在下一个构建开始时将其返回。 我们将所有复制过程移至单独的脚本中,启动命令本身开始如下所示

docker run --rm -v "$PWD":/home/gradle/ -w /home/gradle android-build:5.4.1-28-27 /bin/bash -c "./pre.sh; gradle assembleDebug; ./post.sh"

结果,平均项目构建时间减少了数倍(取决于项目的依赖项数量,但平均项目因此开始在 1 分钟内构建,而不是 5 分钟)。

仅当您拥有自己支持的内部 CI/CD 服务器时,所有这一切本身才有意义。 但现在有很多云服务,所有这些问题都得到了解决,你不必担心,而且还可以在项目设置中指定必要的构建属性。

只有注册用户才能参与调查。 登录拜托

您将 CI/CD 系统保留在内部还是使用第三方服务

  • 使用内部服务器

  • 使用外部服务

  • 我们不使用 CI/CD

  • 其他

42 位用户投票。 16 名用户弃权。

来源: habr.com

添加评论