Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does sourceCompatibility and targetCompatibility impact number of supported devices?

Tags:

What I know

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)

What I am confused about

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.

enter image description here

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.

Summary

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?

like image 971
AlanSTACK Avatar asked Sep 25 '18 07:09

AlanSTACK


1 Answers

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)

like image 197
Martin Algesten Avatar answered Nov 07 '22 18:11

Martin Algesten