如何在 Android 中使用 Java8

Android官方兼容方案

工具方面要求

  1. Android Studio 2.1 以上
  2. 启用 Jack 编译

不过这个 Jack 编译会带来一些问题,例如,不能用 Instant Run,不能用 Lint等等。

Android不同的版本对Java8的支持

  1. 默认方法和接口的静态方法(API >=24)
  2. Lambda表达式
  3. 重复注解(API>=24)
  4. 方法引用
  5. 类型注解

简单的说,Stream流只有到 Android 7.0 以后才能用。

官方方法的缺陷

  1. 要想使用 Lambda 表达式,必须用 Jack 编译,这样 Instant Run 不能用。 这样的话,我们每次编译都可以去倒一杯咖啡了。
  2. 想使用 Stream, 把 minSdkVersion 改为24及以上。这样等于直接打出GG。

非官方的兼容方案

其实我们最常用就是 Lambda表达式 和 Stream API,我们需要兼容这2个方面。

retrolambda

刚才提到,官方的 Lambda表达式 兼容方案是由缺陷的,而 retrolambda 插件就是解决就是解决在 Android 的各个版本使用 Lambda表达式 这一问题的。

由于这个插件是在 maven 仓库中,所以在 Application 的 build.gradle 文件中

buildscript {
    repositories {
        jcenter()
        // step1
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.2.3'
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
        // step2
        classpath 'me.tatarka:gradle-retrolambda:3.4.0'
    }
}


allprojects {
    repositories {
        jcenter()
        //step3
        mavenCentral()
    }
}

为了看清加了哪几行,我标注了 step1, step2, step3,后面也同样这样标注。

然后再到 Application 的 Module 模块中应用这个插件

apply plugin: 'com.android.application'
// step1
apply plugin: 'me.tatarka.retrolambda'


android {
    compileSdkVersion 25
    buildToolsVersion "25.0.0"

    //...

    // step2
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

dependencies {

    // ...

    compile 'com.android.support:appcompat-v7:25.0.0'
    // step3
    compile 'me.tatarka:gradle-retrolambda:3.4.0'
}

同步下,现在项目中可以使用 Lambda表达式了。举个例子

button.setOnClickListener(view -> Toast.makeText(this, "Hello Lambda", Toast.LENGTH_SHORT).show());

与用匿名内部内实现相比,是不是就很简洁。

stream

Java8 中的 Stream 的非官方兼容方案为一个库,名字为 com.annimon:stream

那么很简单了,在 Module 的 build.gradle 文件中加入到 dependencies 中

dependencies {
    compile 'me.tatarka:gradle-retrolambda:3.4.0'
    // step1
    compile 'com.annimon:stream:1.1.4'
}

同步一下就可以使用 Stream 了,不过使用的是 com.annimon.stream.Stream, 举个例子,求 1, 2, 3中的最大值。

int max = Stream.of(1, 2, 3)
    .mapToInt(integer -> integer)
    .max()
    .getAsInt();

其实有对比才有差别,可以对比下用集合的迭代器来求最大值。

非官方兼容方案总结

虽然非官方的替代方案可行,但是我再使用的时候,发现非官方的 Stream 和 Java8 中的 Stream 还是有差别的。例如,上面的例子,在 Java8 中可以这样用

int max = Stream.of(1, 2, 3)
    .mapToInt(integer -> integer)
    .summaryStatistics()
    .getMax();

不过在学习的过程中,功能上也差别不大。

结束

现在的 RxJava 非常火,其中之一就是 Lambda 表达式的应用。另外,RxJava 也有自己的流 Observable,如果你学完了 Java8 ,你可以发现 RxJava 其实很多东西都是相通的。再多说几句,什么是 Rx,全名是 Reactive Extensions – 响应扩展,Reactive 对应的就是观察者模式的,而这个 Extensions 是针对集合的迭代,以及函数式编程。 而 RxJava 中这些东西与 Java8 中的 Lambda , Stream,以及 Stream 的函数式写法相同或者相似,个人感觉就是 Java8 的升级版。 是不是看的你有点心动了,不多说,搞起!

    原文作者:Mr13_周
    原文地址: https://blog.csdn.net/zwlove5280/article/details/54096748#t6
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞