[{"categories":["Android","Docker"],"content":" Alpine Android https:\/\/github.com\/alvr\/alpine-android ","date":"March 29, 2017","objectID":"\/projects\/alpine-android\/:0:0","tags":["alpine","continuous deployment","continuous integration","docker","docker container"],"title":"Alpine Android","uri":"\/projects\/alpine-android\/"},{"categories":["Android","Docker"],"content":"Description Alpine Android is a lightweight Docker image for compiling and testing Android applications. Based on Alpine\u2019s image, it makes the size smaller compared to Debian or Ubuntu based images. Also, there are different images per SDK and only the minimum packages are included. SDK versions from Android 28 to Android 36 are available. Each version of the SDK has its own image, being the identifier alvrme\/alpine-android:android-<version>. If you always want to refer to the latest stable Android version available, you can also use alvrme\/alpine-android:latest. ","date":"March 29, 2017","objectID":"\/projects\/alpine-android\/:1:0","tags":["alpine","continuous deployment","continuous integration","docker","docker container"],"title":"Alpine Android","uri":"\/projects\/alpine-android\/"},{"categories":["Android","Docker"],"content":"Alpine Android Base The image the specific Android SDK\u2019s images are based on. This makes it easy to update the images that extend from it, since only the necessary Dockerfile would have to be modified. ","date":"March 29, 2017","objectID":"\/projects\/alpine-android\/:2:0","tags":["alpine","continuous deployment","continuous integration","docker","docker container"],"title":"Alpine Android","uri":"\/projects\/alpine-android\/"},{"categories":["Android","Docker"],"content":"Use as base image To extend the base image and be able to configure your own image with the packages and applications you want, just add the following line to the top of Dockerfile: FROM alvrme\/alpine-android-base ","date":"March 29, 2017","objectID":"\/projects\/alpine-android\/:2:1","tags":["alpine","continuous deployment","continuous integration","docker","docker container"],"title":"Alpine Android","uri":"\/projects\/alpine-android\/"},{"categories":["Android","Docker"],"content":"Install applications and packages You can install any Alpine application from the following list by adding the following command to the `Dockerfile RUN apk add --no-cache <package1> <package2> <...> && \\ rm -rf \/tmp\/* \/var\/tmp\/* Similarly, you can install any available package of Android: RUN sdkmanager --sdk_root=${ANDROID_SDK_ROOT} --install <package1> <package2> <...> ","date":"March 29, 2017","objectID":"\/projects\/alpine-android\/:2:2","tags":["alpine","continuous deployment","continuous integration","docker","docker container"],"title":"Alpine Android","uri":"\/projects\/alpine-android\/"},{"categories":["Android","Docker"],"content":"Variants There are three variants of the image, all based on bellsoft\/liberica-openjdk-alpine: JDK8 images are based on Liberica JDK 8u422-7 and uses the tag\u2019s suffix -jdk8. JDK11 images are based on Liberica JDK 11.0.26-9 and uses the tag\u2019s suffix -jdk11. JDK17 images are based on Liberica JDK 17.0.14-10 and uses the tag\u2019s suffix -jdk17. JDK21 images are based on Liberica JDK 21.0.6+10 and uses the tag\u2019s suffix -jdk21. ","date":"March 29, 2017","objectID":"\/projects\/alpine-android\/:3:0","tags":["alpine","continuous deployment","continuous integration","docker","docker container"],"title":"Alpine Android","uri":"\/projects\/alpine-android\/"},{"categories":["Android","Docker"],"content":"Which one should I use? JDK version AGP version 8 < 7.0.0 11 >= 7.0.0 && < 8.0.0 17 >= 8.0.0 21 >= 8.2.1 This makes it easy to update the images that extend from it, since only the necessary Dockerfile would have to be modified. ","date":"March 29, 2017","objectID":"\/projects\/alpine-android\/:3:1","tags":["alpine","continuous deployment","continuous integration","docker","docker container"],"title":"Alpine Android","uri":"\/projects\/alpine-android\/"},{"categories":["Android","Docker"],"content":"Tagging API level JDK8 JDK11 JDK17 JDK21 Base Image jdk8 latest-jdk8 jdk11, latest-jdk11 jdk17, latest, latest-jdk17 jdk21, latest-jdk21 Android 9.0 (28) android-28-jdk8 android-28, android-28-jdk11 android-28-jdk17 android-28-jdk21 Android 10 (29) android-29-jdk8 android-29, android-29-jdk11 android-29-jdk17 android-29-jdk21 Android 11 (30) android-30-jdk8 android-30, android-30-jdk11 android-30-jdk17 android-30-jdk21 Android 12 (31) android-31-jdk8 android-31, android-31-jdk11 android-31-jdk17 android-31-jdk21 Android 12L (32) android-32-jdk8 android-32, android-32-jdk11 android-32-jdk17 android-32-jdk21 Android 13 (33) android-33-jdk8 android-33, android-33-jdk11 android-33-jdk17 android-33-jdk21 Android 14 (34) android-34-jdk8 android-34, android-34-jdk11 android-34-jdk17 android-34-jdk21 Android 15 (35) android-35-jdk8, latest-jdk8 android-35, android-35-jdk11, latest-jdk11 android-35-jdk17, latest, latest-jdk17 android-35-jdk21, latest-jdk21 Android 16 (36) android-36-jdk8 android-36, android-36-jdk11 android-36-jdk17 android-36-jdk21 ","date":"March 29, 2017","objectID":"\/projects\/alpine-android\/:4:0","tags":["alpine","continuous deployment","continuous integration","docker","docker container"],"title":"Alpine Android","uri":"\/projects\/alpine-android\/"},{"categories":["Android","Docker"],"content":"Versioning Since January 1st 2021, new versions now include the date it was published so is possible to revert to a previous version. The versioning only applies to tags with the JDK version specified. The tag\u2019s format is: android-XX-jdkZZ-vYYYY.MM.DD, where: XX is the API level. ZZ is the version of the JDK. YYYY is the year of the release version. MM is the month of the year of the release version with leading zeros. DD is the day of the month of the release version with leading zeros. A valid example would be android-30-jdk11-v2021.01.01. Here are listed all the versions. \ud83d\udcdd The versioning is not available for alpine-android-base. ","date":"March 29, 2017","objectID":"\/projects\/alpine-android\/:4:1","tags":["alpine","continuous deployment","continuous integration","docker","docker container"],"title":"Alpine Android","uri":"\/projects\/alpine-android\/"},{"categories":["Android","Docker"],"content":"Tools included Below is a list of all the tools included with the installation of the different packages. Those with their own documentation are linked. Gradle The gradle package is not installed, so the command in the PATH is not available. The reason for this is that the package may be outdated and not compatible with any of the APIs used in the configuration. That\u2019s why you should always use the wrapper that comes with the project and whose version is indicated in the gradle-wrapper.properties file. You can consult here how to configure the wrapper to use it in the different CI\/CD services. ","date":"March 29, 2017","objectID":"\/projects\/alpine-android\/:5:0","tags":["alpine","continuous deployment","continuous integration","docker","docker container"],"title":"Alpine Android","uri":"\/projects\/alpine-android\/"},{"categories":["Android","Docker"],"content":"Command-line apkanalyzer: Provides insight into the composition of your APK after the build process completes. avdmanager: Allows you to create and manage Android Virtual Devices (AVDs) from the command line. lint: A code scanning tool that can help you to identify and correct problems with the structural quality of your code. screenshot2: Do a screenshot of the running emulator. sdkmanager: Allows you to view, install, update, and uninstall packages for the Android SDK. ","date":"March 29, 2017","objectID":"\/projects\/alpine-android\/:5:1","tags":["alpine","continuous deployment","continuous integration","docker","docker container"],"title":"Alpine Android","uri":"\/projects\/alpine-android\/"},{"categories":["Android","Docker"],"content":"SDK build aapt2: Parses, indexes, and compiles Android resources into a binary format that is optimized for the Android platform, and packages the compiled resources into a single output. apksigner: Signs APKs and checks whether APK signatures will be verified successfully on all platform versions that a given APK supports. zipalign: Optimizes APK files by ensuring that all uncompressed data starts with a particular alignment relative to the start of the file. ","date":"March 29, 2017","objectID":"\/projects\/alpine-android\/:5:2","tags":["alpine","continuous deployment","continuous integration","docker","docker container"],"title":"Alpine Android","uri":"\/projects\/alpine-android\/"},{"categories":["Android","Docker"],"content":"SDK platform adb: Android Debug Bridge (adb) is a versatile tool that lets you manage the state of an emulator instance or Android-powered device. You can also use it to install an APK on a device. etc1tool: A command line utility that lets you encode PNG images to the ETC1 compression standard and decode ETC1 compressed images back to PNG. fastboot: Flashes a device with platform and other system images. logcat: This is a tool invoked via adb to view app and system logs. ","date":"March 29, 2017","objectID":"\/projects\/alpine-android\/:5:3","tags":["alpine","continuous deployment","continuous integration","docker","docker container"],"title":"Alpine Android","uri":"\/projects\/alpine-android\/"},{"categories":["Android","Docker"],"content":"Other tools ia: Check and run an instant application. In addition to the above Android-specific tools, the BusyBox commands and packages installed on the base image are also available: git unzip wget ","date":"March 29, 2017","objectID":"\/projects\/alpine-android\/:5:4","tags":["alpine","continuous deployment","continuous integration","docker","docker container"],"title":"Alpine Android","uri":"\/projects\/alpine-android\/"},{"categories":["Android","Docker"],"content":"Extras The base image also includes the extras command that contains small utilities that are not installed by default, since their use is not widespread. These extras are executed with the command extras <command> and are the following: Fastlane fastlane is a tool for iOS and Android developers to automate tedious tasks like generating screenshots, dealing with provisioning profiles, and releasing your application. Visit their documentation for more information. This command allows you to install fastlane. There are two variants: extras fastlane This command allows you to install the latest version of fastlane. If you want to use a specific version, the command is as follows: extras fastlane [VERSION] NDK & CMake NDK (Native Development Kit) is a toolset that allows developers to implement parts of Android applications using native-code languages such as C and C++. CMake is a cross-platform build system generator that helps manage the software build process in a compiler-independent way. To install NDK and\/or CMake, execute the following command: extras ndk [--ndk | -n NDK_VERSION] [--cmake | -c CMAKE_VERSION] ","date":"March 29, 2017","objectID":"\/projects\/alpine-android\/:5:5","tags":["alpine","continuous deployment","continuous integration","docker","docker container"],"title":"Alpine Android","uri":"\/projects\/alpine-android\/"},{"categories":["Android","Docker"],"content":"Content of each image See content of Android Base image Path Version Description Location extras;google;instantapps 1.9.0 Google Play Instant Development SDK extras\/google\/instantapps\/ patcher;v4 1 SDK Patch Applier v4 patcher\/v4\/ platform-tools 35.0.2 Android SDK Platform-Tools platform-tools\/ See content of Android 9 (Pie) image Path Version Description Location build-tools;28.0.3 28.0.3 Android SDK Build-Tools build-tools\/28.0.3\/ extras;google;instantapps 1.9.0 Google Play Instant Development SDK extras\/google\/instantapps\/ patcher;v4 1 SDK Patch Applier v4 patcher\/v4\/ platform-tools 35.0.2 Android SDK Platform-Tools platform-tools\/ platforms;android-28 6 Android SDK Platform 28 platforms\/android-28\/ See content of Android 10 (Q) image Path Version Description Location build-tools;29.0.3 29.0.3 Android SDK Build-Tools build-tools\/29.0.3\/ extras;google;instantapps 1.9.0 Google Play Instant Development SDK extras\/google\/instantapps\/ patcher;v4 1 SDK Patch Applier v4 patcher\/v4\/ platform-tools 35.0.2 Android SDK Platform-Tools platform-tools\/ platforms;android-29 5 Android SDK Platform 29 platforms\/android-29\/ See content of Android 11 (R) image Path Version Description Location build-tools;30.0.3 30.0.3 Android SDK Build-Tools build-tools\/30.0.3\/ extras;google;instantapps 1.9.0 Google Play Instant Development SDK extras\/google\/instantapps\/ patcher;v4 1 SDK Patch Applier v4 patcher\/v4\/ platform-tools 35.0.2 Android SDK Platform-Tools platform-tools\/ platforms;android-30 3 Android SDK Platform 30 platforms\/android-30\/ See content of Android 12 (S) image Path Version Description Location build-tools;31.0.0 31.0.0 Android SDK Build-Tools build-tools\/31.0.0\/ extras;google;instantapps 1.9.0 Google Play Instant Development SDK extras\/google\/instantapps\/ patcher;v4 1 SDK Patch Applier v4 patcher\/v4\/ platform-tools 35.0.2 Android SDK Platform-Tools platform-tools\/ platforms;android-31 1 Android SDK Platform 31 platforms\/android-31\/ See content of Android 12L image Path Version Description Location build-tools;32.0.0 32.0.0 Android SDK Build-Tools build-tools\/32.0.0\/ extras;google;instantapps 1.9.0 Google Play Instant Development SDK extras\/google\/instantapps\/ patcher;v4 1 SDK Patch Applier v4 patcher\/v4\/ platform-tools 35.0.2 Android SDK Platform-Tools platform-tools\/ platforms;android-32 1 Android SDK Platform 32 platforms\/android-32\/ See content of Android 13 (Tiramisu) image Path Version Description Location build-tools;33.0.2 33.0.3 Android SDK Build-Tools build-tools\/33.0.3\/ extras;google;instantapps 1.9.0 Google Play Instant Development SDK extras\/google\/instantapps\/ patcher;v4 1 SDK Patch Applier v4 patcher\/v4\/ platform-tools 35.0.2 Android SDK Platform-Tools platform-tools\/ platforms;android-33 2 Android SDK Platform 33 platforms\/android-33\/ See content of Android 14 (Upside-down Cake) image Path Version Description Location build-tools;34.0.0 34.0.0 Android SDK Build-Tools build-tools\/34.0.0\/ extras;google;instantapps 1.9.0 Google Play Instant Development SDK extras\/google\/instantapps\/ patcher;v4 1 SDK Patch Applier v4 patcher\/v4\/ platform-tools 35.0.2 Android SDK Platform-Tools platform-tools\/ platforms;android-34 3 Android SDK Platform 34 platforms\/android-34\/ See content of Android 15 (VanillaIceCream) image Path Version Description Location build-tools;35.0.1 35.0.1 Android SDK Build-Tools build-tools\/35.0.1\/ extras;google;instantapps 1.9.0 Google Play Instant Development SDK extras\/google\/instantapps\/ patcher;v4 1 SDK Patch Applier v4 patcher\/v4\/ platform-tools 35.0.2 Android SDK Platform-Tools platform-tools\/ platforms;android-35 2 Android SDK Platform 35 platforms\/android-35\/ See content of Android 16 (Baklava) image Path Version Description Location build-tools;36.0.0 36.0.0 Android SDK Build-Tools build-tools\/36.0.0\/ extras;google;instantapps 1.9.0 Google Play Instant Development SDK extras\/google\/instantapps\/ patcher;v4 1 SDK Patch Applier v4 patcher\/v4\/ platform-tools 36.0.0 Android SDK Platform-Tools platform-tools","date":"March 29, 2017","objectID":"\/projects\/alpine-android\/:6:0","tags":["alpine","continuous deployment","continuous integration","docker","docker container"],"title":"Alpine Android","uri":"\/projects\/alpine-android\/"},{"categories":["Android","Docker"],"content":"Container registries Because of the DockerHub rate limits, the image is now in three different containers registries: DockerHub: Base Image and Android Image. GitHub Container Registry: Base Image and Android Image. Quay: Base Image and Android Image. ","date":"March 29, 2017","objectID":"\/projects\/alpine-android\/:7:0","tags":["alpine","continuous deployment","continuous integration","docker","docker container"],"title":"Alpine Android","uri":"\/projects\/alpine-android\/"},{"categories":["Android","Docker"],"content":"As base image Replace <tag> with one of the current available tags. DockerHub\u2019s base image You can use the Docker images from DockerHub as a base image for creating a new one: FROM alvrme\/alpine-android-base:<tag> FROM alvrme\/alpine-android:<tag> GHCR\u2019s base image You can use the Docker images from GitHub Container Registry as a base image for creating a new one: FROM ghcr.io\/alvr\/alpine-android-base:<tag> FROM ghcr.io\/alvr\/alpine-android:<tag> Quay\u2019s base image You can use the Docker images from Quay as a base image for creating a new one: FROM quay.io\/alvr\/alpine-android-base:<tag> FROM quay.io\/alvr\/alpine-android:<tag> ","date":"March 29, 2017","objectID":"\/projects\/alpine-android\/:7:1","tags":["alpine","continuous deployment","continuous integration","docker","docker container"],"title":"Alpine Android","uri":"\/projects\/alpine-android\/"},{"categories":["Android","Docker"],"content":"Pulling Replace <tag> with one of the current available tags. DockerHub pulling You can pull a specific Docker image from DockerHub with the following command: docker pull alvrme\/alpine-android-base:<tag> docker pull alvrme\/alpine-android:<tag> GHCR pulling You can pull a specific Docker image from GitHub Container Registry with the following command: docker pull ghcr.io\/alvr\/alpine-android-base:<tag> docker pull ghcr.io\/alvr\/alpine-android:<tag> Quay pulling You can pull a specific Docker image from Quay with the following command: docker pull quay.io\/alvr\/alpine-android-base:<tag> docker pull quay.io\/alvr\/alpine-android:<tag> ","date":"March 29, 2017","objectID":"\/projects\/alpine-android\/:7:2","tags":["alpine","continuous deployment","continuous integration","docker","docker container"],"title":"Alpine Android","uri":"\/projects\/alpine-android\/"},{"categories":["Android","Docker"],"content":"Run container Replace <tag> with one of the current available tags. The command below will create a new container based on the specific image. It will open in the \/home\/android directory and the various available commands in the PATH will be able to be executed. Once the container is closed, it will be deleted. To keep the container after closing it, you have to remove --rm from the command. DockerHub run container Run the container from the DockerHub image: docker run --rm -it alvrme\/alpine-android-base:<tag> docker run --rm -it alvrme\/alpine-android:<tag> GHCR run container Run the container from the GitHub Container Registry image: docker run --rm -it ghcr.io\/alvr\/alpine-android-base:<tag> docker run --rm -it ghcr.io\/alvr\/alpine-android:<tag> Quay run container Run the container from the Quay image: docker run --rm -it quay.io\/alvr\/alpine-android-base:<tag> docker run --rm -it quay.io\/alvr\/alpine-android:<tag> ","date":"March 29, 2017","objectID":"\/projects\/alpine-android\/:7:3","tags":["alpine","continuous deployment","continuous integration","docker","docker container"],"title":"Alpine Android","uri":"\/projects\/alpine-android\/"},{"categories":["Android","Docker"],"content":"Use in different CI\/CD Here are different configurations for some of the available CI\/CD services. Before you start, remember that you must use Gradle\u2019s wrapper and it needs execution permissions. To give execution permissions to an executable, add chmod +x .\/gradlew to the steps, or use git update-index --chmod=+x .\/gradlew in the repository and then push the changes. This way, you don\u2019t have to give permissions every time. ","date":"March 29, 2017","objectID":"\/projects\/alpine-android\/:8:0","tags":["alpine","continuous deployment","continuous integration","docker","docker container"],"title":"Alpine Android","uri":"\/projects\/alpine-android\/"},{"categories":["Android","Docker"],"content":"CircleCI An example of CircleCI configuration. For more information, visit the official documentation. version: 2 jobs: build: docker: - image: alvrme\/alpine-android:android-<version> environment: JVM_OPTS: -Xmx3200m steps: - checkout - restore_cache: key: jars-{{ checksum \"build.gradle\" }}-{{ checksum \"app\/build.gradle\" }} - run: # Can omit if used `git update-index --chmod=+x .\/gradlew` before. name: Chmod command: chmod +x .\/gradlew - run: name: Download dependencies command: .\/gradlew androidDependencies - save_cache: paths: - ~\/.gradle key: jars-{{ checksum \"build.gradle\" }}-{{ checksum \"app\/build.gradle\" }} - run: name: Compile command: .\/gradlew build - run: name: Testing command: .\/gradlew lint test - run: name: Assemble command: | .\/gradlew assembleRelease apksigner sign --ks keystore.jks --ks-key-alias <alias> --ks-pass pass:<keystore-pass> --key-pass pass:<alias-pass> app.apk # Passwords in plain apksigner sign --ks keystore.jks --ks-key-alias <alias> --ks-pass env:<keystore-pass> --key-pass env:<alias-pass> app.apk # Passwords in envvar ","date":"March 29, 2017","objectID":"\/projects\/alpine-android\/:8:1","tags":["alpine","continuous deployment","continuous integration","docker","docker container"],"title":"Alpine Android","uri":"\/projects\/alpine-android\/"},{"categories":["Android","Docker"],"content":"GitHub An example of GitHub Actions configuration. For more information, visit the official documentation. jobs: build: container: image: alvrme\/alpine-android:android-<version> steps: - uses: actions\/checkout@v2 - name: Chmod # Can omit if used `git update-index --chmod=+x .\/gradlew` before. run: chmod +x .\/gradlew - uses: actions\/cache@v2 with: path: | ~\/.gradle\/caches ~\/.gradle\/wrapper key: ${{ runner.os }}-gradle-${{ hashFiles('**\/*.gradle*') }} restore-keys: | ${{ runner.os }}-gradle- - name: Download dependencies run: .\/gradlew androidDependencies - name: Build run: .\/gradlew build - name: Testing run: .\/gradlew lint test - name: Assemble run: | .\/gradlew assembleRelease apksigner sign --ks keystore.jks --ks-key-alias <alias> --ks-pass pass:<keystore-pass> --key-pass pass:<alias-pass> app.apk # Passwords in plain apksigner sign --ks keystore.jks --ks-key-alias <alias> --ks-pass env:<keystore-pass> --key-pass env:<alias-pass> app.apk # Passwords in envvar ","date":"March 29, 2017","objectID":"\/projects\/alpine-android\/:8:2","tags":["alpine","continuous deployment","continuous integration","docker","docker container"],"title":"Alpine Android","uri":"\/projects\/alpine-android\/"},{"categories":["Android","Docker"],"content":"GitLab An example of GitLab CI\/CD configuration. For more information, visit the official documentation. image: alvrme\/alpine-android:android-<version> before_script: - export GRADLE_USER_HOME=`pwd`\/.gradle - chmod +x .\/gradlew # Can omit if used `git update-index --chmod=+x .\/gradlew` before. cache: key: \"$CI_COMMIT_REF_NAME\" # Optional: share cache between branches paths: - .gradle\/wrapper - .gradle\/caches stages: - build - test - assemble build: stage: build script: - .\/gradlew build tests: stage: test script: - .\/gradlew lint test assemble: stage: assemble script: - .\/gradlew assembleRelease - apksigner sign --ks keystore.jks --ks-key-alias <alias> --ks-pass pass:<keystore-pass> --key-pass pass:<alias-pass> app.apk # Passwords in plain - apksigner sign --ks keystore.jks --ks-key-alias <alias> --ks-pass env:<keystore-pass> --key-pass env:<alias-pass> app.apk # Passwords in envvar ","date":"March 29, 2017","objectID":"\/projects\/alpine-android\/:8:3","tags":["alpine","continuous deployment","continuous integration","docker","docker container"],"title":"Alpine Android","uri":"\/projects\/alpine-android\/"},{"categories":null,"content":"Hello, my name is \u00c1lvaro Salcedo Garc\u00eda, a software engineer who has been programming since I was 16 years old in my spare time and now is dedicated to it professionally. Specialized in Android and Kotlin, although I also like Go and in general strong and static typed languages. In my CV (also in RxResume) I have listed my professional experience as well as my studies and the most interesting projects I have done. A more detailed list of projects is available here. ","date":"January 11, 2013","objectID":"\/about-me\/:0:0","tags":null,"title":"About me","uri":"\/about-me\/"},{"categories":null,"content":"You can contact me through email and I will try to get back to you as soon as possible. ","date":"January 11, 2013","objectID":"\/contact\/:0:0","tags":null,"title":"Contact","uri":"\/contact\/"},{"categories":["General"],"content":"What a better way to start the blog that with the first thing you do as a programmer.","date":"January 11, 2013","objectID":"\/post\/hello-world\/","tags":["hello world","welcome"],"title":"Hello World!","uri":"\/post\/hello-world\/"},{"categories":["General"],"content":"What a better way to start the blog that with the first thing you do as a programmer. fun main() { println(\"Hello World!\") } ","date":"January 11, 2013","objectID":"\/post\/hello-world\/:0:0","tags":["hello world","welcome"],"title":"Hello World!","uri":"\/post\/hello-world\/"}]