Relationship between OS version, API Level, and Ja

2019-01-26 13:13发布

问题:

I know there are a lot of questions on here about Android API Level and Version but this question is different so please don't mark it as a duplicate.

I am wondering how Java version 1.6, 1.7, 1.8... relates to those two. The source of my confusion is me trying to use the Pattern.compile method with the Pattern.UNICODE_CHARACTER_CLASS flag as seen below.

Pattern pattern = Pattern.compile("\\b" + keywordToCheck + "\\b", Pattern.UNICODE_CHARACTER_CLASS);

From the docs on Pattern.UNICODE_CHARACTER_CLASS it says that it says Since: 1.7, which I assume to mean it is available in Java version 1.7 and above. I am trying to use that line of code in an Android project but every time I run it on my device I get:

java.lang.IllegalArgumentException: Unsupported flags: 256

Below are the relevant parts of my build.gradle file

defaultConfig {
        minSdkVersion 19
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }

From my understanding this means my app will use any API level 19 and above, which means it can run on Android 4.4 (KitKat) or higher. The device I'm running the app on has Android 6.0. How does the Java version fit into this? I am using Android Studio 3.0 which says I'm using:

Android Studio 3.0
Build #AI-171.4408382, built on October 20, 2017
JRE: 1.8.0_152-release-915-b08 x86_64
JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
Mac OS X 10.12.6

Can someone explain to me why I'm getting this error, and also the relationship between Android API Level, Version, and Java version? Thank you

回答1:

In the case of your given example, that flag wasn't added until API 24. In a lot of cases, even though support for a given language level (e.g. 7) was added earlier doesn't mean everything is added instantly. Some things are waited with for whatever reason Google has for waiting with it.

I can't tell you why because I don't know.

And as Gabe mentioned, the versions of Java isn't necessarily compatible with Android.

So because of your code where you use the flag on API 19 and up, you'll get a crash on versions between and equal to 19 and 23 because the flag isn't added yet.

And it's also worth noting that version compatibility doesn't limit versions of Java by versions of Android. Now you can for an instance run Java 8 on whatever version of Android you want. This is compatibility.

However. If you read Android Java 8 Language Features, it says (emphasis mine):

Android Studio 3.0 and later supports all Java 7 language features and a subset of Java 8 language features that vary by platform version.

I'm using Java 8 as the example here, but this applies to mostly every version of Android and java.

Essentially:

  • The flag you're using wasn't added until API 24. AFAIK, usage wasn't added even though the hard-coded variable is there
  • Android doesn't necessarily have every single Java API, and these vary by versions of Android
  • Versions of Java isn't limited by API, but the accessible features vary. Meaning you can run Java 8 on API (random number) 12 if you wanted to.

There's no fixed relationship (Android [x] = Java[x]) between the two. Different fields/methods/classes may be added eventually, instantly (on release of support for a given version of java) or not at all.


The regular Java and the version of Java used in Android are two very different ones, because Android is platform-based while Java is version-based. You can't compare versions between them, and they both have separate documentations.

It's worth noting that for Android (Java) questions you should look at the Android docs which can be found in the API reference instead of using the Oracle documentation which doesn't apply to Android because of the massive differences in the API.



回答2:

When it says available since 1.7, notice who's docs you're looking at- the Oracle (official Java docs). So it will always be Java version. Android documentation will always give you the Android SDK version its available since.

Note that Android is not always 100% compatible with Java's official versions. It tries to be, but obviously large chunks of the library just aren't there. When in doubt look at the Android documentation of the class, not the Oracle.

As for Java versions- they're independent from Android versions, mostly. Java 8 was just made officially fully supported with AS3. Before that it was deemed experimental. You can still use Java 7 if you want. For Java 8, most language features are available on all platforms, but one or two require a minimum SDK version of 24. The two I know of like that are Java streams and Annotation types/repeated annotations.

For your specific problem, note the android documentation says this about the flag: "This flag has no effect on Android, unicode character classes are always used." So you can just remove it.