Есть ли способ использовать функциональные интерфейсы Java 8 на Android API ниже 24?

Я могу использовать retrolambda для включения lambdas с уровнем API Android

myButton.setOnClickListener(view -> Timber.d("Lambdas work!"));

это также работает

Runnable runLater = () -> Timber.d("Lambdas work!");
runLater.run();

но этот не

Consumer<Integer> runLaterWithInt = (Integer i) -> Timber.d("i = " + i);
runLaterWithInt.accept(3);

последний работает на уровне API Android 24, но на других устройствах этот код вызывает сбой

java.lang.NoClassDefFoundError: com.retrolambdatry.MainActivity$$Lambda

вместо использования retrolambda я попытался включить Java 8. Первые два примера кода все еще работают, хотя butterknife перестал работать. https://developer.android.com/preview/j8-jack.html#configuration здесь ava.util.function говорят, что поддерживается, но я все равно получаю сбой при запуске третьего, на этот раз это немного отличается

java.lang.NoClassDefFoundError: com.retrolambdatry.MainActivity$-void_onCreate_android_os_Bundle_savedInstanceState_LambdaImpl1

4 ответов


не уверен, что вам все еще нужен ответ на этот вопрос, но другие (такие как я) могут.

как версия 3.0, Android Studio поддерживает лямбда-функции и многие другие функции Java 8 на всех уровнях API, но некоторые (например, функциональные интерфейсы и java.util.function) по-прежнему ограничены API 24+.

пока эта поддержка не будет расширена, android-retrostreams обеспечивает поддержку backport для большинства из них. Этот проект является " модернизированным портвейн библиотека streamsupport, который вы также можете использовать и имеет множество функций в android-retrostreams. Библиотека streamsupport поддерживает до Java 6/7, поэтому вы можете использовать ее, даже если у вас нет as 3.0+ или не нацелены на Java 8, но вам, вероятно, лучше использовать android-retrostreams в большинстве случаев, если вы можете. Вы можете пройти через javadocs проекта, чтобы увидеть именно то, что предлагается, но основные моменты, которые я использовал, -java.util.function и java.util.Comparator.

отметим, что java в названиях пакетов заменяется на java9, и некоторые имена классов и/или методов могут быть слегка изменены. Например:

java.util.function становится java9.util.function,

пока

java.util.Comparator становится java9.util.Comparators (и с немного разными именами методов и шаблонами вызовов, но с той же функциональностью).


для альтернативных, легкий-поток-API также обеспечивает поддержку backport. Как android-retrostreams metioned выше, вы должны заменить некоторые имена пакетов, используя:

com.annimon.stream.function вместо java.util.function

com.annimon.stream.ComparatorCompat вместо java.util.Comparator


функциональные интерфейсы Java 8 можно включить для запуска на более ранних версиях android, включив Jack Toolchain. Вы можете сделать это путем добавления следующих строк кода :

android{
...
  defaultConfig{
    ...
    jackOptions.enabled = true
  }
  compileOptions{
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  }
}

однако вы должны отметить, что вам нужно отключить мгновенный запуск, так как он все еще не может работать с Java 8.

вы также можете узнать больше информации из этого видео с канала разработчиков android: https://www.youtube.com/watch?v=zfLKMun94Yc&index=10&list=PLWz5rJ2EKKc9tH0dRV1_HmQBXe_-qFQPl

Дайте мне знать, как это происходит.


allprojects {
    repositories {
        maven { url 'https://jitpack.io' }
    }
}
dependencies {
        compile 'com.github.ipcjs:java-support:0.0.3'
}

код: ipcjs / java-поддержка