APK update and installation
Android reads Manifest and some packaging information from the installed APK. Manifest and its associated resource table must be written back to the APK. Native libraries also use this path when SO hot update is disabled. After Jugg incrementally compiles these changes, it modifies the latest trusted Gradle APK, re-signs it, and installs it so the system reads the updated package. With SO hot update enabled, native libraries enter an overlay and load after an app restart.
This is still incremental deployment. Jugg reuses the existing APK and replaces only local files already generated in the current Run instead of rerunning a full Gradle build. After installation completes, the same Run can continue to apply classes, resources, and assets overlays.
Artifacts that must enter the APK
| Current artifact | Why the APK must be updated | Subsequent result |
|---|---|---|
AndroidManifest.xml patch | The system reads components, permissions, and other Manifest information from the install package | Write it back to the target APK, re-sign, and install |
resources.arsc associated with Manifest | Resource references in Manifest must remain consistent with the resource table | Update it in the APK together with Manifest |
| Already generated native library with SO hot update disabled | The app loads the .so from the updated APK | Write it back to the corresponding APK and reinstall |
Ordinary classes, res/**, and assets/** | Incremental overlays can carry them | Continue through Apply Changes or Hot Fix after installation |
Jugg can write only files generated by the current incremental flow. A C/C++ source change first runs the native task for the current variant. Gradle must regenerate the APK when ABI changes, packaging configuration changes, or a complete Manifest merge falls outside the current incremental result.
APK update requires re-signing
Android does not accept an APK whose content changed without an updated signature. After writing the target files, Jugg re-signs the APK with the current project signing configuration. If the signing configuration is missing or invalid, APK update fails explicitly and passes Gradle fallback eligibility to the Run layer.
The signing identity must match the package already installed on the device, otherwise the update is rejected. When a Gradle SigningConfig cannot express a platform certificate, vendor key, or server-side signing flow, the Run Configuration can enable a custom APK sign script: Jugg passes the absolute path of the aligned temporary APK as the last argument, the project script signs it in place, and Jugg still runs apksigner verify before replacing the original APK. With a script enabled, the local signing configuration is no longer a precondition for APK update, and a failed script never falls back to local keystore signing. The full contract is in Custom APK sign script.
In a multi-APK project, Jugg modifies the corresponding base, split, or test APK according to actual artifact ownership. An artifact is written only to the APK that owns it and is not placed into the base APK merely for convenience.
Installation establishes a new device baseline
The updated APK is no longer identical to the previous installation on the device. The current Run cannot continue to assume that the old deployment cache and overlay ID remain valid, so deployment enters state recovery and installs the updated APK.
generate incremental Manifest artifacts, or native library artifacts with SO hot update disabled
-> write them into the latest Gradle APK
-> re-sign with the project signing configuration, or with the project script when a custom sign script is enabled
-> install the updated APK
-> rebuild the deployment cache and device checkpoint
-> regenerate classes and overlays still waiting for delivery
-> complete the remaining incremental deployment for the current RunInstallation replaces the old process and overlay baseline. Jugg clears deployment file state that can no longer be reused and reorganizes the remaining data from the current compilation result. This lets Manifest or native library changes with SO hot update disabled take effect in the same Run as ordinary classes and resources.
When the current Run Configuration enables a custom APK install script, the project script performs the "install the updated APK" step for ordinary apps. Jugg still requires the script to install the APK supplied by the current run and rebuilds the deployment cache only after checksum verification passes. Android test APKs do not use this script.
Difference between APK update and Gradle fallback
Both paths install an APK, but they regenerate different scopes.
| Path | Reused content | Applicable scenario |
|---|---|---|
| Jugg APK update | The latest trusted Gradle APK and local files generated in the current Run | Deterministic write-back changes such as a Manifest patch or an existing native library with SO hot update disabled |
| Installation after a Gradle build | Reruns the build, packaging, and signing flow | Build scripts, dependencies, C/C++ compilation, ABI, or packaging results must be refreshed |
A reinstall triggered by recovery is also not a Gradle fallback. It usually installs the current existing APK to repair device state. Gradle is required only when the build baseline itself is untrusted.