Engine
Extensions
Extensions are Java or Kotlin code compiled to one DEX file and injected into the target app by a patch. Use them when the patched app needs new code at runtime: Activities, Services, settings UIs, or logic too large to splice inline.
Project layout
Each extension is a Gradle subproject under apps/<app>/extensions/<name>/, or shared/<name>/ for code reused across apps. Its build.gradle.kts:
extra["dexOutputName"] = "<app>-<name>.dex"
apply(from = rootDir.resolve("android-extension-module.gradle.kts"))
dependencies {
add("compileOnly", project(":shared-<name>"))
}
dexOutputName: the filename of the produced DEX. Keep it stable; patches reference it by name.dexExcludeClasses: optional comma-separated list of.classfiles to exclude from the DEX (for build stubs that must not ship).- Dependencies on shared modules are
compileOnly. Each extension is emitted as its own DEX, so a non-compileOnlydependency would duplicate classes into multiple DEX files.
Referencing from a patch
A patch declares which DEX files to inject from inside its body:
extendWith("example-downloader.dex")
Multiple calls or multiple arguments are allowed. Filenames must match the dexOutputName from the extension modules.