• A day in the life of an Android apk (assuming a split bundle)

    From Maria Sophia@mariasophia@comprehension.com to comp.mobile.android on Wed Apr 8 16:36:45 2026
    From Newsgroup: comp.mobile.android

    A day in the life of an Android APK (assuming a split bundle)

    Baswed on a nicely detailed conversation with Jeff Layman in
    Newsgroups: comp.mobile.android
    Subject: PSA: Muntashirakon extracting vs Aurora exporting app bundles for archival reuse
    Date: Thu, 2 Apr 2026 01:35:08 -0400
    Message-ID: <10qkv6c$sn8$1@nnrp.usenet.blueworldhosting.com>

    I decided to try to describe how Android APKs work from start to finish.
    Please correct the errors that I inadvertently will have made in doing so.

    1. On Google Play servers (the repository)
    Google stores a giant "App Bundle" (.aab) which contains every
    possible variant of the app:
    a. Core logic (DEX bytecode)
    b. All CPU types (arm, arm64, x86)
    c. All screen densities (ldpi through xxxhdpi)
    d. All languages (en, fr, de, etc.)

    The .aab is never installed directly on any device.

    2. What Aurora or Google Play actually download
    The Aurora or Play Store client reports the phone's hardware and
    locale. (Aurora can spoof much of this, which affects the results.)

    Google then generates a custom set of APKs for that device only:
    a. base.apk (core logic, resources, manifest)
    b. split_config.arm64_v8a.apk (CPU architecture)
    c. split_config.xxhdpi.apk (screen density)
    d. split_config.en.apk (language)

    These are ordinary ZIP files with the .apk extension.

    3. How these APKs get installed when they are a split APK bundle
    The built-in Android installer only understands single APK files.
    If you tap one of the split APKs in a file manager, installation
    will fail because Android does not know about the other pieces.

    Google Play, Aurora, SAI, and Muntashirakon all use the official
    Android "Package Installer Session API". This API allows them to
    stream multiple APKs into a single install session so Android sees
    the entire bundle at once.

    ADB also uses this API when you unzip the .apks file and run:
    adb install-multiple base.apk split*.apk

    Only after Android receives *all* required split APKs does it accept
    the install and move the files into:
    /data/app/~~random_id/com.example.app-string/

    Only the APKs live in this directory. They remain intact because
    Android reads resources (icons, layouts, strings, etc.) directly
    from inside these ZIP files at runtime. These APKs remain intact
    forever, for as long as the app is installed.

    Modern Android (10+) does NOT store optimized code (odex/vdex/oat)
    here anymore. Instead, Android Runtime (ART) places that performance
    cache in hidden system-wide directories such as:
    /data/misc/profiles/cur/0/com.example.app/
    /data/misc/profiles/ref/com.example.app/
    /data/dalvik-cache/arm64/...

    Older Android (5-9) stored:
    oat/arm64/base.odex
    oat/arm64/base.vdex
    next to the APKs, but this no longer happens.

    So the APKs in /data/app/ are the permanent "source package".
    The optimized code lives elsewhere and is regenerated as needed.

    Note: On an unrooted phone, none of the archive apps can access the
    optimized code, so it never appears in any exported backup.

    4. SAI, Muntashirakon, or Aurora "archival" of the APK bundle
    Aurora exports the APKs it downloaded from its own cache.
    (This must be done fast, i.e., before the cache is cleared.)

    SAI and Muntashirakon copy the installed APKs from:
    /data/app/~~random_id/com.example.app-string/

    All of these tools package the split APKs into a single archive:
    com.example.app.apks (zip containing the split APKs)
    com.example.app.zip (same idea)

    Aurora and SAI allow you to place the output anywhere.
    Muntashirakon "Save APK" always puts the archive in:
    /internalstorage/AppManager/apks/
    where you have control of how Muntashirakon labels it:
    %label%_%version%_%version_code%.apk(s)
    but you will get one of two extensions depending on whether it is split:
    packagename.apk (if it is not a split bundle)
    packagename.apks (if it is a split bundle)

    Aurora outputs a .zip file containing the split APKs. It is not
    directly installable as-is, but it is functionally identical to an
    .apks file and can be imported into SAI or Muntashirakon. The APKs
    inside are unchanged. Aurora may add metadata files (installer.json,
    metadata.json, etc.) to the exported archive, but the APK files
    themselves are unchanged.

    None of these tools include the optimized code (odex/vdex/oat),
    because those files are stored in protected system locations.

    5. When the app is deleted, Android performs a full sweep:
    a. The APK "library" in /data/app/ is deleted.
    b. The optimized code in /data/dalvik-cache/ is wiped.
    c. The private data/cache in /data/data/ is erased.
    Without the APK, the app has no images or layouts; without the
    optimized .odex, it has no executable logic. Both must be present
    for the app to function.

    There is a major difference between "User Apps" and "System Apps."

    a. USER APPS: "Uninstall" means "Delete".
    Android wipes the APKs from /data/app/, the optimized .odex from
    the dalvik-cache, and the user data. The app is 100% removed.

    b. SYSTEM APPS: "Uninstall" usually just means "Uninstall Updates."
    The Package Manager deletes the updated APKs from /data/app/,
    but the original factory APK remains in the /system/ partition.
    Because /system/ is read-only, we cannot delete the factory app
    without root. It is simply disabled and hidden.

    c. ADB UNINSTALL: When we run "pm uninstall --user 0" to remove
    bloatware (like Chrome), we are not deleting the APK. We are
    telling the Package Manager to "forget" the app for our user
    profile. The APK remains in the system partition taking up space,
    but the app is dead, its data is wiped, and it will not run.

    This is why a Factory Reset brings back the "bloat".
    The source APKs were never actually gone; they were simply
    hidden from the user's view. They can even be re-installed by
    adb because they were always there.

    Summary:
    A. The APK files in Step 2 and Step 3 are identical.
    B. Step 4 may include extra metadata added by Aurora or SAI, but the
    APKs themselves are unchanged.
    C. The APK is always the real app package. The optimized code is a
    performance cache created after installation and stored elsewhere.
    --
    On Usenet, knowledge is meant to be passed along to others, not hoarded.
    --- Synchronet 3.21f-Linux NewsLink 1.2