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

適用於Android的Java 8:使用Lambda表達式的簡介代碼

by
Read Time:15 minsLanguages:
This post is part of a series called Java 8 for Android Development.
Java 8 for Android Development: Default and Static Methods

Chinese (Traditional) (中文(繁體)) 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 toastTest your lambda expression by triggering the Java 8 toastTest 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開發人員執行的壹些最常見任務。

對於任何希望采用功能更強大的編程方法的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 appearsSelect Replace with lambda from the context menu that appearsSelect 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 popupSelect Anonymous type can be replaced with lambda from the Enter inspection name popupSelect 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 In the Inspection Results window select the Replace with lambda button 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應用程序開發的其他文章!

关注我们的公众号
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.