新版本系統適配: Android 12 中的相容性變更

Android開發者發表於2022-01-17

隨著 Android 12 正式版 的釋出,越來越多的使用者將升級至最新版本。Android 12 帶來大量新 API 和功能更新的同時也帶來了平臺相容性的變更,我們建議開發者優先對當前應用進行測試,並進行相容性更新。這樣一來,當使用者將裝置更新至 Android 12 時,可確保其擁有良好的體驗。

本文將重點介紹 Android 12 中最大的相容性變更,並分享有關如何讓使用者順利過渡到最新版本系統的一些建議。此外,我們還會分享一些來自領先應用的案例和建議,以幫助您瞭解其他開發者如何充分利用 Android 12 的功能,以及如何借鑑到自己的應用中。

如果您更喜歡通過視訊瞭解此內容,請在此處檢視:

https://www.bilibili.com/vide...

△ 新版本系統適配: Android 12 中的相容性變更

Android 12 中的變更

相容性變更主要分為兩類,一類預設影響所有執行的應用,另一類則只基於應用已宣告的目標 SDK 級別對其產生影響。方便起見,本文將在變更標題中加以備註以幫助您更好地瞭解對應變更內容對您應用的影響。

Android 12 採用全新的個性化 Material Design 實現了跨越式的視覺更新。我們一直致力於簡化和完善現有體驗並幫助您構建美觀、安全和高效能的應用來滿足使用者需求。為此,我們專注於使用者介面、效能和隱私三大方面進行優化。本文中將主要介紹 Android 12 在使用者介面和效能方面的變更。

使用者介面相關的變更

應用開屏頁 (影響所有應用)

從 Android 12 開始,系統會在冷啟動和暖啟動應用時都使用新的預設開屏頁。該開屏頁由應用的啟動圖示和主題的 windowBackground 組成,並在啟動時展現順滑、流暢的過渡動畫。

△ Android 12 中的預設開屏頁

△ Android 12 中的預設開屏頁

這種全新的體驗適用於所有執行在 Android 12 上的應用。如果您的應用實現了自定義開屏頁,則需要遷移到新的 SplashScreen API。我們建議使用 Jetpack 的 SplashScreen 庫來實現向後相容性,以在所有 Android 版本中提供一致的觀感。

由於新開屏頁可完全自定義,因此,即使您現有的開屏頁用於路由,我們也建議將其完全移除。這樣將避免開屏頁重複,而且能減少載入時間。

如需瞭解詳細的適配流程,請查閱 Android 開發者網站的 遷移指南

自定義通知 (僅影響 targetSdkVersion 為 31 的應用)

Android 12 更改了完全自定義通知的外觀和行為,使其在視覺上保持一致且易於瀏覽,併為使用者提供可檢測到的、熟悉的通知展開狀態。

△ Android 12 的通知樣式

△ Android 12 的通知樣式

在之前,自定義通知能使用整個通知區域,並能提供自己的佈局和樣式。對於面向 Android 12 的應用,帶有自定義內容檢視的通知將不再使用整個通知區域,系統改而使用標準模板。

△ Android 12 之前和之後自定義通知可使用的區域對比

△ Android 12 之前和之後自定義通知可使用的區域對比

該模板確保自定義通知在所有狀態下的裝飾與其他通知相同,例如圖示、應用名、展開和收起狀態標識。該變更會影響使用自定義 Notification.Style 子類或使用 Notification.Builder 方法設定自定義內容檢視的應用。如果您的應用正在使用完全自定義通知,請務必測試這類通知是否能夠相容新模板。

△ 受影響的自定義內容檢視的 API

△ 受影響的自定義內容檢視的 API

沉浸式模式下的手勢導航 (影響所有應用)

Android 12 還整合了現有行為,讓使用者在沉浸模式下更輕鬆地執行手勢導航命令。即使處於沉浸式模式下,系統手勢也會立即響應。BEHAVIOR_SHOW_BARS_BY_TOUCH 和 BEHAVIOR_SHOW_BARS_BY_SWIPE 這兩種行為現已棄用,被新的 BEHAVIOR_DEFAULT 行為所取代。BEHAVIOR_DEFAULT 行為讓使用者只需滑動一次即可執行手勢導航,而在 Android 11 上則需要滑動兩次。即使是開發全屏遊戲的體驗,仍可在沉浸模式下通過使用 BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE 標記來防止使用者受到誤觸手勢的影響。

△ Android 12 中沉浸式模式下的手勢導航

△ Android 12 中沉浸式模式下的手勢導航

效能相關的變更

前臺服務 (僅影響 targetSdkVersion 為 31 的應用)

前臺服務能讓 Android 系統確保資源優先用於完成使用者發起的耗時任務,但它經常被濫用。我們發現幾乎一半的前臺服務是從後臺啟動的,這導致了許多問題,包括電量會被迅速耗盡,以及使用者會被意外的前臺服務通知困擾等。因此從 Android 12 開始,將禁止從後臺啟動前臺服務,並對啟動前臺服務作了限制。以下情況可啟動前臺服務:

  • 可見的 Activity 或視窗
  • 使用者操作,如通知、小部件等等
  • 特定的廣播和回撥
  • STICKY 型別的服務可在崩潰或由於低記憶體而停止執行的情況下重啟

有關前臺服務啟動限制的完整豁免列表,請查閱 Android 開發者網站—— 前臺服務

今年早些時候,我們在 Jetpack 的 WorkManager 庫中引入了加急任務。這些低延遲任務可從前臺或後臺呼叫並會立即執行。這些任務可在低電量模式下執行。我們鼓勵開發者儘可能使用這些任務來替代啟動前臺服務。

精確鬧鐘許可權 (僅影響 targetSdkVersion 為 31 的應用)

在大多數情況下,應用應使用粗精確度鬧鐘,其優勢在於省電。在鬧鐘和計時器等特殊情況下,可使用精確鬧鐘。Android 12 新增了一項清單許可權——SCHEDULE_EXACT_ALARM,使用者可檢視並控制擁有此許可權的應用。此外,還新增了一個新的 API —— canScheduleExactAlarms(),您可使用此 API 來檢查應用的許可權狀態。

通知 trampoline (Notification trampolines,僅影響 targetSdkVersion 為 31 的應用)

一些應用在處理使用者點選通知的行為時,會使用廣播接收器或服務等中間元件,這些元件被稱為通知 trampoline,它們常常導致延遲和使用者流程中斷,面向 Android 12 的應用將不能從這些蹦床啟動 Activity。這一新限制有助於減少從通知啟動應用的延遲。我們鼓勵棄用通知 trampoline 並直接從通知啟動目標 Activity。舉個例子,在棄用通知 trampoline 後,Google 相簿應用的啟動速度提高了 34%。如果您的應用使用了通知 trampoline,請使用以下 adb 命令檢視使用者與通知互動時所啟動的元件:

$ adb shell dumpsys activity service \ 
com.android.systemui/.dump.SystemUIAuxiliaryDumpService

△ 使用該命令檢視使用者與通知互動時所啟動的元件

應用連結 (僅影響 targetSdkVersion 為 31 的應用)

Android 支援應用連結的概念,它可以讓 HTTP 網址直接連結到已安裝的應用。這樣便可完全繞過消歧對話方塊,通過消除使用者使用過程中的分歧來改善使用者體驗。應用連結與深層連結的區別在於應用連結只能處理 HTTP 模式,而深層連結可以處理任何模式。

不同於以前的版本,Android 12 將始終為未驗證的連結開啟預設瀏覽器。這可能是應用連結在行為方面最重要的變更。Android 12 還引入了逐條連結驗證,因此,如果存在任何伺服器端整合或配置錯誤,將僅限於未通過驗證的連結,您可以使用新 DomainVerificationManager API 檢查域名驗證狀態,並在需要時將使用者帶到「設定」以便批准應用使用的域名。如需瞭解詳情,請參閱 Android 開發者網站—— 驗證 Android 應用連結

△ 使用應用連結繞過消歧對話方塊直達已安裝應用

△ 使用應用連結繞過消歧對話方塊直達已安裝應用

相容性框架工具

現在我們已瞭解 Android 12 中的新功能和變更,下面我們來看看讓應用相容的測試和工具。在 Android 11 中我們引入了相容性框架工具以便針對變更更輕鬆地測試和除錯應用。有了這些工具您可以單獨開啟和關閉某個重大變更並評估其對應用的影響。通過這種方式,您可以一次只針對一項行為變更進行隔離和測試,或輕鬆啟用 targetSDK 對應的變更。

△ 開發者選項 > 應用相容性變更

△ 開發者選項 > 應用相容性變更

您可以使用開發者選項、logcat 或 adb 命令來檢查當前啟用的行為變更。對於每項行為變更,當應用首次呼叫受影響的 API 時,系統會輸出一條類似這樣的 logcat 訊息:

D CompatibilityChangeReporter: Compat change id reported: 170668199 ;
UID 10265; state: ENABLED

△ Logcat 為某項變更的輸出示例

您可以使用以下 adb 命令列出系統已知的所有相容性變更 (包括已啟用和禁用的變更) 及其當前的啟用情況。列表中的每項變更都有名稱、供引用的變更 ID 和啟用/禁用狀態。

$ adb shell dumpsys platform-compat

△ 使用 adb 命令列出系統已知的所有相容性變更

還可以使用以下 adb 命令開啟或關閉某個軟體包的變更:

$ adb shell am compat enable|disable|reset <CHANGE_ID | CHANGE_NAME> <PACKAGE_NAME>

△ 使用 adb 命令設定單個應用的變更

在基本測試中無需更改 targetSdkVersion 或重新編譯應用,Android 平臺會自動調整其內部邏輯。由於可單獨開啟或關閉變更,因此可逐一進行隔離測試、除錯行為變更,或禁用導致問題的單項變更。

請注意,由於只能開啟或關閉可除錯應用的變更。因此,如果在相容性框架中未看到您的應用請確保在清單中將應用設定為可除錯:

<application
    android:debuggable="true">

△ 在清單檔案中將應用設定為可除錯

請記住在已簽名的 Android 釋出版本上,無法修改影響所有應用的變更的啟用狀態。Android 12 新增了新的 adb 命令來測試和驗證應用的應用連結。您可使用這些命令在裝置上手動驗證連結,或將其新增到持續整合工具鏈中。

// 清除應用任何已經驗證的狀態:
$ adb shell pm set-app-links --package PACKAGE_NAME 0 all
 
// 開始驗證測試:
$ adb shell pm verify-app-links --re-verify PACKAGE_NAME
 
// 檢視測試結果:
$ adb shell pm get-app-links PACKAGE_NAME

△ 在 Android 12 中使用這些 adb 命令測試應用連結

請務必嘗試使用 Android Studio Arctic Fox 進行開發和測試。我們已新增 lint 檢查來幫助您發現程式碼可能受 Android 12 變更影響的地方。例如自定義開屏頁、針對精確位置使用的粗略位置許可權、媒體格式等。當然,首先要做的就是設定 Android 12 SDK。

開發者案例

現在我們將展示一些開發者已經適配 Android 12 的成功案例。由於適配了 Android 12,他們的使用者便可以充分利用這種新體驗。

附近裝置許可權 (僅影響 targetSdkVersion 為 31 的應用)

Withings 的 HealthMate 應用讓使用者能通過藍芽連線和同步 Withings 的裝置。Android 12 引入了一項新許可權將藍芽掃描與位置許可權分離。

△ HealthMate 應用申請附近裝置許可權

△ HealthMate 應用申請附近裝置許可權

對我們而言,附近裝置許可權是 Android 12 中最重要的變更之一。

Withings HealthMate

在隱私層面上,很難向終端使用者解釋位置許可權與藍芽的關係。有好幾年,Withings 的團隊不得不在客戶服務主題和教程方面投入成本,以便使用者瞭解應用需要位置許可權才能掃描藍芽的原因。即使做了充分的解釋,該團隊也因申請位置許可權而收到了負面反饋。

相比之下,附近裝置許可權更有效。因為它只在掃描和連線時要求許可權。Withings 的工程師提出了一些建議:

  • 將檢查和申請新許可權的邏輯進行抽象。這有助於控制入口點並儘可能減少測試工作;
  • 在所有受支援的 Android 版本上對所有許可權檢查進行單元測試;
  • 使用 Android 真機並測試不同的升級場景以確保應用正常執行;
  • 如果應用在之前的 Android 版本上獲得了位置許可權,當使用者升級到 Android 12 時,該應用將自動被授予附近裝置許可權。

要使用新的附近裝置許可權,必須在清單檔案中宣告 BLUETOOTH_SCAN 許可權:

<uses-permission
    android:name="android.permission.BLUETOOTH_SCAN"
    android:usesPermissionFlags="neverForLocation" />

△ 掃描附近裝置時應在清單檔案中宣告許可權

這是一項執行時許可權,除了在清單中宣告外,應用還必須在開始掃描裝置之前,在執行時檢查並申請此許可權。您可以通過將 usesPermissionFlags 屬性宣告為 neverForLocation,來表明不打算使用掃描結果獲取使用者位置。

如果只需要連線到裝置,則可以宣告 BLUETOOTH_CONNECT 許可權:

<uses-permission
    android:name="android.permission.BLUETOOTH_CONNECT" />

△ 連線裝置時應在清單檔案中宣告許可權

過度滾動效果 (Overscroll Effect,影響所有應用)

在 Android 12 上大多數應用都會有一種新的過度滾動拉伸效果。一些使用 Android 12 的 Beta 使用者在 Signal 應用中滾動瀏覽訊息時,注意到了一種奇怪的效果:

△ Signal 應用中的奇怪效果

△ Signal 應用中的奇怪效果

在 Signal 的案例中,應用支援自定義背景。該應用使用了一種可穿透介面層級的掩蔽演算法,每當佈局或滾動內容時,Signal 應用都會在螢幕上建立一個訊息氣泡投影列表,然後應用將使用這些投影建立一個蒙版,並將其應用於給定的漸變色或純色。

工程團隊很快想出了一個利用 RecyclerView.ItemDecoration 的解決方案。儘早修復過度滾動問題可讓 Signal 應用在新版裝置上提供使用者期望的體驗而不影響效能。

△ Signal 修復過度滾動問題後的效果

△ Signal 修復過度滾動問題後的效果

我們為 Android 12 正式版及時修復了過度滾動的問題併為使用者提供了統一的體驗。

Signal Private Messenger

Signal 團隊提出了一些建議:

  • 注意混合模式及其作為附加層的工作原理。Android 12 過度滾動使用附加層來渲染拉伸效果,這可通過不同混合演算法生成不同的結果;
  • 確保背景由 RecyclerView 渲染;
  • 在釋出之前,執行一次全面質量檢查,並解決使用者對 Android 12 相容性的反饋。

Signal 應用是提供愉悅使用者體驗的一個範例。幸運的是,Android 版 Signal Private Messenger 為開源軟體,您可在 GitHub 上檢視其修復程式碼。

總結

在本文中,我們介紹了 Android 12 給開發者及使用者帶來的最重要的幾項變更,並提出部分建議:

  • Android 12 帶來了明顯的視覺更新
  • 使用已提供的工具和建議來測試您的應用
  • 從其他開發者處獲得啟發

更多變更相關內容,請參閱 Android 開發者網站——Android 12

最重要的一點,記得測試您的應用並確認其與 Android 12 的相容性。許多開發者已完成此任務,現在是時候為這些變更做好準備並提供出色的使用者體驗。我們期待在 Android 12 上看到您的應用。

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

相關文章