Android官方兼容方案
工具方面要求
- Android Studio 2.1 以上
- 启用 Jack 编译
不过这个 Jack 编译会带来一些问题,例如,不能用 Instant Run,不能用 Lint等等。
Android不同的版本对Java8的支持
- 默认方法和接口的静态方法(API >=24)
- Lambda表达式
- 重复注解(API>=24)
- 方法引用
- 类型注解
简单的说,Stream流只有到 Android 7.0 以后才能用。
官方方法的缺陷
- 要想使用 Lambda 表达式,必须用 Jack 编译,这样 Instant Run 不能用。 这样的话,我们每次编译都可以去倒一杯咖啡了。
- 想使用 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 的升级版。 是不是看的你有点心动了,不多说,搞起!