Basics
Applications that are entirely built from Java or Kotlin code, including all the libraries and SDKs they use, don't care about which of armv7a and armv8a a device supports. However, quite a few apps include "native code", or "machine code", usually compiled from C or C++ code using the Android Native Development Kit ("NDK").
A given piece of machine code is either 32-bit (armv7a) or 64-bit (armv8a).
Running native code
Applications that support both armv7a and armv8a have two sets of machine code included in their APK files:
- One set for armv7a
- One set for armv8a
Your armv7a device can happily run the code that's intended for it, and which it can understand and run. It can't understand armv8a code at all, and is unable to run it. Applications that only support armv8a thus can't be run, so Android prevents you from installing them.
Forthcoming Complexities
The ARMv9 architecture will start to appear in Android devices quite soon. The Qualcomm Snapdragon 8 Gen 1 was one of the first v9 chips announced, in November 2021. Most ARMv9 cores can't run armv7a code, because they don't implement that 32-bit instruction set (or any other). They can run armv8a code. This means that devices with ARMv9 processors:
- Can run apps that support armv7a and armv8a.
- Can run apps that only support armv8a.
- Can't run apps that only support armv7a.
It's a good thing that Google have been demanding that new and updated apps support 64-bit since August 2019.
Why is there any armv7a machine code in use?
Android has quite a long history, and when it started, neither armv7a nor armv8a had been created. So there's been a gradual process of upgrading native code to newer standards.
Someone starting on Android NDK work today would support armv7a and armv8a, or maybe only armv8a if they were only interested in newer, faster devices, or their app needed to use lots of memory.