Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Android SDK
Code

适用于Android的Java 8:使用Lambda表达式的简介代码

by
Difficulty:IntermediateLength:LongLanguages:
This post is part of a series called Java 8 for Android Development.
Java 8 for Android Development: Default and Static Methods

Chinese (Simplified) (中文(简体)) translation by Zhang Xiang Liang (you can also view the original English article)

Lambda表达式可以帮助您从项目中移除样板代码并轻松处理大量数据。看看如何深入了解您今天可以在Android项目中开始使用的Java 8功能。 

Java 8 for Android

2014年3月首次推出的Java 8向编程语言迈进了一大步,它引入了一系列功能,这些功能可以使Java编码变得比以前更简单,更简洁。

不幸的是,Android开发人员暂时不会感受到这些功能的好处,因为谷歌在弃用Jack之前试图通过Jack(Java Android Compiler Kit)将Java 8引入Android平台,以支持在Android Studio中原生支持Java 8。

现在,随着Android Studio 3.0的发布,我们终于有了一个Android工具链版本,它内置了对Java 8最重要的一些功能的支持。

在本系列中,我将向您展示如何从项目中删除大量样板代码,轻松处理大量数据,甚至在Java 8编程中拥有更实用的风格。我们将深入了解您现在可以开始使用的Java 8功能。

在完成本系列时,您将准备好在Android项目中使用以下所有Java 8功能:

  • lambda表达式
  • 方法引用
  • 默认方法
  • 静态接口方法
  • 键入注释
  • 重复注释
  • 功能接口
  • Stream API

在第一篇文章中,我们将看看Java 8第一次发布时产生最多嗡嗡声的特性,并且这有助于为Android开发人员带来最大的不同:lambda表达式。

准备你的开发环境

在开始使用任何 Java 8功能之前,您需要确保您的开发环境已设置为支持此版本的Java。

如果您尚未安装Java 8,那么您需要下载最新的JDK8并更新Android Studio的JDK路径,以便它指向JDK8软件包:

  • 启动Android Studio。
  • 从Android Studio工具栏中选择File> Project Structure ...
  • 更新JDK位置字段,以便它指向新下载的JDK8软件包。

如果您不确定您安装的是哪个版本的Java,那么可以通过打开终端窗口(如果您是Mac用户)或命令提示符(如果您在Windows上)来检查,然后运行以下命令命令:

如果它返回1.8或更高版本,那么你很好走!

您还需要安装Android Studio 3.0 Preview 1或更高版本,但为了减少遇到错误和其他奇怪行为的机会,建议您安装最新版本的Android Studio 3.0--无论是测试版还是预览版,或者,理想情况下,是一个稳定版本的Android Studio 3.0(在撰写本文时尚未提供)。 

接下来,您需要对项目build.gradle文件进行一些更改。通常,您只需添加几行代码即可指定该项目应生成Java 8字节码。但是,如果您以前使用Jack编译器或流行的Retrolambda项目对Java 8功能进行了试验,那么在项目可以使用Android默认工具链提供的新增和改进的Java 8支持之前,您需要禁用这些工具。

在下面的章节中,我将向您展示如何启用Java 8支持,以及如何在需要时禁用Retrolambda和Jack。

将Java 8支持添加到新项目

假设您之前没有启用Jack或将Retrolambda添加为项目依赖项,则第一步是打开您的项目级build.gradle文件并确保您使用的是适用于Android的Gradle版本3.0.0-alpha1(或更高版本)插入:

接下来,打开build.gradle您要使用Java 8功能的每个模块级文件,并将源代码的语言级别和生成的Java字节码的版本设置为JavaVersion.VERSION_1_8

如果你从Jack迁移

Jack编译器可能会被弃用,但只要启用它,您的项目将使用由Jack提供的Java 8支持,而不是Android默认工具链提供的支持。

使用不推荐使用的工具永远不是一个好主意,但是如果你还没有从Jack编译器迁移出来,还有一些额外的原因。

首先,Jack可能会支持Java 8功能的一个子集,但与默认工具链不同,它不支持使用这些功能的第三方库,所以通过使用Jack,您立即就第三方库限制了您的选择。

其次,Jack编译器需要Java代码并将其直接转换为dex,而不产生任何中间字节码。只要启用了Jack,您将无法使用任何依赖此中间输出的工具,例如注释处理器和字节码分析器。

要禁用Jack编译器,请打开您的模块级build.gradle文件并删除该jackOptions部分,但请确保compileOptions完整地保留该块:

如果你从Retrolambda迁移

与Jack类似,Retrolambda不支持使用Java 8语言功能的第三方库。如果您的项目设置为使用Retrolambda插件,那么您应该删除此插件,以便您的项目可以恢复为默认工具链。

打开您的项目级build.gradle文件并将Retrolambda作为项目依赖项移除:

然后,从每个模块级build.gradle文件中删除Retrolambda插件:

测试您的Java 8支持

验证您的项目现在可以支持Java 8的最简单方法是编写快速的lambda表达式,并查看您的项目是否仍在编译。

将一个按钮添加到您的用户界面(或使用已存在的按钮),然后onClickListener 使用lambda表达式为此按钮实现一个按钮。不要担心,如果下面的代码现在没有多大意义 - 这将在本文结尾!

Test your lambda expression by triggering the Java 8 toast

检查您的项目是否仍然编译,通过从出现的横幅中选择同步,或从Android Studio工具栏中选择工具> Android>使用Gradle文件同步项目

如果Android Studio不会引发任何错误,那么您就可以开始使用本文开头列出的所有功能,包括lambda表达式!

为什么Lambda表达式如此重要?

Lambda表达式很容易成为Java 8最大的新功能,并且可以对创建几乎任何Android应用程序时需要编写的样板代码数量产生巨大影响。

本质上,lambda表达式表示一个不属于任何类的函数,并且可以轻松传递,然后按需执行。

此功能消除了许多Android开发人员在Java方面经历的长期挫折:作为一种面向对象的语言,传递代码块总是感觉比应该更困难。例如,如果您想创建一个新线程,然后将一些代码传递给该线程,那么您通常必须通过匿名实现Runnable接口来实例化一个线程 - 这只是为了传递一些代码而做的很多工作!通过提供一种将函数传递给方法的简单方法,lambda表达式有可能简化您作为Android开发人员执行的一些最常见任务。 通过提供一种将函数传递给方法的简单方法,lambda表达式有可能简化您作为Android开发人员执行的一些最常见任务。

对于任何希望采用功能更强大的编程方法的Java开发人员来说,Lambda表达式也将是一个受欢迎的补充。在Java 8之前,以功能风格进行编码将不可避免地要求您编写大量样板代码,但现在您可以使用lambda表达式传递函数,以较少面向对象的方式编写Java代码,而不必涉及写了大量的匿名类。

如何创建Lambda表达式?

您可以使用以下语法创建一个lambda表达式:

箭头运算符是不言而喻的,但是您应该如何构造lambda的参数和表达式的规则可以根据您要实现的内容而有所不同,因此我们来更详细地探讨这两个元素。

参数

参数是一个或多个参数,它们几乎总是用圆括号括起来。即使你的lambda表达式没有任何参数,你仍然需要提供空的括号,例如:

这个规则的例外是当你的方法有一个推断出它的类型的单个参数时,在这种情况下你可以省略括号:

您可以在参数中使用多个参数,方法是用逗号分隔每个参数:

类型推断在lambdas中是可能的,所以你通常可以从你的参数中省略数据类型。但是,如果编译器无法推断数据类型,则需要在参数前添加类型:

表达体

表达式主体是您要执行的代码,可以是单个表达式或多行代码。如果你想要执行多行代码,那么你需要用大括号括住代码的这一部分来创建一个语句块:

如果你的表达式返回一个值,那么它必须返回一个return语句,例如:

在您的Android应用中使用Lambda表达式

现在我们对可以构造lambda表达式的各种方式进行了概述,让我们来看看一些最常见的场景,您可以在Android开发工作中使用lambda表达式。

Lambdas进行事件处理

典型的Android应用程序必须能够响应各种各样的用户输入事件,并且lambda表达式可以使此事件处理更直接。

在下面的代码中,我们使用一个匿名类来创建一个onClickListener带有重写onClick方法的实例。很有可能,你已经无数次地写了这样的代码。

通过用lambda表达式重写上述代码,我们可以删除以下所有内容:

  • 类实例化: new View.OnClickListener()
  • 访问修饰符,方法名称和类型: public void onClick(View view)
  • 和参数类型,所以你不必写 View view

这意味着我们可以使用单行来实现完全相同的功能:

Lambdas用于多线程

多线程是lambda表达式可以帮助您编写更简洁的代码的另一种常见方案。默认情况下,Android具有一个UI(用户界面)线程,负责处理所有用户交互,将事件分派到相应的UI小部件以及修改用户界面。只要您用任何长时间运行或密集型操作阻止此UI线程,您的应用程序就会变得无响应,甚至可能触发Android的ANR(应用程序无响应)对话框。因此,创建其他线程并分配代码以在这些线程上运行通常是Android开发的重要组成部分。 只要您用任何长时间运行或密集型操作阻止此UI线程,您的应用程序就会变得无响应,甚至可能触发Android的ANR(应用程序无响应)对话框。因此,创建其他线程并分配代码以在这些线程上运行通常是Android开发的重要组成部分。

在Java 8之前,分配代码以在其他线程上运行需要您创建一个实现该Runnable接口的匿名类:

或者,您可以使用Runnable接口的匿名实现来实例化新线程:

用lambda表达式替换这个匿名类可以使这个频繁执行的任务很多更简洁:

最后,如果您使用的是RxJava或RxAndroid库,那么您可以使用lambda表达式来帮助您创建observables。

在这里,我们正在创建一个简单的命令Observable,将hello world字符串 发送给它的所有字符串Observers

使用lambda表达式可以让你Action1用一行代替所有的代码:

在您的 实际代码中使用Lambda表达式

在阅读了一个新功能背后的所有理论之后,下一个挑战就是养成使用这个新功能的习惯。对于像lambda这样的设计用来代替熟悉的样板代码的设计来说,这可能会特别困难,因为总会有一种简单回归你所知的诱惑。

Android Studio有一些功能可以帮助您最终推动使用闪亮的新lambda表达式替换熟悉而笨重的代码。

第一个功能是Android Studio的意图操作菜单,它可以将任何兼容的匿名类自动转换为等效的lambda表达式。如果您不确定如何编写lambda格式的特定代码,那么这非常完美:只需像往常一样编写代码,然后使用intent操作菜单的自动转换功能即可。

要将匿名类自动转换为lambda表达式:

  • 将光标悬停在匿名类上,Android Studio应该显示一个工具提示,通知您它可以将这段代码转换为lambda表达式。
  • 按下Mac的Alt / Option-Enter键,或者如果您是Windows或Linux用户,请使用Alt-Enter快捷键。
  • 从上下文菜单中选择Replace with lambda选项。

Select Replace with lambda from the context menu that appears

或者,您可以使用Android Studio的检测工具在整个项目中标记每个可以用lambda表达式替换的匿名类。然后,您可以手动重写每个匿名类,也可以让Android Studio的自动转换功能向您演示如何完成。

突出显示Android Studio可能用lambda表达式替换的每个匿名类:

  • 从Android Studio工具栏中选择分析>按名称运行检查
  • 在出现的弹出窗口中,开始输入匿名类型可以替换为lambda,然后在出现在下拉菜单中时选择该选项。

Select Anonymous type can be replaced with lambda from the Enter inspection name popup

  • 在随后的窗口中,选择整个项目来标记项目中的每个匿名类。或者,您可以指定Android Studio应执行此检查的个别模块或文件。
  • 点击确定
  • 从Android Studio工具栏中选择分析>检查代码

“检查结果”窗格现在应显示并显示可用Lambda表达式替换的所有匿名类的列表。要仔细查看一个匿名类,只需在“ 检查结果”窗口中双击该类,Android Studio将打开该文件并带您到包含此特定匿名类的确切行。

要用lambda表达式替换当前选定的匿名类,请单击“ 替换为lambda”按钮。

In the Inspection Results window select the Replace with lambda button

如果Android Studio未自动打开检查结果窗口,则可以通过从Android Studio工具栏中选择视图>工具窗口>检查结果手动启动它。如果检查结果未出现在工具Windows子菜单中,则可能需要先从Android Studio工具栏中选择分析>检查代码...

测试Lambda表达式

尽管lambda表达式提供了许多好处,但在将其添加到代码之前,您应该知道一个主要缺点。由于lambda没有名称,因此不能直接从测试代码中调用它们,因此向项目添加大量lambda表达式可能会使测试更加困难。

理想情况下,您的lambda表达式应该太简单而不会中断,因此无法对它们进行单元测试应该不是太大的问题。然而,如果你确实需要测试lambda,那么你总是可以像处理私有方法一样对待它,并且单元测试结果,而不是lambda本身。或者,您可以将lambda表达式重构为其自己的方法,因此您可以直接引用它,因此可以正常进行测试。   或者,您可以将lambda表达式重构为其自己的方法,因此您可以直接引用它,因此可以正常进行测试。  

结论

在这篇关于Java 8语言特性的第一篇文章中,我们研究了如何设置Android项目以支持Java 8,以及如何通过用lambda表达式替换匿名类来减少样板代码。 

在下一篇文章中,我将向您展示如何通过将lambda表达式与方法引用相结合来修剪Android项目中的更多代码,以及如何使用默认和静态接口方法来增强接口。

同时,查看一些关于Android应用程序开发的其他文章!

Envato qr branded
关注我们的公众号
Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.