Bei der Entwicklung eines Projekts für die Android-Plattform steht man früher oder später vor der Herausforderung, eine geeignete Entwicklungsumgebung einzurichten. Neben dem Android SDK sind die neuesten Versionen von Kotlin, Gradle, platform-tools und build-tools erforderlich. Während auf dem Entwicklungsrechner diese Abhängigkeiten weitgehend über die Android Studio IDE gelöst werden, kann jedes Update auf einem CI/CD-Server zu einer echten Herausforderung werden. In der Webentwicklung hat sich Docker als Standardlösung für das Problem der Umgebung etabliert – warum nicht auch für die Android-Entwicklung?
Für diejenigen, die nicht wissen, was Docker ist: Einfach gesagt, es handelt sich um ein Tool zur Erstellung sogenannter "Container", in denen ein minimales Betriebssystem-Kernel und die erforderliche Software enthalten sind, die wir überall bereitstellen können, während wir die Umgebung beibehalten. Was genau in unserem Container enthalten ist, wird in der Dockerfile festgelegt, die dann in ein Image erstellt wird, das überall ausgeführt werden kann und die Eigenschaft der Idempotenz aufweist.
Der Installationsprozess und die Grundlagen von Docker sind hervorragend auf seiner Um ein wenig vorzugreifen, hier ist der Dockerfile, den wir erstellt haben.
# Т.к. основным инструментом для сборки 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"
Wir speichern ihn im Ordner unseres Android-Projekts und starten den Container-Bau mit dem Befehl
docker build -t android-build:5.4-28-27 .Parameter -t setzt das Tag oder den Namen unseres Containers, der normalerweise aus dem Namen und der Versionsnummer besteht. In unserem Fall haben wir ihn android-build genannt und die Version setzt sich aus den Versionen von Gradle, Android-SDK und Platform-Tools zusammen. So können wir später das benötigte Image einfacher nach dem Namen suchen, indem wir diese „Version“ verwenden.
Nachdem der Build abgeschlossen ist, können wir unser Image lokal verwenden oder es mit dem Befehl docker push in ein öffentliches oder privates Image-Repository hochladen, um es auf anderen Maschinen zu verwenden.
Als Beispiel bauen wir das Projekt lokal. Dazu führen wir in dem Projektordner den Befehl aus
docker run --rm -v "$PWD":/home/gradle/ -w /home/gradle android-build:5.4.1-28-27 gradle assembleDebugLassen Sie uns untersuchen, was er bedeutet:
docker run — der Befehl zum Starten des Images
-rm — bedeutet, dass der Container nach dem Stoppen alles, was während seines Lebenszyklus erstellt wurde, entfernt.
-v "$PWD":/home/gradle/ — bindet den aktuellen Ordner mit unserem Android-Projekt in den internen Ordner des Containers /home/gradle/
-w /home/gradle — legt das Arbeitsverzeichnis des Containers fest
android-build:5.4.1-28-27 — der Name unseres Containers, den wir erstellt haben
gradle assembleDebug — das ist der eigentliche Build-Befehl, der unser Projekt erstellt
Wenn alles gut geht, sehen Sie in ein paar Sekunden/Minuten etwas wie BUILD SUCCESSFUL in 8m 3s! Und im Ordner app/build/output/apk liegt die erstellte Anwendung.
Ähnlich können auch andere Gradle-Aufgaben ausgeführt werden – das Projekt überprüfen, Tests durchführen usw. Der Hauptvorteil ist, dass wir uns beim benötigten Build des Projekts auf einem anderen Rechner keine Sorgen um die Installation der gesamten Umgebung machen müssen; es reicht, das erforderliche Image herunterzuladen und den Build darin auszuführen.
Der Container speichert keine Änderungen, und jeder Build beginnt von Grund auf, was einerseits die Identität des Builds unabhängig vom Startort garantiert, andererseits jedoch bedeutet, dass alle Abhängigkeiten jedes Mal heruntergeladen und der gesamte Code neu kompiliert werden muss, was manchmal erhebliche Zeit in Anspruch nehmen kann. Daher haben wir neben dem herkömmlichen "kalten" Start auch eine Möglichkeit geschaffen, den Build mit der Speicherung eines sogenannten "Caches" zu starten, bei dem wir den Ordner ~/.gradle einfach in das Arbeitsverzeichnis des Projekts kopieren und zu Beginn des nächsten Builds wieder zurückführen. Alle Kopiervorgänge haben wir in separate Skripte ausgelagert, und der Befehl zum Starten sieht nun so aus.
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"Insgesamt hat sich die durchschnittliche Build-Zeit unseres Projekts um ein Vielfaches verkürzt (abhängig von der Anzahl der Abhängigkeiten im Projekt, aber ein durchschnittliches Projekt wird auf diese Weise in 1 Minute statt in 5 Minuten gebaut).
All dies macht nur Sinn, wenn Sie einen eigenen internen CI/CD-Server haben, um den Sie sich selbst kümmern. Aber heutzutage gibt es viele Cloud-Services, bei denen all diese Probleme gelöst sind, und Sie müssen sich nicht darum kümmern. Die benötigten Build-Eigenschaften können ebenfalls in den Projekteinstellungen angegeben werden.
Nur registrierte Benutzer können an der Umfrage teilnehmen. Sind Sie an Contour interessiert?
Betreiben Sie ein internes CI/CD-System oder nutzen Sie einen externen Service?
Wir verwenden einen internen Server
Wir nutzen einen externen Service
Wir verwenden kein CI/CD
Sonstiges
42 Benutzer haben abgestimmt. 16 Benutzer haben sich enthalten.
Quelle: habr.com
