Android Java Projects

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 AndroidAppModule and AndroidSdkModule to streamline the process of building an Android application with minimal configuration.

By extending AndroidAppModule, 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 mill.javalib.android.{AndroidAppModule, AndroidSdkModule}

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

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

Actual android application

object app extends AndroidAppModule {
  def androidSdkModule = mill.define.ModuleRef(androidSdkModule0)

  // Configuration for ReleaseKey
  def androidReleaseKeyName: T[String] = Task { "releaseKey.jks" }
  def androidReleaseKeyAlias: T[String] = Task { "releaseKey" }
  def androidReleaseKeyPass: T[String] = Task { "MillBuildTool" }
  def androidReleaseKeyStorePass: T[String] = Task { "MillBuildTool" }

}
> ./mill show app.androidApk
".../out/app/androidApk.dest/app.apk"

This command triggers the build process, which installs the Android Setup, compiles the Java code, generates Android resources, converts Java 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 AndroidAppModule, 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:

.
├── app
│   ├── AndroidManifest.xml
│   ├── releaseKey.jks
│   ├── resources
│   │   └── values
│   │       ├── colors.xml
│   │       └── strings.xml
│   └── src/main/java/com/helloworld/app/MainActivity.java
└── build.mill

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 Java code, package it into an APK, and run the app on an Android device.

Understanding AndroidSdkModule and AndroidAppModule

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

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.

AndroidAppModule: 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 Java code: The module compiles your Java 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.

After creating Simple Android Application now let’s focus on how to create Android App Bundle Using Mill Build Tool

Android App Bundle

This Example provides the basic setup for building Android App Bundle using Mill Build Tool.

By extending AndroidAppBundle, we inherit all Android Bundle tasks such as Android Bundle zip generation, Bundle Creation and Bundle signing. Additionally, AndroidSdkModule is embedded, making SDK management seamless.

build.mill (download, browse)
package build

import mill._
import mill.javalib.android.{AndroidSdkModule, AndroidAppBundle}

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

object bundle extends AndroidAppBundle {
  def androidSdkModule = mill.define.ModuleRef(androidSdkModule0)

  def androidReleaseKeyName: T[String] = Task { "releaseKey.jks" }
  def androidReleaseKeyAlias: T[String] = Task { "releaseKey" }
  def androidReleaseKeyPass: T[String] = Task { "MillBuildTool" }
  def androidReleaseKeyStorePass: T[String] = Task { "MillBuildTool" }
}
> ./mill show bundle.androidBundle
".../out/bundle/androidBundle.dest/signedBundle.aab"

This command triggers the App Bundle Build process, which installs Bundle Tool then resource compilation, and then building Android Bundle Zip then Creation of Android App Bundle and finally signs it.

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

Project Structure:

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

.
├── app
│   ├── AndroidManifest.xml
│   ├── releaseKey.jks
│   ├── resources
│   │   └── values
│   │       ├── colors.xml
│   │       └── strings.xml
│   └── src/main/java/com/helloworld/app/MainActivity.java
└── build.mill

Understanding AndroidAppBundle

The AndroidAppBundle trait is used to create and manage Android App Bundles (AAB) in Mill. It provides tasks for creating, building, and signing an AAB from Android resources and DEX files.

Key Functions

  • androidAaptOptions: Here, Overrides androidAaptOptions to add the --proto-format option to AAPT commands, enabling protocol buffer format for assets.

  • androidBundleZip: Creates a zip archive containing: Compiled DEX files, Resources, libraries, and assets, The Android manifest. This zip follows the Android App Bundle format, as outlined in the official documentation.

  • androidUnsignedBundle: Uses the bundleTool to build an unsigned AAB from the bundle zip.

  • androidBundle: Signs the AAB using a specified keystore with the jarsigner tool, producing a signed Android App Bundle (AAB).