Особенности языка Ява 7 с Андроидом
просто интересно, пробовал ли кто-нибудь использовать новые функции языка Java 7 с Android? Я знаю, что Android читает байт-код, который выплевывает Java, и превращает его в dex. Поэтому я предполагаю, что мой вопрос заключается в том, может ли он понять байт-код Java 7?
8 ответов:
если вы используете Android Studio, Java 7 язык должен быть включен автоматически без каких-либо исправлений. Для Try-with-resource требуется уровень API 19+, а материал NIO 2.0 отсутствует.
если вы не можете использовать функции Java 7, см. @Nuno ответ о том, как редактировать ваш
build.gradle
.ниже приводится только для исторического интереса.
небольшая часть Java 7, безусловно, может быть использована с Android (примечание: Я тестировал только на 4.1).
во-первых, вы не могли использовать ADT Eclipse, потому что это жестко что только компилятор Java 1.5 и 1.6 совместимы. Вы можете перекомпилировать ADT, но я считаю, что нет простого способа сделать это, кроме перекомпиляции всего Android вместе.
но вам не нужно использовать Eclipse. Например, Android Studio 0.3.2,IntelliJ IDEA CE и другие javac на основе IDEs поддерживает компиляцию в Android и вы можете установить соответствие даже до Java 8 с помощью:
- файл → структура проекта → модули → (выберите модуль на 2-й панели) → уровень языка → (выберите "7.0 - алмазы, ARM, multi-catch и т. д.")
это позволяет только Java 7 языковые особенности, и вы вряд ли можете извлечь выгоду из чего-либо, так как половина улучшения также исходит от библиотека. Вы можете использовать те функции, которые не зависят от библиотеки:
- Алмазный оператор (
<>
)- строка переключатель
- несколько-поймать (
catch (Exc1 | Exc2 e)
)- подчеркивание в числовых литералах (
1_234_567
)- двоичные литералы (
0b1110111
)и эти функции не могут быть использованы и все же:
- The
try
-С-resources заявление-потому что он требует несуществующий интерфейс " java.ленг.Автоклавируемый" (это можно использовать публично в 4.4+)- аннотация @SafeVarargs-потому что " java.ленг.SafeVarargs" не существует
... "пока" :) оказывается, что, хотя библиотека Android нацелена на 1.6, источник Android содержит интерфейсы, такие как AutoCloseable и традиционные интерфейсы, такие как выходит наследует от AutoCloseable (SafeVarargs действительно отсутствует, хотя.) Мы могли бы подтвердить его существование через отражение. Они скрыты просто потому, что Javadoc имеет
@hide
тег, который вызвал " android.jar " не включать их.уже есть как существующий вопроскак создать Android SDK со скрытыми и внутренними API-интерфейсами?о том, как вернуть эти методы. Вам просто нужно заменить существующий " android.jar " ссылка на текущую платформу с нашей индивидуальной, тогда многие из API Java 7 станут доступными (процедура аналогична той, что в Eclipse. Проверьте Структуру Проекта → SDKs.)
в дополнение к AutoCloseable, (только) следующий Java 7 библиотеке также обнаружено:
- исключение цепочки конструкторов в ConcurrentModificationException, LinkageError и AssertionError
- статический .compare () методы для примитивов: Boolean.compare (), Byte.сравнивать(), Короткий.сравнить(), характер.compare (), целое число.сравните (), долго.сравнение.)(
- валюты: .getAvailableCurrencies (),.getDisplayName() (а без .getNumericCode ())
- BitSet: .previousSetBit (),.previousClearBit (),.valueOf (),.toLongArray (),.toByteArray()
- коллекции: .emptyEnumeration (),.опорожнитель(), .emptyListIterator ()
- AutoCloseable
- Throwable: .addSuppressed (),.getSuppressed () и конструктор с 4 аргументами
- символ: .сравнение. ,)(isSurrogate (),.getName (),.highSurrogate (),.lowSurrogate (),.isBmpCodePoint () (но без .isAlphabetic () and .isIdeographic ())
- система: .lineSeparator() (без документов?)
- java.ленг.отражать.Модификатор: .classModifiers (),.constructorModifiers (),.fieldModifiers (),.interfaceModifiers (),.methodModifiers ()
- NetworkInterface: .getIndex (),.getByIndex()
- InetSocketAddress: .getHostString ()
- InetAddress: .getLoopbackAddress ()
- регистратор: .getGlobal()
- ConcurrentLinkedDeque
- AbstractQueuedSynchronizer: .hasQueuedPredecessors ()
- DeflaterOutputStream: 3 конструктора с "syncFlush".
- Deflater: .NO_FLUSH, .SYNC_FLUSH, .FULL_FLUSH, .deflate() с 4 аргументами
это в основном все. В частности, NIO 2.0 не существует, а массивы.asList все еще нет @SafeVarargs.
EDIT: в то время, когда это было написано, последним релизом был Android 9 и Eclipse Indigo. С тех пор все изменилось.
- практический ответ
Да, я пробовал. Но это не большой тест, поскольку совместимость была ограничена уровнем 6 без возможности (по крайней мере, не простой способ) действительно использовать java 7:
- сначала я установил JDK7 на машине, на которой не был установлен другой JDK-Eclipse и Android также не установлены:
- затем я установил новый Eclipse Indigo и проверил, что он действительно использует JDK 7 (Ну, поскольку это единственный, и поскольку это тот, который я выбрал, я был бы удивлен)
затем я установил последнюю версию Android SDK (EDIT: Honeycomb, API13, в то время как этот пост был написан). Он нашел мой JDK 7 и установлен правильно. То же самое для ADT.
но у меня был сюрприз при попытке скомпилировать и запустить приложение Hello Word для Android. Совместимость была установлена на Java 6 без возможности принудительно установить ее на Java 7:
- я попробовал с проектом не Android, обычным Java, и у меня было объяснение. Уровень совместимости, по-видимому, ограничен Eclipse (см. сообщение внизу следующего изображение):
так у меня было Привет, Мир работа, а также другие приложения, более сложные и с помощью
SQLite
,Listview
,Sensor
иCamera
, но это только доказывает, что обработка совместимости Java 7, кажется, хорошо сделано и работает с Android.Итак, кто-то пытался с добрым старым муравьем, чтобы обойти ограничение затмения, замеченное выше?
- Theroetical ответ
в любом случае, SDK предназначен для использования С Java 5 или 6, как объяснено здесь.
у нас может быть что-то работающее с Java 7, но это будет работать "случайно". Здание DEX может работать правильно или нет, и как только DEX построен, он может работать или нет. Это потому, что использование неквалифицированного JDK дает непредсказуемые результаты по определению.
даже если кто-то успешно построил приложение для Android под простой Java 7, это не квалифицирует JDK. Тот же самый процесс, примененный к другому приложению, может завершиться неудачей, или у полученного приложения могут быть ошибки, связанные с использованием этого JDK. Не рекомендуемый.
для тех, кто участвует в разработке webapps, это точно так же, как развертывание веб-приложения, построенного под Java 5 или 6 под сервером приложений, квалифицированным только для Java 4 (например, Weblogic 8). Это может работать, но это не то, что может быть рекомендовано для других цели, чем пытаться.
цитата из dalvikvm.com:
dx, включенный в Android SDK, преобразует файлы классов Java классов Java, скомпилированных обычным компилятором Java, в другой формат файла класса (the .формат dex)
Это означает, что .исходный файл Java не имеет значения, это только .байт-код класса.
насколько я знаю, только invokedynamic был добавлен в байт-код JVM в Java 7, остальное совместимо с Java 6. ява сам язык не использует invokedynamic. Другие новые функции, такие как switch заявление строкаs или мульти -лови являются просто синтаксическим сахаром и не требуют изменения байтового кода. Например, мульти-лови просто копирует лови-блок для каждого возможного исключения.
единственная проблема должна быть в том, что новые классы, введенные в Java 7, отсутствуют в Android, например AutoCloseable, поэтому я не уверен, что вы можете использовать попробовать-функция с ресурсами (кто-то пробовал?).
какие-нибудь комментарии по этому поводу? Я что-то упустил?
начиная с Android SDK v15, наряду с Eclipse 3.7.1, Java 7 является не поддерживается для разработки Android. Установка совместимости источника на 1.7 мандаты установка сгенерированного .класс совместимости файлов до 1.7, что приводит к следующей ошибке компилятора Android:
Android требует уровень соответствия компилятора 5.0 или 6.0. Нашли '1.7' вместо этого. Пожалуйста, используйте инструменты Android > исправить свойства проекта.
чтобы расширить приведенный выше ответ @KennyTM, если вы нацелены на 4.0.3 и выше (minSdkVersion=15), вы можете использовать скрытые API, добавив несколько классов в SDK вашего целевого android.сосуд.
как только вы это сделаете, вы можете использовать try-with-resources на любом закрытом, а также реализовать автоклавирование в своих собственных классах.
Я сделал zip, содержащий источники и двоичные файлы всех классов, которые необходимо было изменить в android.jar, чтобы сделать эти API доступный. Вам просто нужно распаковать его и добавить двоичные файлы в ваш
android-sdk / платформы / android-NN / android.банку
вы можете скачать его здесь:http://db.tt/kLxAYWbrтакже следует отметить, что за последние пару месяцев Эллиот Хьюз сделал несколько коммитов для дерева Android:добили AutoCloseable,добавлено SafeVarargs,unhidden различные API,исправлено Защищенный конструктор Throwable и добавлена поддержка файлов класса версии 51 в dx. Итак, наконец-то есть некоторый прогресс.
Edit (Апрель 2014):
С выпуском SDK 19 больше не нужно исправлять android.jar с дополнительными API.
лучший способ использовать try-with-resources в Android Studio для приложения, предназначенного для 4.0.3 и выше (minSdkVersion=15) - добавить после
compileOptions
наbuild.gradle
:android { compileSdkVersion 19 buildToolsVersion '19.0.3' defaultConfig { minSdkVersion 15 targetSdkVersion 19 } compileOptions { sourceCompatibility JavaVersion.VERSION_1_7 targetCompatibility JavaVersion.VERSION_1_7 } }
Android Studio будет жаловаться, что try-with-resources не может использоваться с этим уровнем API, но мой опыт заключается в том, что он может. Проект будет построен и запущен без проблем на устройствах с 4.0.3 и выше. Я не испытывал никаких проблем с этим, с приложением, которое было установлено в 500k+ устройств.
чтобы игнорировать это предупреждение, добавьте следующее в
lint.xml
:<issue id="NewApi"> <ignore regexp="Try-with-resources requires API level 19"/> </issue>
кажется, что заставить это работать с чистым муравьем-это немного Клудж.
но это сработало для меня: http://www.informit.com/articles/article.aspx?p=1966024
чтобы использовать функции Java 7 в сборке кода системой сборки на основе ant Android, просто поместите следующее в свой
custom_rules.xml
в корневом каталоге вашего проекта:custom_rules.XML-код:
<project name="custom_android_rules"> <property name="java.target" value="1.7" /> <property name="java.source" value="1.7" /> </project>
некоторые люди могут быть заинтересованы в этом проекте git, который я нашел, что, кажется, позволяет запускать Java 7 на android. https://github.com/yareally/Java7-on-Android
однако слишком большой риск, если я добавлю это в текущий проект, над которым я работаю. Поэтому я подожду, пока Google официально не поддержит Java 7.