Android 使用 Java 8 語言功能
此文完全來源於谷歌開發者網站的文件,介紹你可以使用的 Java 8 語言功能、如何正確配置專案以使用這些功能以及您可能遇到的任何已知問題。(傳送門直達: 使用 Java 8 語言功能 )
Android+Studio/">Android Studio 3.0 及以上版本支援所有 Java 7 語言功能,以及部分 Java 8 語言功能(具體因平臺版本而異)。
注:在開發 Android 應用時,可以選擇使用 Java 8 語言功能。 您可以將專案的原始碼和目的碼相容性值保留為 Java 7,但仍須使用 JDK 8 進行編譯。
Android Studio 為使用部分 Java 8 語言功能及利用這些功能的第三方庫提供內建支援。
如圖 1 所示,預設工具鏈對 javac
編譯器的輸出執行位元組碼轉換(稱為 desugar
),從而實現新語言功能。 Jack 不再受支援 ,您需要首先 停用 Jack 才能使用預設工具鏈內建的 Java 8 支援。

圖 1. 採用 desugar 位元組碼轉換的 Java 8 語言功能支援
要開始使用受支援的 Java 8 語言功能,請 更新 Android 外掛 到 3.0.0
(或更高版本)。
然後,針對使用(包括在原始碼中或通過依賴項使用)Java 8 語言功能的每個模組,在其 build.gradle
檔案中新增以下程式碼:
android { ... // Configure only for each module that uses Java 8 // language features (either in its source code or // through dependencies). compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } }
注:如果 Android Studio 檢測到您的專案使用的是 Jack、 Retrolambda 或 DexGuard ,IDE 則會使用由這些工具提供的 Java 8 支援。 但您可以考慮 遷移至預設工具鏈 。
支援的 Java 8 語言功能和 API
雖然 Android Studio 並非支援所有 Java 8 語言功能,但未來發布的 IDE 版本將會增加更多功能。 目前,部分功能和 API 已可使用,具體取決於您所使用的 minSdkVersion,詳見下表:
Java 8 語言功能 | 相容的 minSdkVersion |
---|---|
Lambda 表示式 | 任意。 然而,只有在 Lambda 採集的所有值可序列化時才支援 Lambda 序列化。 |
函式引用 | 任意。 |
型別註解 | 任意。 然而,型別註解資訊僅在編譯時可用,在執行時不可用。 此外,在 API 級別 24 及更低級別中,平臺支援 TYPE ,而不支援 ElementType.<wbr style="box-sizing: inherit;">TYPE_USE 或 ElementType.<wbr style="box-sizing: inherit;">TYPE_PARAMETER 。 |
預設和靜態介面函式 | 任意。 |
重複註解 | 任意。 |
Java 8 Language API | 相容的 minSdkVersion |
java.lang.annotation.Repeatable |
API 級別 24 或更高級別。 |
AnnotatedElement.getAnnotationsByType(Class) |
API 級別 24 或更高級別。 |
java.util.stream |
API 級別 24 或更高級別。 |
java.lang.FunctionalInterface |
API 級別 24 或更高級別。 |
java.lang.reflect.Method.isDefault() |
API 級別 24 或更高級別。 |
java.util.function |
API 級別 24 或更高級別。 |
除了上述 Java 8 語言功能和 API 之外,Android Studio 3.0 及更高版本還將對 try
-with-resources 的支援擴充套件到所有級別的 Android API。
Desugar 目前暫不支援 MethodHandle.invoke
或 MethodHandle.invokeExact
。 如果您的原始碼或任一模組依賴項使用了其中一種函式,則需指定 minSdkVersion 26
或更高版本。 否則會出現以下錯誤:
<pre class="prettyprint" style="box-sizing: inherit; background: rgb(247, 247, 247); color: rgb(55, 71, 79); font: 400 14px/20px "Roboto Mono", monospace; padding: 8px; margin: 16px 0px; overflow-x: auto; position: relative; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">`Dex:Error converting bytecode to dex:Cause: signature-polymorphic method called without --min-sdk-version >=26` </pre>
在某些情況下,即使您的模組包含在庫依賴項中,也可能不會使用 invoke
或 invokeExact
函式。 因此,要繼續使用 minSdkVersion 25
或更低版本的庫,請通過 啟用程式碼壓縮 移除未使用的函式。 如果這種方法無效,可考慮使用一個替代庫,該庫不使用未受支援的函式。