Skip to content

Building APKs

aaalllexxx edited this page Jun 29, 2026 · 2 revisions

Building APKs

ENPAF turns your project into a native Android APK using Gradle + Chaquopy. The build runs natively on Windows (and macOS/Linux) — no WSL or Docker.

Prerequisites

  • JDK 17–21 and the Android SDK — see Installation.
  • Run paf doctor to confirm both are detected.

Commands

paf build apk                 # debug build (auto-signed, installable)
paf build apk --release       # release build (optimized + release-signed)
paf build apk --release --keystore mykeys.jks
paf build apk --clean         # wipe the build dir first
paf build aab                 # Android App Bundle (implies release)

The finished artifact is copied to dist/<name>-<version>.apk, where name and version come from enpaf.json.

Install it:

adb install dist/myapp-1.0.0.apk

…or use the Companion app + paf serve to install over Wi-Fi.

Debug vs. release

paf build apk paf build apk --release
Gradle task assembleDebug assembleRelease
Signing debug-signed release-signed (see Release & Signing)
Optimization none release variant
Use for quick testing distribution

Both produce an installable, signed APK — an unsigned release APK can't be installed, so ENPAF always signs release builds.

What happens under the hood

  1. Validate the project (enpaf.json, main.py, app/index.html).
  2. Check the environment — resolve a compatible JDK (pinning JAVA_HOME if the default Java is too new) and locate the Android SDK.
  3. Generate a complete Gradle/Chaquopy Android project into the build dir:
    • MainActivity (Java) hosting a WebView.
    • Your app/ copied to assets/www/.
    • The framework's Python modules + your main.py as Chaquopy sources.
    • A manifest from your enpaf.json (permissions, features, deep links, icon).
    • python_requirements wired into Chaquopy's pip { install ... }.
  4. Run Gradle (assembleDebug/assembleRelease).
  5. Copy the APK to dist/.

Toolchain versions: Gradle 8.4, AGP 8.2, Chaquopy 15.0.1, compileSdk 34 (defaults; min_sdk/target_sdk come from enpaf.json).

Where the build runs

By default the Gradle project is generated in .enpaf_build/ inside your project. If the project is under OneDrive, the build is relocated to %LOCALAPPDATA%\enpaf\builds\<name>-<hash> to avoid OneDrive's file locks. The APK is still copied back to your project's dist/.

Override the build location with ENPAF_BUILD_DIR:

$env:ENPAF_BUILD_DIR = "D:\enpaf-builds"
paf build apk --release

Tips

  • First build is slow (downloads Gradle + Android deps; Chaquopy assembles the Python runtime). Later builds reuse the cache.
  • A code change only takes effect in a new APK — an already-installed APK won't pick it up until you rebuild and reinstall.
  • Bump version in enpaf.json for updates. versionCode is derived from it (major*10000 + minor*100 + patch); reinstalling the same version over an existing app is rejected by Android. See Troubleshooting.
  • Keep build_config.minify off unless you've verified your Python/JNI deps survive R8 shrinking.
  • If a build fails, run paf doctor and check JDK/SDK first; see Troubleshooting.

CI builds

The framework's GitHub Actions build the Python distribution (wheel/sdist), not APKs — APK builds need the Android SDK + Chaquopy and are best run locally or on a dedicated runner. See Testing & CI.

Clone this wiki locally