Java 8 的推出引入不少革命性變化,加入了函數式編程的特徵,使基於行爲的編程成爲可能,同時簡化了各類設計模式的實現方式,是 Java 有史以來最重要的更新。java
自 Android N 以後,因爲 Jack&Jill 編譯工具鏈的存在,Java 8 的一些語言功能終於獲得了支持。雖然還存在一些限制,如,新編譯器附帶的數據綁定支持庫沒法使用,以及註釋支持受限等,但這徹底不足以否認 Java 8 中存在的其餘先進功能。在這篇文章中,做者介紹了在 Android 中引入 Java 8 功能的四個庫,但願它們對你有幫助。android
文章若是有翻譯不到位的地方,歡迎你們進行指正。喜歡的也不要忘了點贊、打賞、收藏哦~git
Java 8 的發佈引入了一些新特性。在全部功能中較爲重要的有 lambda 表達式,方法引用,Stream API 和新的時間日期 API。github
目前,Jack&Jill 編譯工具鏈還處於早期開發階段,它比較容易與 Java 7 保持同步。另外,很幸運的是,如今有幾款庫還能將 Android 中 的 Java 8 移植到更低版本的編譯器中。讓咱們來看看它們是如何發揮做用的。express
伴隨 Java 8 的發佈而發佈的 lambda 表達式,容許你使用參數傳遞代碼塊。它們能夠用於代替類的匿名實例,例如,對單擊按鈕時執行的操做進行定義。下面我演示了使用匿名類和 lambda 表達式在按鈕上設置 onClick 監聽器:編程
// Anonymous class approach: button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // onClick action here } });
// Lambda expresssion approach: button.setOnClickListener(view -> { // onClick action here });
若是想了解有關 lambda 表達式的更多信息,能夠參閱 Java 8 中的 Lambda 表達式和 Android 中的 Lambda 表達式。設計模式
使用 Retrolambda 能很快實現 Java 6 和 Java 7中的Lambda 表達式功能,將它應用在 Android 上也是同樣。Retrolambda 能轉換 Java 8 編譯的字節碼,以便它在更低版本的 Java 中運行此代碼,而不須要任何附加的依賴關係。api
要在 Android Studio 項目中使用 retrolambda,須要將下列代碼添加到項目級別的 build.gradle 文件中:併發
buildscript { repositories { jcenter() mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:2.1.2' classpath 'me.tatarka:gradle-retrolambda:3.2.5' } } ...
模塊級 build.gradle 文件應包含如下突出顯示的代碼行:app
apply plugin: 'com.android.application' apply plugin: 'me.tatarka.retrolambda' android { compileSdkVersion 23 buildToolsVersion "24.0.1" defaultConfig { applicationId "com.example.lambdas" minSdkVersion 16 targetSdkVersion 23 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } }
遵循以上步驟,你已經可以成功地在 Android上啓用 Java 8 的其中一項功能。
方法引用能夠很方便地與 lambda 表達式一塊兒使用,以簡化語法。例如,若是一個 lambda 表達式主體包含一個類方法調用,它能夠替換爲一個方法引用:
Arrays.sort(new Integer[] {1, 2, 3}, (first, second) -> first.compareTo(second));
Arrays.sort(new Integer[] {1, 2, 3}, Integer::compareTo);
參數會自動提供以匹配方法簽名(method signature)。
這裏存在三種::運算符用法:
你可點擊此處瞭解更多有關方法引用和構造函數引用的信息。
若是你已經使用 retrolambda 庫啓用了 lambda 表達式,方法引用此時也能正常運行,由於此功能是包含在內的。若是沒有,請你參考上一節的內容。
Java 8 另外一個了不得的語言特性就是 Stream API,Stream 表示抽象層,容許開發人員以聲明方式處理底層數據。它的另外一個好處就是能對 Stream 採起並行執行操做,這有利於開發人員有效地處理大量數據,而沒必要爲併發和線程管理擔憂。
例如,咱們有一個數字列表,須要過濾出小於 10 的數字,而後返回其他的排序列表。使用 Stream API,事代碼表現更美觀:
List<Integer> numbers = new ArrayList<>(); numbers.addAll(Arrays.asList(1, 20, 3, 10, 20, 30, 4, 50, 80, 1, 2)); List<String> large_number = numbers.stream() .filter(num -> num >= 10) .sorted() .collect(Collectors.toList());
這僅是 Stream API 提供的一個簡單示例。 有關 Java 中的 Stream 的更多信息,請參閱 Java 8 中的 Stream API。
在 Android 中,咱們有兩個庫,能夠從 Stream API 中選擇,咱們來看下:
Lightweight-Stream-API 庫將 Stream API 反向運行到 Java 7,並經過使用迭代器重寫 API 來下降版本。該庫在原始 Java 8 實現中提供了許多 Stream 操做符,其中有一些是新的,如:sortBy,groupBy,chunkBy,sample,slidingWindow 等。
將庫包含到 Android 項目中是爲了給 build.gradle 文件中的依賴項添加單獨的一行:
dependencies { ... compile 'com.annimon:stream:1.1.3' ... }
因爲該庫已經從新實現 Stream API 的方式,一些語法會與原始的 Stream 實現不一樣,而且並行執行也被省略。 更多信息,請參閱 Github 上的庫頁面。
第二個將 Stream API 從 Java 8 回退到更低版本的庫就是 streamsupport 庫。與 Lighweight-Stream-API 相比,streamsupport 除了具備並行執行功能和 Java 9 的加強功能外,還有一些其餘的功能,如,Java 8 的功能接口或可選模式。
爲了在您的項目中使用 streamsupport 庫,請將如下依賴項添加到 build.gradle 文件中:
dependencies { compile 'net.sourceforge.streamsupport:streamsupport:1.5.2' compile 'net.sourceforge.streamsupport:streamsupport-cfuture:1.5.2' compile 'net.sourceforge.streamsupport:streamsupport-atomic:1.5.2' compile 'net.sourceforge.streamsupport:streamsupport-flow:1.5.2' compile 'net.sourceforge.streamsupport:streamsupport-literal:1.5.2' }
更多信息,請參閱 Github 上的 streamsupport 庫。
Java 8 以前的版本不太支持日期和時間的設置。雖然也有幾個支持的 API,但它們各自都存在問題。爲解決這些問題,Java 8 帶來了新時間日期,你能夠點擊此處瞭解更多相關信息。
雖然 Android 不支持 Java 8 中的時間日期 API,但一個名爲 ThreeTen Android Backport 的庫能夠提供相同的功能。
使用以前,請將如下行添加到 build.gradle 文件中:
compile 'com.jakewharton.threetenabp:threetenabp:1.0.4'
在這篇文章中,我介紹了在 Android 中引入 Java 8 功能的四個庫。 使用這些庫,您能夠在 Android 中使用 lambda 表達式,方法引用,Stream API 或新日期時間 API,而無需遷移到新的 Jack&Jill 編譯器工具鏈,同時還能保持與之前版本的 Android 和 Java 的兼容性。
本文翻譯自 Milan Bárta 的 Enable Java 8 features in Android with these libraries。