(Experimental) Android Builds

This page provides an example of using Mill as a build tool for Android applications. This workflow is still pretty rough and nowhere near production ready, but can serve as a starting point for further experimentation and development.

Relevant Modules

These are the main Mill Modules that are relevant for building Android apps:

Simple Android Hello World Application

This section sets up a basic Android project using Mill. We utilize AndroidAppKotlinModule and AndroidSdkModule to streamline the process of building an Android application with minimal configuration.

By extending AndroidAppKotlinModule, we inherit all Android-related tasks such as resource generation, APK building, DEX conversion, and APK signing. Additionally, AndroidSdkModule is embedded, making SDK management seamless.

build.mill (download, browse)
package build

import mill._
import kotlinlib._
import mill.kotlinlib.android.AndroidAppKotlinModule
import mill.javalib.android.AndroidSdkModule

Create and configure an Android SDK module to manage Android SDK paths and tools.

object androidSdkModule0 extends AndroidSdkModule{
  def buildToolsVersion = "35.0.0"
}

Actual android application

object app extends AndroidAppKotlinModule {

  def kotlinVersion = "2.0.0"
  def androidSdkModule = mill.define.ModuleRef(androidSdkModule0)
}
> ./mill show app.androidApk
".../out/app/androidApk.dest/app.apk"

This command triggers the build process, which installs the Android Setup, compiles the kotlin code, generates Android resources, converts kotlin bytecode to DEX format, packages everything into an APK, optimizes the APK using zipalign, and finally signs it.

This Mill build configuration is designed to build a simple "Hello World" Android application. By extending AndroidAppKotlinModule, we leverage its predefined Android build tasks, ensuring that all necessary steps (resource generation, APK creation, and signing) are executed automatically.

Project Structure:

The project follows the standard Android app layout. Below is a typical project folder structure:

.
├── build.mill
├── AndroidManifest.xml
└── app/src/main/kotlin
    └── com/helloworld/app
        └── MainActivity.kt

This example demonstrates how to create a basic "Hello World" Android application using the Mill build tool. It outlines the minimum setup required to compile Kotlin code, package it into an APK, and run the app on an Android device.

Understanding AndroidSdkModule and AndroidAppKotlinModule

The two main modules you need to understand when building Android apps with Mill are AndroidSdkModule and AndroidAppKotlinModule.

AndroidSdkModule:

  • This module manages the installation and configuration of the Android SDK, which includes tools like aapt, d8, zipalign, and apksigner. These tools are used for compiling, packaging, and signing Android applications.

AndroidAppKotlinModule: This module provides the step-by-step workflow for building an Android app. It handles everything from compiling the code to generating a signed APK for distribution.

  1. Compiling Kotlin code: The module compiles your Kotlin code into .class files, which is the first step in creating an Android app.

  2. Packaging into JAR: It then packages the compiled .class files into a JAR file, which is necessary before converting to Android’s format.

  3. Converting to DEX format: The JAR file is converted into DEX format, which is the executable format for Android applications.

  4. Creating an APK: The DEX files and Android resources (like layouts and strings) are packaged together into an APK file, which is the installable file for Android devices.

  5. Optimizing with zipalign: The APK is optimized using zipalign to ensure better performance on Android devices.

  6. Signing the APK: Finally, the APK is signed with a digital signature, allowing it to be distributed and installed on Android devices.