Når man utvikler et prosjekt for Android-plattformen, uansett hvor lite det er, kommer man før eller siden til å måtte forholde seg til et utviklingsmiljø. I tillegg til Android SDK er det nødvendig å ha den nyeste versjonen av Kotlin, Gradle, platform-tools og build-tools. Mens disse avhengighetene på utviklerens maskin i stor grad løses ved hjelp av Android Studio IDE, kan hvert oppdatering på CI/CD-serveren bli en hodepine. I webutvikling har Docker blitt en standardløsning for miljøproblemer, så hvorfor ikke prøve å løse tilsvarende problemer innen Android-utvikling...
For de som ikke vet hva Docker er — kort sagt, det er et verktøy for å lage såkalte "containere", hvor det finnes et minimalt OS-kjerne og nødvendig programvare, som vi kan distribueres hvor som helst, mens vi bevarer miljøet. Hva som vil være i containeren vår, bestemmes i Dockerfile, som deretter bygges til et bilde som kan kjøres hvor som helst og har egenskapene til idempotens.
Installasjonsprosessen og grunnleggende konsepter i Docker er godt beskrevet i . Så, for å komme et steg videre, her er Dockerfile vi har fått.
# Т.к. основным инструментом для сборки 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"
Vi lagrer den i mappen med vårt Android-prosjekt og starter byggingen av containeren med kommandoen
docker build -t android-build:5.4-28-27 .Parameter -t setter tag eller navn på containeren vår, som vanligvis består av navnet og versjonen. I vårt tilfelle kalte vi den android-build, og i versjonen spesifiserte vi samlet versjoner av gradle, android-sdk og platform-tools. Senere blir det enklere å finne det aktuelle bildet etter navn ved hjelp av en slik "versjon".
Etter at byggingen er fullført, kan vi bruke bildet vårt lokalt, eller vi kan laste det opp med kommandoen docker push til et offentlig eller privat bilde-repositorium for å laste det ned på andre maskiner.
Som et eksempel vil vi bygge prosjektet lokalt. For dette utfører vi kommandoen i prosjektmappen
docker run --rm -v "$PWD":/home/gradle/ -w /home/gradle android-build:5.4.1-28-27 gradle assembleDebugLa oss analysere hva den betyr:
docker run — selve kommandoen for å kjøre bildet
-rm — betyr at etter at containeren stoppes, vil den fjerne alt som ble opprettet i løpet av dens livstid
-v "$PWD":/home/gradle/ — monterer den nåværende mappen med vårt Android-prosjekt til den interne mappen i containeren /home/gradle/
-w /home/gradle — angir arbeidskatalogen i containeren
android-build:5.4.1-28-27 — navnet på containeren vår som vi har bygget
gradle assembleDebug — selve bygningslaget som bygger prosjektet vårt
Hvis alt går bra, vil du om et par sekunder/minutter se noe som ligner på skjermen din BYGG SUKSESSFULLT på 8m 3s! Og i mappen app/build/output/apk vil den byggede applikasjonen ligge.
På samme måte kan andre gradle-oppgaver utføres — sjekke prosjektet, kjøre tester osv. Hovedfordelen er at vi, hvis vi trenger å bygge prosjektet på en annen maskin, ikke trenger å bekymre oss for å installere hele miljøet, men bare laste ned det nødvendige bildet og kjøre byggingen.
Beholderen lagrer ingen endringer, og hver bygging starter fra bunnen av, noe som på den ene siden garanterer at byggingen er identisk uansett hvor den kjøres, men på den andre siden må vi alltid laste ned alle avhengigheter og kompilere all koden på nytt, noe som noen ganger kan ta betydelig tid. Derfor, i tillegg til vanlig 'kalde' oppstart, har vi et alternativ for å starte byggingen med bevaring av såkalte 'cacher', der vi lagrer mappen ~/ .gradle ved å kopiere den til prosjektets arbeidsmappe, og i begynnelsen av neste bygging returnerer vi den tilbake. Alle kopieringsprosedyrer har vi flyttet til separate skripter, og selve oppstartskommandoen ser nå slik ut
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"Som et resultat har den gjennomsnittlige tiden for å bygge prosjektet blitt redusert flere ganger (avhengig av antallet avhengigheter i prosjektet, men et gjennomsnittlig prosjekt bygges nå på 1 minutt i stedet for 5 minutter).
Alt dette gir mening bare hvis du har din egen interne CI/CD-server, hvis du selv håndterer vedlikeholdet av den. Men i dag finnes det mange skytjenester der disse problemene er løst, og du trenger ikke å bekymre deg for dette, og de nødvendige bygginstillingene kan også angis i prosjektinnstillingene.
Kun registrerte brukere kan delta i undersøkelsen. , vær så snill.
Har du et CI/CD-system internt eller bruker du en ekstern tjeneste?
Bruker intern server
Bruker ekstern tjeneste
Bruker ikke CI/CD
Other
42 brukere stemte. 16 brukere avsto.
Kilde: habr.com
