一起看 I/O | Jetpack 元件的新特性

Android開發者發表於2022-05-27

作者 / Amanda Alexander, Product Manager, Android

Android Jetpack 是開啟 現代 Android 開發 (Modern Android Development,即 MAD 之門的鑰匙,它是一個包含超過 100 個庫、工具及指南的套件,以幫助開發者遵循最佳實踐、減少模板程式碼,以及編寫在不同 Android 版本和裝置上表現一致的程式碼,從而使您可以專注於在應用中實現獨特的功能。

在 Google Play 中,絕大多數應用都使用了 Jetpack 實現應用架構。今天,在排名前 1,000 的應用中,超過 90% 使用了 Jetpack

本文是 Jetpack 近期更新中的重點部分,也是 I/O 大會演講: Jetpack 的新功能 的延展閱讀!

接下來,我們將會介紹 Jetpack 在三個主要領域的更新:

  1. 架構庫及指南;
  2. 應用的效能優化;
  3. 使用者介面庫及指南。

以及對一些其他關鍵更新的總結。

1. 架構庫及指南

應用架構庫及其元件可以保證應用的健壯性、可測試性,以及可維護性。

資料持久化

Room 是我們推薦的資料持久化層,它在 SQLite 之上提供了一個抽象層,從而提高了平臺的可用性和安全性。

在 Room 2.4 中,對 Kotlin Symbol Processing (KSP) 的支援已經穩定。在我們針對 Kotlin 程式碼的基準測試中,KSP 相對 KAPT 有兩倍的速度提升。Room 2.4 還內建了對列舉和 RxJava3 的支援,同時也全面支援 Kotlin 1.6。

我們從 Room 2.5 開始使用 Kotlin 對整個庫進行重寫。這一改變可以為未來與 Kotlin 相關的改進打下基礎,同時又與之前使用 Java 程式語言編寫的版本二進位制相容。這一版本還內建了對 Paging 3.0 的支援,通過使用 room-paging 元件,可以使 Room 返回 PagingSource 物件。除此之外,由於 Room 支援使用多重對映 (巢狀的 Map 和 Array) 進行關聯查詢,開發者現在可以使用 JOIN 查詢,而無需定義額外的資料結構。

@Query("SELECT * FROM Artist 
    JOIN Song ON Artist.artistName = 
    Song.songArtistName")
fun getArtistToSongs(): Map<Artist, List<Song>>

△ 使用多重對映作為返回值的關聯查詢方法

AutoMigrations 在更新中加入了對額外註解和屬性的支援,從而進一步簡化了資料庫遷移。其中,@Database 註解新加入了一個屬性,可以用於定義需要在哪兩個版本間進行自動遷移。而當 Room 需要一些額外資訊 (如表或列的修改資訊) 時,可以使用 @AutoMigration 註解指定輸入。

Database(
  version = MyDb.LATEST_VERSION,
  autoMigrations = {
    @AutoMigration(from = 1, to = 2,
      spec = MyDb.MyMigration.class),
    @AutoMigration(from = 2, to = 3)
  }
)
public abstract class MyDb
    extends RoomDatabase {
  ...

DataStore

DataStore 庫是一款健壯可靠的資料儲存解決方案,它解決了 SharedPreferences 所存在的問題。如果想要了解如何在各種 SharedPreferences 的應用場景中使用這一強大的替代方案,您可以檢視 MAD Skills: DataStore 系列文章和視訊,其中包含了如何測試應用中 DataStore 庫的使用情況、如何配合依賴注入使用 DataStore,以及如何從 SharedPreference 遷移至 Proto DataStore。

增量資料獲取

Paging 庫可以讓您載入和顯示整體資料中的一小部分,從而改善網路與系統資源的消耗。您可以配合 RecyclerViews 或 Compose lazy list 優雅地漸進載入應用資料。

Paging 3.1 為 Rx 和 Guava 整合提供了穩定支援,從而為 Paging 原生使用的 Kotlin 協程提供了 Java 版的替代方案。此版本還通過新的返回型別 LoadResult.Invalid 表示無效或過期的資料,從而改進了對無效競爭條件的處理。同時,該版本還通過新的 onPagesPresented 與 addOnPagesUpdatedListener API 改進了對無操作載入和操作空頁面的處理。

如需瞭解有關 Paging 3 的更多資訊,請參閱 Android 開發者網站中全新簡化版的教程: Paging Basics Codelab,它描述瞭如何在包含列表的應用中整合 Paging 庫。

定義應用內導航模型

Navigation 庫是用於在應用中的目的地之間進行移動的框架。

Navigation 元件現已通過 navigation-compose 元件整合到了 Jetpack Compose 中,從而允許可組合函式作為您應用中的目的地。

經過優化的 Multiple Back Stacks 功能,更便於 Navigation 元件記錄狀態。NavigationUI 現在可以自動儲存和恢復彈出目的地的狀態,這意味著開發人員無需改動任何程式碼即可支援多返回棧。

Navigation-fragment 元件進一步增強了對大螢幕裝置的支援,它在 AbstractListDetailFragment 中提供了一個預製的雙窗格佈局實現。這一 Fragment 使用 SlidingPaneLayout 管理一個列表窗格 (由您的子類管理),以及一個由 NavHostFragment 實現的詳情窗格。

所有的 Navigation 元件現已使用 Kotlin 重寫,並使用泛型改進了類的可空性,例如 NavType 的子類。

架構庫指南

針對我們的核心架構庫如何協同使用這一問題,如您想要了解更多資訊,可以觀看我們的視訊與 文章 合集,這其中涵蓋了現代 Android 開發最佳實踐系列內容——MAD Skills: 架構

2. 優化應用效能

通過使用效能庫,您可以構建高效能的應用,並作出針對性的優化以維持其效能表現,從而獲得更好的終端使用者體驗。

優化啟動時間

應用的啟動時間對使用者體驗影響巨大,特別是在應用安裝完成後立即使用時尤為明顯。為了提升首次啟動時的體驗,我們建立了 Baseline Profiles。Baseline Profiles 允許應用和庫向 Android 執行時提供有關程式碼路徑使用情況的後設資料,從而確定提前編譯的優先順序。這一配置檔案會對依賴庫的資料進行聚合,以 baseline.prof 檔案的形式放入應用的 APK 中,並且隨後會在安裝時用於實現應用的部分預編譯以及用於靜態連結庫程式碼中。這會使您的應用載入的更快,並且可以在使用者首次與應用互動時減少丟幀。

我們已經開始在 Google 內部使用 Baseline Profiles。Play Store 應用在接入 Baseline Profiles 後,搜尋結果頁初始頁面的渲染時間減少了 40%。為了給終端使用者提供更好的使用者體驗,一些流行的依賴庫也已經加入了 Baseline Profiles,例如 Fragment 和 Compose。如果想要建立您自己的基線配置檔案,您需要使用 Macrobenchmark 庫。

檢測您的應用

Macrobenchmark 庫可以通過將 Jetpack 基準測試的覆蓋範圍擴充套件至更為複雜的用例,來幫助開發者更好的瞭解應用效能。這其中包含了應用啟動及整合介面操作 (如滾動 RecyclerView 或執行動畫)。Macrobenchmark 也可用於生成 Baseline Profiles。

Macrobenchmark 已經更新以提高測試速度,同時也帶來了幾個新的實驗性功能。它現在還支援通過使用 TraceSectionMetric 進行基於自定義跟蹤的時序測量,從而允許開發者針對特定的程式碼部分進行基準測試。此外,AudioUnderrunMetric 現在可以檢測音訊快取欠載,以幫助開發者瞭解音訊卡頓的情況。

BaselineProfileRule 可以生成配置檔案來幫助進行執行時優化。它的工作方式與其他巨集基準測試類似,您只需通過 lambda 程式碼表示使用者操作即可。在下面的示例中,編譯器應該提前優化的關鍵使用者場景是冷啟動: 從啟動器開啟應用的啟動 Activity。

@ExperimentalBaselineProfilesApi
@RunWith(AndroidJUnit4::class)
class BaselineProfileGenerator {
  @get:Rule
  val baselineProfileRule = BaselineProfileRule()

  @Test
  fun startup() = baselineProfileRule.collectBaselineProfile(
    packageName = "com.example.app"
  ) {
    pressHome()

    // 這一程式碼塊定義了應用的關鍵使用者場景。這裡我們所關注的是應用啟動的優化,但您
    // 也可以進行導航和滾動瀏覽您最重要的介面。
    startActivityAndWait()
  }
}

如需瞭解更多關於通過 Macrobenchmark 生成和使用基準配置檔案的詳細資訊和完整指南,請參閱 Android 開發者的指南文件——基準配置檔案

避免介面卡頓

全新的 JankStats 庫可以幫您追蹤和分析應用介面的效能問題,其中包括報告丟失渲染幀——通常被稱為 "卡頓 (jank)"。JankStats 建立在現有 Android 平臺 API (例如 FrameMetrics) 之上,但最低可以用於 API Level 16。

JankStats 還提供了超越平臺內建功能的其他能力: 幫助定位丟幀原因的啟發式演算法、在報告中提供了額外上下文的介面狀態,以及可以用於上傳資料以進行分析的報告回撥。

下面我們詳細說說 JankStats 的三個主要功能:

  1. 識別卡頓 : JankStats 使用內建的啟發式演算法確定卡頓發生的時機,並使用該資訊得知何時釋出卡頓報告,從而使開發者可以獲得有關這些問題的資訊,以幫助分析和修復問題。
  2. 提供介面上下文 : 為了提高卡頓報告的可利用性和可操作性,JankStats 提供了一個幫助追蹤當前介面和使用者狀態的機制。每當記錄報告時,都會提供相應的資訊,這樣不但可以幫助開發者瞭解問題是何時發生的,更可以瞭解到使用者當時在做什麼。這有助於確定應用中存在問題的區域,以便稍後進行解決。這其中一些狀態是由一些 Jetpack 庫自動提供的,但我們也鼓勵開發者提供自己應用特定的狀態。
  3. 報告結果 : 在每一幀中,JankStats 客戶端都會通過監聽器收到包含該幀相關資訊的通知,包括幀完成所用的時間、是否被視為卡頓,以及該幀顯示期間的介面上下文是什麼。我們鼓勵客戶端聚合和上傳適合分析的資料,以幫助和除錯整體效能問題。

在您的應用中新增日誌

Tracing 庫通過將跟蹤事件寫入系統緩衝區來啟用應用效能分析。Tracing 1.1 支援對低至 API Level 14 的應用的非除錯構建進行分析,類似於在 API Level 29 中加入的 <profileable> 清單檔案標記。

3. 介面庫及指南

我們對介面庫進行了一些更改,以更好地支援大螢幕相容性、可摺疊裝置和 Emoji。

Jetpack Compose

Jetpack Compose 是 Android 用於構建原生介面的現代工具,如今已更新至 1.2 beta 版。新版本新增了一些用於支援先進用例的功能,包括支援可下載字型、惰性佈局及巢狀滾動互操作性。更多資訊請參閱文章: 一起看 I/O | Jetpack Compose 中的新特性

瞭解視窗狀態

新的 WindowManager 庫通過提供一個支援低至 API Level 14 的通用 API 介面,幫助開發人員適配他們的應用支援多視窗環境和新的裝置形態。

最初的版本針對可摺疊裝置的用例,包括查詢影響內容顯示方式的物理屬性。

Jetpack 的 SlidingPaneLayout 元件已更新為使用 WindowManager 的智慧佈局 API,以避免內容被放置於被遮擋區域 (例如跨越物理鉸鏈區域)。

拖放

新的 DragAndDrop 通過讓開發者接收來自應用內外的拖放資料,來幫助在新的外形和視窗模式下實現功能。DrapAndDrop 包含了一致的放置目標功能,它最低支援 API Level 24:

移植新 API 到舊的 API Level

AppCompat 庫可以讓我們在舊平臺 API 版本下訪問新的 API,包含一些介面功能移植,如暗色模式。

AppCompat 1.4 整合了 Emoji2 庫,從而為 API Level 14 及以上版本、AppCompat 中支援的所有基於文字的檢視帶來了對新 Emoji 的預設支援。

自定義區域選擇 目前已支援低至 API Level 14。該功能支援跨應用手動持久化區域設定,並且可以通過 Service 的 metadata 標籤支援自動持久化。它可以告訴庫同步載入區域並根據需要重建任何正在執行的 Activity。在 API Level 33 及以上,持久化是由平臺管理的,無需額外開銷。

其他關鍵更新

Annotation

Annotation 庫公開了後設資料,從而幫助工具和其他開發者理解應用的程式碼。它提供了一些我們耳熟能詳的註解,如 @NonNull。這些註解與 lint 檢查配對,可以提高程式碼的正確性和可用性。

Annotation 正遷移至 Kotlin,所以正使用 Kotlin 的開發者會看到更合適的註解目標,包括 @file。

一些呼聲很高的註解已隨其相應的 lint 檢查新增了進來。其中包括了有關方法或函式重寫的註解,以及 @DeprecatedSinceApi 註解。後者作為 @RequiresApi 的必然結果,可以阻止在某個 API 級別之上進行使用。

在 Github 上為 Jetpack 程式碼倉庫做貢獻

我們目前在 GitHub 上已有超過 100 個專案

開發者可以向下列專案貢獻程式碼,它們均基於 Github 的標準流程:

  • Activity
  • AppCompat
  • Biometric
  • Collection
  • Compose Compiler
  • Compose Runtime
  • Core
  • DataStore
  • Fragment
  • Lifecycle
  • Navigation
  • Paging
  • Room
  • WorkManager

檢視 專案主頁 可獲得更多內容,包括我們如何處理拉取請求,以及如何開始使用 Jetpack 構建應用。

以上就是對過去幾個月 Jetpack 所有變更的簡要介紹。更多有關每個 Jetpack 庫的資訊,請參閱以下資料:

歡迎您 點選這裡 向我們提交反饋,或分享您喜歡的內容、發現的問題。您的反饋對我們非常重要,感謝您的支援!

*Java 是 Oracle 和/或其附屬公司的商標或註冊商標

相關文章