Android и Лямбда

Мне нужно интегрировать некоторый код с широким использованием Java-лямбда-функций. Несколько ограничений, которые я требую от разработки моего проекта с использованием Eclipse Mars, с последним плагином ADT, а не с Android Studio.

Проблема заключается в том, что использование функций Lambda требует использования 1.8 JDK соответствия, но если установлено так, я получаю это сообщение:

Android requires compiler compliance level 5.0 or 6.0. Found '1.8' instead.

Как они могут жить вместе в гармонии?

Изменить: Это не дубликат предложенных вопросов, так как я спрашиваю об ADT Eclipse, и с момента последнего обновления в этом вопросе Android поддерживает Java 8, поэтому не только это не дубликат, но этот вопрос сейчас (после 1,5 года после последнего обновления) устарели.

Ответ 1

Обновление языковых функций Java 8 на Android

Lambda снова портирована на более старые версии Android.

Это функция из Android Gradle Plugin 3.0 и выше, лямбда перенесена на более старые версии ОС Android как часть других функций языка Java 8.

Добавьте это в ваши скрипты сборки Gradle, чтобы включить эту функцию.

android {
  compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  }
}

Дополнительные сведения см. В разделе " Использование функций языка Java 8" и "Поддержка Java 8 в Android".

Как сказал @dhke, поддержки Java 8 на Android пока нет.

Используйте Java 8, Build For Java 6/7

Но вы все равно можете использовать JDK 8 для разработки приложений для Android. Вам просто нужно установить совместимость источника на 6 или 7, в зависимости от вашего minSDKVersion. Таким образом, вы потеряете все новые функции, представленные в Java 8, такие как лямбда в вашем случае.

Backport of Lamda

Поскольку вы широко используете лямбду, Retrolambda может быть вариантом для вас. Он обеспечивает лямбда-бэкпорт для версий до Java 8. Он имеет плагин Maven/Gradle/командной строки, чтобы включить поддержку.

Другие Backports

Если вам нужны другие функции Java 8, AFAIK, ThreeTen ABP обеспечивает поддержку бэкпорта для Java 8 Date Time API.

Ответ 2

В настоящее время вы не можете (как минимум до Android 5.1.1) использовать лямбда-функции на Android.

Лямбда-функции требуют новых кодов операций Dalvik (не обязательно JVM!) (libate-variable, box-lambda, unbox-lambda, capture-variable, create-lambda, invoke-lambda), которые не поддерживаются ни Dalvik, ни ART.

Похоже, что в Google может быть запланировано (хотя пока ничего официально не известно) Поддержка Java 8 для сообщения 5.1.1 (API-уровень 23 и выше). По крайней мере smali disassembler уже добавили поддержку с отличной ссылкой на уровень API:

https://github.com/JesusFreke/smali/commit/144951a9e9e6c87866245f2bdeebf0ebedaa0e38:

Добавить новый -X/- экспериментальный флаг для [dis] собрать коды операций не в искусстве

  • Добавить новые opcodes освободить переменную, box-lambda, unbox-lambda, capture-variable, create-lambda, invoke-lambda
  • Добавить поддержку для кодирования инструкций 25x
  • Добавляет LambdaTest для проверки новых кодов операций сборки/дизассемблирования.

А также

https://github.com/JesusFreke/smali/commit/144951a9e9e6c87866245f2bdeebf0ebedaa0e38#diff-5d7892344c0b747d3667bf8623c690c5R66

options.apiLevel = 23;  // since we need at least level 23 for lambda opcodes

Это только указывает коды операций, а не необходимые изменения в библиотеке. Он также ничего не говорит нам о самом Android, поэтому я бы предложил не считать это официальным расписанием выпуска.

Ответ 3

Android поддерживает Java 8, поэтому не только это не дубликат

Как Android N превью освободить поддержку Android ограниченных функций Java 8 см. Java 8 Особенности языка

Чтобы начать использовать эти функции, вам необходимо загрузить и настроить Android Studio 2.1 и Android N Preview SDK, который включает в себя требуется Jack toolchain и обновленный Android-модуль для Gradle. если ты еще не установили SDK Android N Preview, см. Настройка для разработки для Android N.

Поддерживаемые Java 8 Language Features и API

Android в настоящее время не поддерживает все функции языка Java 8. Однако при разработке приложений теперь доступны следующие функции для просмотра Android N:

По умолчанию и статические методы интерфейса

Лямбда-выражения

Повторяющиеся аннотации

Есть некоторые дополнительные функции Java 8, поддерживаемые Android, вы можете увидеть полную информацию из Java 8 Language Features

Ответ 4

Я не думаю, что это сработает.

Чтобы использовать lambdas, вам необходим уровень совместимости с исходным кодом 1.8. Для того, чтобы компилятор DEX работал, вам нужна целевая совместимость 1.7. Eclipse не позволит вам установить целевую совместимость ниже исходной совместимости (рисунок ниже).

Обратите внимание, что это не связано с привычкой IntelliJ думать, что он знает лучше, чем вы, каким должен выглядеть ваш код. Он может показать вам лямбда, даже если фактический код является анонимным классом.

введите описание изображения здесь

Ответ 5

UPDATE: через несколько дней Android Studio 3.0 находится на стабильном уровне. Он официально поддерживает подмножество функций Java 8, лямбда-выражения среди них.

В соответствии с этой учетной записью разработчиков Android от 14 марта 2017 года google

решил добавить поддержку функций языка Java 8 непосредственно в текущий набор инструментов javac и dx и отказаться от инструментальной привязки Jack. В этом новом направлении существующие инструменты и плагины, зависящие от формата файла классов Java, должны продолжать работать. Двигаясь вперед, функции языка Java 8 будут поддерживаться системой Android. Мы собираемся запустить это как часть Android Studio в ближайшие недели, и мы хотели бы поделиться этим решением с вами на ранней стадии.

Таким образом, нам, вероятно, не придется ждать намного дольше для Java 8 в Android Studio.

Ответ 6

Обратный синтаксис лямбда

Насколько я знаю, все, что сделано в новом синтаксисе Java 8 Lambda, может быть выполнено с использованием кода старой школы Java, такого как анонимный внутренний класс. (Учебное пособие по Oracel) (Быстрый старт Oracle)

Чтобы облегчить перенос синтаксиса Lambda, некоторые IDE, такие как NetBeans, могут предложить автоматическую пересмотр кода в любом направлении/из синтаксиса лямбда. С одним щелчком подтверждения синтаксис автоматически меняет магию. См. Документ NetBeans на Использование поддержки выражений Lambda.

Вот скриншот NetBeans, предлагающего превратить кнопки Vaadin Button.ClickListener от синтаксиса Lambda до анонимного внутреннего класса. Обратите внимание на указатель мыши, нажимая на значок лампочки в строке # 107.

снимок экрана NetBeans, предлагающий переключить синтаксис Lambda на анонимный внутренний класс

Чтобы включить эту функцию в среде IDE, вам необходимо временно включить Java 8 в свой проект. После отмены всего синтаксиса Lambda переключите проект обратно на Java 6/7. В NetBeans способ включить Java 8 находится в вашем проекте > Properties > Sources > Source/Binary Format (popup menu) > 1.8.