I am quite familiar with the common the settings found in build.gradle
minSdkVersion 21
- means that the Android device needs to at least have Android API level 21 or greater to install my app
(this should be as low as possible, so to reach the maximum number of users while preserving all mission critical app functionality)
targetSdkVersion 26
- means that my app was "designed" for this version of the Android API, so that the device knows whether or not to run in compatibility mode, etc.
(this should be as high as possible, and for developers to update along with any deprecated API calls)
But what about sourceCompatibility
and targetCompatibility
that specify the JDK version to use? I seem to be getting conflicting messages.
For example, when I look into my project structure settings in Android studio, I seem to be getting recommendations of using the default JDK that comes with Android Studio - version 1.8
.
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?
I seem to get the message that Android mostly runs on version 1.7
and only supports a small subset of version 1.8
- suggesting that version 1.7
is the logical choice instead.
Question 1)
Which version should I use for maximum compatibility with new and old Android devices? version 1.7
or version 1.8
? (Does this even matter? Refer to question #2)
Question 2)
Is sourceCompatibility
and targetCompatibility
(and JDK version) something that is only used during compilation from .java
files to .class
files? So after the java byte code is generated, whatever version (version 1.7
vs version 1.8
) won't matter anymore - since the byte code will be the same & interoperable regardless.
Or is this something that will persist all the way up to the end user (e.g. if their Android phone's JVM doesn't know how to read version 1.8
byte code, it will just blow up)
Question 3)
What happens if I set minSdkVersion
to something very low (e.g. 10
) while setting sourceCompatibility
and targetCompatibility
to something very high (e.g. version 1.8
)?
Can I blindly rely on Android Studio to catch all possible incompatibilities? As in, if it successfully builds an APK, I am guaranteed it will work?
Or will it still build and let users with API >= 10
install it, but will just blow up on runtime if the users device JVM can't run 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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With