Подтвердить что ты не робот

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

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

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);

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

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

Вместо использования 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
4b9b3361

Ответ 1

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

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

Пока эта поддержка не будет расширена, android-retrostreams обеспечивает поддержку бэкпорта для большинства из них. Этот проект является "модернизированным портом" библиотеки 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 (и с немного разными именами методов и шаблонами вызовов - но с той же функциональностью).

Ответ 2

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

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

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

Ответ 3

Библиотека поддержки Android (AndroidX) теперь имеет Consumer и Supplier:

к сожалению, только эти два интерфейса добавляются на момент написания.

Теперь у нас есть Kotlin, он не требует явного указания функционального интерфейса:

    fun test() {
        val text = withPrintStream {
            it.println("Header bla bla ")
            it.printf("%s, %s, %s,", "a", "b", "c").println()
        }
    }

    // Equivalent to the following code in Java:
    //     Consumer<PrintStream> action;
    //     action.accept(ps);
    fun withPrintStream(action: (PrintStream) -> Unit): String {
        val byteArrayOutputStream = ByteArrayOutputStream()
        val ps = PrintStream(byteArrayOutputStream)
        action(ps)
        ps.flush()
        return byteArrayOutputStream.toString()
    }

Ответ 4

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

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

Сообщите мне, как это происходит.

Ответ 5

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

code: ipcjs/java-support