minSdkVersion 21
- means that the device must have at least Android API level 21 or higher installed in order to install the app. (This value should be set as low as possible to help reach the largest number of users while still maintaining all critical app functionality.)
targetSdkVersion 26
- means that it was developed for the Android API version 26, allowing the device to determine if compatibility mode or optional features should be enabled. (This value should be set as high as possible to allow developers to access new features and manage any deprecated API calls.)
But what about the configurations sourceCompatibility
and targetCompatibility
? I have been receiving conflicting information about which JDK version should be used.
An example of this is seen in the project structure settings in Android Studio, where using the default JDK version that comes with Android Studio (version 1.8) is recommended by the tooltips.
However, when I read other online sources such as the following:
https://www.christopherprice.net/which-jdk-do-i-use-with-android-studio-3686.html
Which JDK version (Language Level) is required for Android Studio?
It appears that Android primarily runs on Java version 1.7, with only limited support for some features of version 1.8. This suggests that using version 1.7 would be the more logical choice.
Question 1) Which JDK version, 1.7 or 1.8, should I choose for maximum compatibility with both new and old Android devices? Does this configuration even make a difference in terms of reachable market size?
Question 2) Is the choice of sourceCompatibility
and targetCompatibility
(and JDK version) only relevant during the compilation of .java files to .class files and have no effect once the Java bytecode is generated? Or does the chosen JDK version affect the end user's experience, for example if their device's JVM can't interpret version 1.8 bytecode, causing the app to crash during runtime?
Question 3) What are the consequences of setting minSdkVersion
to a low value (e.g. 10) and sourceCompatibility
and targetCompatibility
to a high value (e.g. 1.8)? Can I trust that Android Studio will detect all compatibility issues and if it builds an APK, it will function properly? Or can it still be built and installed on devices with API level >= 10, but crash at runtime if the device's JVM can't handle version 1.8?
The android toolchain does some extra steps before the code is run on your device:
.java
-> .class
-> .class (desugared)
-> .dex
This is described here: https://developer.android.com/studio/write/java8-support
The desugaring step is responsible for turning your modern bytecode into something that works on older VMs.
How backwards compatible the desugaring makes your code depends on the minSdkVersion
. If your project makes a combination of sourceCompatibility
/targetCompatibility
and minSdkVersion
that isn't possible, the compiler will tell you.
This also goes for byte code from 3rd party libraries. Errors look like this:
Error: Static interface methods are only supported starting with Android N (--min-api 24): okhttp3.Request
(this specific problem came from using 1.7 source compatibility with okhttp3 4.0.1 and went away by using target 1.8)