This question already has answers here:
Is it possible to use Java 8 for Android development?
(28 answers)
Closed 7 years ago.
Is there any issues with using Java 1.8 for an android project targetting API 14 and above? I can't find any documentation on this and would like to use Optionals.
Edit: Mainly focused on optionals (not duplicate).
for Optionals only you can also use guava - if you want other features you might want to have a look at retro-lambda
Also think twice about Optional - try to do it at compile-time as much as possible with Annotations like #Nullable #NonNull - same effect - more speed
As far as I know you can't do this. Android works with a subset of the Java APIs and with the Java language as-of Java 1.5 (from memory). So Optional won't be available in the APIs included in Android and 1.8 language features (lambdas, etc) are not available to you when targetting Android as a platform.
You might be able to compile to Java 1.5 (language level) using the 1.8 compiler; but then you may as well just use Java 1.5. (Keeping in mind that you still need to run you project through all the Android SDK steps need to deploy it on Dalvik: you can't just build a .jar as you would a regular Java app.)
This has been my experience - though I am not a full-time Android developer.
Not as far as I know.
You can use retrolambda project to use lambda expressions, but I don't know any project that back ported Optional's
Related
I'm going to install Android Studio 3 in order to develop an Android application.
I'd like to know if it is possible to use Java 9 for Android development? If so, does it support all of the Java 9 features?
As far as I know, the IDE itself supports Java 9. This means you can write a Java 9 desktop program, or run the IDE with JDK 9.
However, Android itself does not support Java 9 (yet). You can still download JDK 9, although I have seen some questions on problems related to Android Studio and Java 9. Personally, I have Java 9 and Android Studio runs without problems.
The Android SDK is the development kit you'll be dealing with, and with source compatibility you'll get language features similar to Java 6, 7, or 8, depending on your settings. So you can download JDK 9 and use that most likely without issues, but you can't use any of the language features in any Android apps.
As for differences between the JDK and the Android SDK, you should read this. Android currently supports a subset of Java 8 features, but not everything. It might never support everything, or leave out some parts of Java 8, even if it later supports some parts on Java 9 or higher.
UPDATE: as of https://jakewharton.com/androids-java-8-support/, it seems like this should almost work by now (as well as for Java 9, 10, 11, and 12). Or just use Kotlin.
To help the last steps along, you can star the issue.
As of now, the Android SDK does not even support java 8 completely:
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. This page describes the Java 8 language features you can use, how to properly configure your project to use them, and any known issues you may encounter. [emphases mine]
That probably needs to be supported completely before Java 9 is approached.
Just tried to do it with Ubuntu 18.04 which uses Java 10 already. You run into tons of problems from invalid java certificates to extra warnings on gradle invocations etc. It's a mess and hopefully solved soon, you will find solutions to every problem via google but it's more easy to install Java 8 instead.
I have no idea about using the language itself inside Android application code, because i'm a full NDK C++ programmer and only use the toolchain which contains many java programs.
I need to integrate some code with extensive usage of Java lambda functions.
Several restrictions I have demand that I develop my project using Eclipse Mars, with the latest ADT plugin, and not Android Studio.
The problem is that using Lambda functions demands using 1.8 JDK compliance, but if set so, I get this message:
Android requires compiler compliance level 5.0 or 6.0. Found '1.8' instead.
How can the two live together in harmony?
Edit:
This is not a a duplicate of the questions suggested, as I'm asking about ADT Eclipse, and since the last update in that question, Android does support Java 8, so no only is this not a duplicate, but that question is now (after 1.5 yrs after the last update) obsolete.
Update on Java 8 language features on Android
Lambda is back ported to older versions of Android.
This is a feature from Android Gradle Plugin 3.0 and above, lambda is back ported to older Android OS versions as part of other Java 8 language features.
Add this to your Gradle build scripts to enable the feature.
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
For more details, see Use Java 8 language features, and Android' Java 8 support.
As #dhke said, there's no support for Java 8 on Android yet.
Use Java 8, Build For Java 6/7
But you can still use JDK 8 to develop Android application. You just need to set source compatibility to either 6 or 7 depends on your minSDKVersion. Thus, you would lose any new features introduced in Java 8, like lambda in your case.
Backport of Lamda
Since you have extensive usage of lambda, Retrolambda might be an option for you. It provides backport of lambda for pre-Java 8 versions. It has Maven/Gradle/command line plugin to enable the support.
Other Backports
If you need other Java 8 features, AFAIK, ThreeTen ABP provides backport support for Java 8 Date Time API.
You cannot currently (as up to at least Android 5.1.1) use lambda functions on Android.
Lambda functions require new Dalvik (not necessarily JVM!) opcodes (liberate-variable, box-lambda, unbox-lambda, capture-variable, create-lambda, invoke-lambda) that neither Dalvik nor ART currently have support for.
It looks like google might have scheduled (though nothing seems to be official yet) Java 8 support for post 5.1.1 (API Level 23 and later). At least the smali disassembler already added support with a distinct reference to the API level:
https://github.com/JesusFreke/smali/commit/144951a9e9e6c87866245f2bdeebf0ebedaa0e38:
Add new -X/--experimental flag to [dis]assemble opcodes not in art yet
Add new opcodes liberate-variable, box-lambda, unbox-lambda, capture-variable, create-lambda, invoke-lambda
Add support for encoding 25x instructions
Adds LambdaTest to check new opcodes assemble/disassemble properly
And also
https://github.com/JesusFreke/smali/commit/144951a9e9e6c87866245f2bdeebf0ebedaa0e38#diff-5d7892344c0b747d3667bf8623c690c5R66
options.apiLevel = 23; // since we need at least level 23 for lambda opcodes
This only marks the opcodes, not the necessary library changes. It also does not tell us anything about Android itself, so I'd suggest not to take this as an official release schedule.
Android does support Java 8, so no only is this not a duplicate
As of Android N preview release Android support limited features of Java 8 see Java 8 Language Features
To start using these features, you need to download and set up Android
Studio 2.1 and the Android N Preview SDK, which includes the
required Jack toolchain and updated Android Plugin for Gradle. If you
haven't yet installed the Android N Preview SDK, see Set Up to Develop
for Android N.
Supported Java 8 Language Features and APIs
Android does not currently support all Java 8 language features.
However, the following features are now available when developing apps
targeting the Android N Preview:
Default and static interface methods
Lambda expressions
Repeatable annotations
There are some additional Java 8 features which Android support, you can see complete detail from Java 8 Language Features
I don't think this is going to work.
In order to use lambdas, you need source compatibility level 1.8. In order for the DEX compiler to work you need target compatibility 1.7. Eclipse is not going to let you set the target compatibility below the source compatibility (picture below).
Note that this is unrelated to IntelliJ's habit of thinking it knows way better than you do, what your code should look like. It can show you a lambda, even when the actual code is an anonymous class.
UPDATE: Since a few days, Android Studio 3.0 is out on stable. It officially supports a subset of Java 8 features, lambda expressions among them.
According to this Android Developers Blogpost from March 14th, 2017, google
decided to add support for Java 8 language features directly into the current javac and dx set of tools, and deprecate the Jack toolchain. With this new direction, existing tools and plugins dependent on the Java class file format should continue to work. Moving forward, Java 8 language features will be natively supported by the Android build system. We're aiming to launch this as part of Android Studio in the coming weeks, and we wanted to share this decision early with you.
So we probably won't have to wait much longer for Java 8 in Android Studio.
Reverse The Lambda Syntax
As far as I know, everything done in the new Java 8 Lambda syntax can be done using old-school Java code such as anonymous inner class. (Oracel Tutorial) (Oracle Quick Start)
To ease the burden of undoing the Lambda syntax, some IDEs such as NetBeans can suggest automatic revision of code in either direction to/from Lambda syntax. With one-click of approval, the syntax is auto-magically swapped. See the NetBeans document on Using Lambda Expressions Support.
Here is a screenshot of NetBeans offering to turn a Vaadin button’s Button.ClickListener from Lambda syntax to an anonymous inner class. Notice the mouse pointer clicking on the light bulb icon on line # 107.
To enable this feature in your IDE, you will need to enable Java 8 in your project temporarily. After undoing all the Lambda syntax, switch your project back to Java 6/7. In NetBeans the way to enable Java 8 is in your project > Properties > Sources > Source/Binary Format (popup menu) > 1.8.
Since the release of Java 8, I found myself slowly becoming dependent on Java 8-specific features (ex. lambda statements) on a library project that I have just started.
I have seen many other projects which, to this day, still build against Java 7, or even Java 6, causing me to second-guess myself.
Is it a good idea to immediately start building against the newest version of Java, or should I still use older versions?
Note that unlike those other projects that have started back when Java 6/7 was the newest version, mine was started recently when Java 8 is the newest.
There are two reasons I can think of that would require staying with a pre-Java 8 JVM:
You are writing a library that is being used by a large group of people outside your organization who are still stuck on a pre-Java 8 JVM. If you use the latest and greatest JVM, they won't be able to use your product anymore.
You are dependent on a 3rd party library that has not upgraded to Java 8 and breaks on Java 8.
Since you mentioned this is a new project, #1 is unlikely. Even if you plan on having external users, if it's a new project, requiring the latest version of the JVM isn't really an issue.
Number 2 is also getting more and more unlikely as the more popular 3rd party libraries have released updates to work on Java 8. Even the few stragglers are usually OK working on Java 8. For example I use an ancient version of hibernate with Java 8. I just don't use any Java 8 features in any mapped fields/entities.
Java 8 denotes a major change to the language since Java 5 (or perhaps its inception). If you are targeting specifically the changed language parts (which I guess you claim) then making it usable only by Java 8+ runtime makes sense.
When Java 5 occurred 10 years ago and you wanted to use all the new features introduced at the time (e.g. foreach statement, Enums etc.) into your own library development, what would you have done? I believe you would have made your library require Java 5 at the minimum. If you agree with that, then that (sound) logic applies consistently to your present situation as well.
For server side application, possibly a version or two prior to the current version as suggested by EJP.
On the client side however, I don't see any point in trying to support older Java versions. The JRE has been auto-updating since at least Java 6. It has gotten to the point where Java Web Start launched applications cannot specify an earlier than current JRE. Or rather, it can specify any JRE it chooses in the launch file, but that will be ignored in favor of the latest version installed on the user's computer.
I was wondering if I can use default methods in interfaces in Android development.
The feature is included in Java 8, but I have found out that Android Java VM doesn't yet support it.
It there any way to use default methods in Android development? If not, when this feature will be available, is there some kind of timeline for this features?
On the availability: I think we'll see default methods in Android N. There are already a lot of tests related to default methods for the new Jack compiler on AOSP. See http://bit.ly/1PZoV1A
And today the java.util.function package has been merged into the ojluni master (including default methods and the use of lambdas).
Edit: Here is the official confirmation that Android N is going to support Java 8: http://developer.android.com/preview/j8-jack.html
Streams are still missing but java.util.Spliterator(s) has been integrated yesterday. Given the current pace, I'd expect we'll see the Stream API in May.
Possible duplicate : will android java support lambda expression in java 8?
In the possible duplicate question, kapep answered this (read the full answer for more details) :
Android doesn't use Oracle's Java SE versions, it's based on parts of the Apache Harmony project so it doesn't even support Java 7. Harmony is not actively developed any more and won't support 1.7.
So I think you can forget new features of Oracle Java version for Android development and follow the Android API (not the Oracle one).
Most of us have heard by now of the cool features Java 8 will bring, but Android will not support it. This is because of Google using Apache Harmony for Android. This is what is keeping us (the android app developers) from improving our code with lambdas, default implementations in interfaces, switching on a String and a lot more. Surely, we will handle for some time, but what if some libraries we use in our apps start to use Java 8 features? As far as I know, this will not work (please correct me if wrong). This creates incompatibility between Standard-Java and Android-Java. It cannot be what Google intends, or at least I can't think of a reason why a company, developing a widely adopted operating system, would wan't to permanently stay with an old Java version.
Questions:
Why do they use Apache Harmony?
Why can't they adopt a newer version of java?
If they don't want Oracle's Java, why can't they use a subset of OpenJDK (licensing noob here)?
Do you know of any plans to update the used Java version?
Do you know of any way to use Java 8 classes on current Android systems?
Why do they use Apache Harmony?
Because Sun refused to provide Google with a license for Sun (now Oracle) Java under terms that were acceptable. Google and Sun negotiated, but they ended up walking away from the deal.
Nitpick: in fact, the Android libraries are not Apache Harmony. They started out as based on Harmony, but the two codebases have diverged. Furthermore, the Apache Harmony project was officially "retired" in November 2011.
Why can't they adopt a newer version of java?
Firstly, Android does not run Java(tm). It runs a language that is identical to Java with a class library that is functionally equivalent to a subset of the Java class library (+ Android-specific libraries), on a virtual machine with a different instruction set.
From a technical pespective, they could ... but only if they put in a lot of work into implementing Java 7 and Java 8 language features, library features, etc, for the Android platform.
UPDATE - As of Android 19 (KitKat) and Eclipse ADT 22.6, Android does now support the Java 7 language extensions; see http://tools.android.com/recent/eclipseadt226preview
If they don't want Oracle's Java, why can't they use a subset of OpenJDK?
I don't think that switching to OpenJDK would change anything. Oracle Java and OpenJDK are 99.9% the same.
Anyway, there may be licensing and related legal issues. (And to get a feel for that, read up on the Oracle vs Google lawsuit ... that is going to appeal.)
More likely, Google doesn't see enough commercial value to counteract the (massive) effort it would take to change, and the disruption it would cause to the Android ecosystem ... which already suffers from problems with fragmentation.
Do you know of any plans to update the used Java version?
No I don't. It doesn't mean that there aren't plans, but if there are, they are not public.
Do you know of any way to use Java 8 classes on current Android systems?
You could port them. Or at least, you could try to port them. (Some Java APIs have an intimate relationship with the native code side of the JVM ... and that could make porting problematic.)
Do you know of any way to use Java 8 classes on current Android systems?
There are a few libraries which backport parts of Java 8 API (see the update section below for native support of these APIs in the latest Android versions):
ThreeTenABP backport of Java 8 date and time API optimised for Android
Stream support is a backport of the Java 8 java.util.function (functional interfaces) and java.util.stream (streams) API for users of Java 6 or 7 supplemented with selected additions from java.util.concurrent which didn't exist back in Java 6.
And you can use retrolambda (along with gradle-retrolambda plugin) to utilize lambdas in Android development.
UPDATE
Android Studio 3.0 started to provide built-in support for some of Java 8 language features, which are:
Lambda expressions
Method references
Type Annotations (information is available at compile time, but not at runtime)
Repeating annotations
Default and static interface methods
Also starting from API level 24 the following Java 8 API are available:
java.util.stream
java.util.function
java.lang.FunctionalInterface
java.lang.annotation.Repeatable
java.lang.reflect.AnnotatedElement.getAnnotationsByType(Class)
java.lang.reflect.Method.isDefault()
API level 26 (Android O) added java.time API support.
UPDATE 2020/01/17
Android Studio 4.0 includes support for using a number of Java 8 language APIs, by using technique called desugaring, without requiring a minimum API level for your app:
https://developer.android.com/studio/preview/features#j8-desugar
The following set of APIs is supported in this release:
Sequential streams (java.util.stream)
A subset of java.time
java.util.function
Recent additions to java.util.{Map,Collection,Comparator}
Optionals (java.util.Optional, java.util.OptionalInt and java.util.OptionalDouble) and some other new classes useful with the
above APIs
Some additions to java.util.concurrent.atomic (new methods on AtomicInteger, AtomicLong and AtomicReference)
ConcurrentHashMap (with bug fixes for Android 5.0)
To support these language APIs, D8 compiles a separate library DEX
file that contains an implementation of the missing APIs and includes
it in your app. The desugaring process rewrites your app’s code to
instead use this library at runtime.
To enable support for these language APIs, include the following in
your module’s build.gradle file:
android {
defaultConfig {
// Required when setting minSdkVersion to 20 or lower
multiDexEnabled true
}
compileOptions {
// Flag to enable support for the new language APIs
coreLibraryDesugaringEnabled true
// Sets Java compatibility to Java 8
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.4'
}
More technical details on how desugaring is implemented, can be found in Jake Wharton's articles:
Android's Java 8 Support
Android's Java 9, 10, 11, and 12 Support
D8 Library Desugaring
Update.
Android is planning to use the OpenJDK. Possibly because they are thinking like you and wants to use the Java 8 features. See this