1# Incremental Install 2 3Incremental Install is a way of building & deploying an APK that tries to 4minimize the time it takes to make a change and see that change running on 5device. They work best with `is_component_build=true`, and do *not* require a 6rooted device. 7 8## Building 9 10Add the gn arg: 11 12 incremental_install = true 13 14This causes all apks to be built as incremental except for denylisted ones. 15 16## Running 17 18It is not enough to `adb install` them. You must use the generated wrapper 19script: 20 21 out/Debug/bin/your_apk run 22 out/Debug/bin/run_chrome_public_test_apk # Automatically sets --fast-local-dev 23 24# How it Works 25 26## Overview 27 28The basic idea is to sideload .dex and .so files to `/data/local/tmp` rather 29than bundling them in the .apk. Then, when making a change, only the changed 30.dex / .so needs to be pushed to the device. 31 32Faster Builds: 33 34 * No `final_dex` step (where all .dex files are merged into one) 35 * No need to rebuild .apk for code-only changes (but required for resources) 36 * Apks sign faster because they are smaller. 37 38Faster Installs: 39 40 * The .apk is smaller, and so faster to verify. 41 * No need to run `adb install` for code-only changes. 42 * Only changed .so / .dex files are pushed. MD5s of existing on-device files 43 are cached on host computer. 44 45Slower Initial Runs: 46 47 * The first time you run an incremental .apk, the `DexOpt` needs to run on all 48 .dex files. This step is normally done during `adb install`, but is done on 49 start-up for incremental apks. 50 * DexOpt results are cached, so subsequent runs are faster. 51 * The slowdown varies significantly based on the Android version. Android O+ 52 has almost no visible slow-down. 53 54Caveats: 55 * Isolated processes (on L+) are incompatible with incremental install. As a 56 work-around, isolated processes are disabled when building incremental apks. 57 * Android resources, assets, and `loadable_modules` are not sideloaded (they 58 remain in the apk), so builds & installs that modify any of these are not as 59 fast as those that modify only .java / .cc. 60 * Since files are sideloaded to `/data/local/tmp`, you need to use the wrapper 61 scripts to uninstall them fully. E.g.: 62 ```shell 63 out/Default/bin/chrome_public_apk uninstall 64 ``` 65 * `AppComponentFactory.instantiateClassLoader()` is not supported. 66 67## The Code 68 69All incremental apks have the same classes.dex, which is built from: 70 71 //build/android/incremental_install:bootstrap_java 72 73They also have a transformed `AndroidManifest.xml`, which overrides the the 74main application class and any instrumentation classes so that they instead 75point to `BootstrapApplication`. This is built by: 76 77 //build/android/incremental_install/generate_android_manifest.py 78 79Wrapper scripts and install logic is contained in: 80 81 //build/android/incremental_install/create_install_script.py 82 //build/android/incremental_install/installer.py 83 84Finally, GN logic for incremental apks is sprinkled throughout. 85