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

作者 / 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 和/或其附屬公司的商標或註冊商標

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章