

Google supports Java 7 features on Android - yareally
http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Using-sourceCompatibility-1.7

======
yareally
Officially relying on "try with resources" for Android 4.3 and before can be
hit or miss, depending whether the OEM added it to the build for the device or
not, so just a fair warning.

A way to overcome the issue with "try with resources" is to add the missing
JDK7 source files[1] yourself to your build and enable "\--core-libraries"
found under settings → Compiler → Android Compilers in Intellij IDEA 13 and
Android Studio. The "\--core-libraries" option allows your app to use any
system libraries you may include instead of those on the device. It's a dex
compiler option that's been around for a while, but was much more painful to
enable prior to a recent update to IDEA 13.

[1] From the Android SDK v19 sources, take java.lang.AutoCloseable,
java.lang.Throwable and any of the Stream Classes you wish to use that
implement AutoCloseable (such as java.io.BufferedInputStream)

Edit: Forgot to mention the stream classes that implement AutoCloseable are
also required for the 4.3 and before to use the workaround.

~~~
lxgr
Statically including system libraries with an application just to be able to
use a convenience feature of a language seems pretty dangerous. What if Google
finds and fixes a bug in one of those classes in an Android version update?

~~~
yareally
Since it could set it up so you're only overriding system files for Android
versions older than 4.4. Any bug fixes, would be part of the system core are
only going to be in updated with Android 4.4+, which is not using the
backported classes. If doing that, don't see it ever being an issue.

This is a little rough and there may be a better way, as it's 7am here right
now and looking at the SDK source is not something I want to do at this hour,
but something like this should work, making your own "Android support
library":

1) Use multiple dex files[1] in an apk and dynamically load the backported
library files based on whether the app is using 4.3 and before or 4.4+.

or

2) Mess around with the source files, which is much more ugly:

\- Change Throwable to your app package domain, leaving the class name the
same. This will likely require changing some other exception classes to do the
same as well.

\- Leave Closable and AutoCloseable in the system package domain within your
app, as each is just a one method interface and will make things more
complicated if you move them, but they could also be changed if refactored in
the backported stream files.

\- Change the backported AutoClosing streams to your app package domain. Make
a wrapper for each to check if you're on 4.3 and before and call to your
modded stream backported files or 4.4+ and call to the system ones. The key
would be ensuring it uses the proper Throwable class, since that is where
things happen.

\- Add to the Streams some conditions to check if the app is installed on
Android 4.4+ and use the system classes with the OS or 4.3 and use your
backported classes.

[1] [http://android-developers.blogspot.com/2011/07/custom-
class-...](http://android-developers.blogspot.com/2011/07/custom-class-
loading-in-dalvik.html)

Edit: Remembered you could load a library from a separate dex file and
dynamically load it.

~~~
clhodapp
> Since it could set it up so you're only overriding system files for Android
> versions older than 4.4...

I note that, to do this, you would have to publish (at least) two APKs using
the multiple APK mechanism
([http://developer.android.com/google/play/publishing/multiple...](http://developer.android.com/google/play/publishing/multiple-
apks.html)), which seems like quite a hassle.

~~~
yareally
I revised my post to be more clear about how it would be done so no need for
that I don't think if minimizing what one is directly overriding in the system
classes.

EDIT: I forgot that multiple dex files can be included in an apk[1] as well
and dynamically loaded. That may be the most elegant solution. To just package
it as as separate dex file and dynamically load it if on Android 4.3 or older.

[1] [http://android-developers.blogspot.com/2011/07/custom-
class-...](http://android-developers.blogspot.com/2011/07/custom-class-
loading-in-dalvik.html)

------
lxgr
That's interesting. As far as I remember, it's not possible to use any Java 7
language features while compiling to class files compatible with the 1.6 JRE
with "regular" Java. (See e.g.
[http://stackoverflow.com/questions/17168184/java-7-language-...](http://stackoverflow.com/questions/17168184/java-7-language-
backwards-compatibility))

~~~
lnanek2
The title of the section is using Java 7 source compatibility, so I don't
think it is about compiling to be compatible with 1.6, it's compiling to be
compatible with 7. Realistically, Android code doesn't get run on a JVM
anyway, so the whole thing is kind of silly. If their translation to DEX byte
code supports only 1.6 class files, then it supports only 1.6, but clearly it
supports 7 now.

~~~
eropple
Try-with-resources requires library compatibility. All other Java 7 features
can be expressed using Java 6 bytecode structures, so it doesn't surprise me
that they're allowing them in pre-KitKat projects.

------
clhodapp
But does it actually support invokedynamic?

I saw that [https://android-
review.googlesource.com/#/c/58880/](https://android-
review.googlesource.com/#/c/58880/) was merged a while ago, but I'm not sure
if any other commits have improved things further.

~~~
yareally
Not sure yet, but I'll test and see at some point. I only stumbled on the
actual support evidence shortly before submitting the link to HN.

~~~
clhodapp
If you plan to check, I won't bother (I had also planned to investigate
later). You should also check on MethodHandles, since (as of the commit I
linked) their parser also threw exceptions when it came across them.

If these things don't work, I'm very disappointed in the Android team, as this
would be totally fake v51 classfile support.

~~~
yareally
Tried a small invoke example, there seems to be no java.lang.invoke.* package
in Android API 19 and also no MethodHandle class.

