相容性架構工具

Android 11 導入了新的開發人員工具,可針對新版 Android 平台中的行為變化進行測試及偵錯。這些工具是「相容性架構」的一部分,可讓應用程式開發人員使用開發人員選項或 ADB,個別開啟或關閉破壞性變更。當您要鎖定最新的穩定 API 版本,以及使用下一個 Android 版本的預覽版本測試應用程式時,都能利用此彈性。

使用相容性架構工具時,Android 平台會自動調整其內部邏輯,因此您無須變更 targetSDKVersion,或重新編譯應用程式,以執行基本測試。由於可個別切換變更,因此您可一次隔離、測試及偵錯一項行為變更,或者,如果需要先測試其他項目,也可以先停用造成問題的單一變更。

如何識別已啟用的變更

啟用行為變更時,可能會影響應用程式存取受該變更影響的平台 API。您可以透過開發人員選項、logcat 或 ADB 指令,查看目前啟用的行為變更。

使用開發人員選項來識別啟用的變更

圖 1. 開發人員選項中的「應用程式相容性變更」畫面。

您可在裝置的開發人員選項中,查看目前啟用的變更,以及開啟或關閉這些變更。若要存取這些選項,請依下列步驟操作:

  1. 如果開發人員選項尚未啟用,請啟用
  2. 開啟裝置的「設定」應用程式,並依序前往「System」(系統) >「Advanced」(進階) >「Developer options」(開發人員選項) >「App Compatibility Changes」(應用程式相容性變更)
  3. 從清單中選取您的應用程式。

每個行為變更通常都會歸入下列兩個類別之一:

  • 影響在該 Android 版本上執行的所有應用程式的變更,無論應用程式的 targetSdkVersion 為何。

    在相容性架構中,這些變更預設為啟用,並列在 UI 的「預設啟用變更」部分中。

  • 只會影響適用於特定 Android 版本的應用程式的變更。由於這些變更只會影響適用於特定 Android 版本的應用程式,因此也稱為受 targetSDKVersion「管制」的變更。

    如果應用程式適用的版本高於列出的 API 版本,這些變更會在相容性架構中預設為啟用。例如,在 Android 11 (API 級別 30) 中受 targetSDKVersion 管制的行為變更,會列在 UI 的「在 SDK 29 之後啟用」部分 (有時會顯示為「在 targetSdkVersion >=30 啟用」)。

您也會在圖 1 中發現稱為「預設停用變更」的部分。此部分中的變更具有許多用途。啟用這些變更之前,請參閱該 Android 版本的相容性架構清單中對該變更的說明。

使用 logcat 來識別已啟用的變更

對於每個行為變更,在應用程式第一次呼叫受影響的 API 時,系統都會輸出如下所示的 logcat 訊息:

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

每個 logcat 訊息都包含下列資訊:

變更 ID
指出哪些變更會影響應用程式。這個值對應至「應用程式相容性變更」畫面中列出的其中一個行為變更 (請參閱圖 1)。在此範例中,119147584 對應至 CALLBACK_ON_CLEAR_CHANGE
UID
指出受到這個變更影響的應用程式。
狀態

指出變更是否正在影響應用程式。

狀態可為下列其中一個值:

狀態 意義
ENABLED 變更目前已啟用,如果應用程式使用已變更的 API,就會影響應用程式的行為。
DISABLED

變更目前已停用,不會影響應用程式。

注意:如果因為應用程式的 targetSDKVersion 低於規定門檻導致這個變更已停用,當應用程式提高其 targetSDKVersion 以適用更高版本時,變更會預設為啟用。

LOGGED 透過相容性架構記錄變更,但無法開啟或關閉變更。雖然無法切換這個變更,但仍可能影響應用程式的行為。詳情請參閱該 Android 版本的相容性架構清單中對該變更的說明。在許多情況下,這類變更屬於實驗性質,可能會被忽略。

使用 ADB 來識別已啟用的變更

執行下列 ADB 指令,查看整個裝置的完整變更 (包括啟用和停用)。

adb shell dumpsys platform_compat

輸出結果會列出每個變更的下列資訊:

變更 ID
此行為變更的專屬 ID。例如 119147584
名稱
此行為變更的名稱。例如 CALLBACK_ON_CLEAR_CHANGE
targetSDKVersion 條件

變更受到哪個 targetSDKVersion 管制 (若有)。

例如,如果僅針對適用於 SDK 30 以上版本的應用程式啟用這個變更,就會輸出 enableAfterTargetSdk=29。如果變更不受 targetSDKVersion 管制,就會輸出 enableAfterTargetSdk=0

套件覆寫

變更的預設狀態 (已啟用或已停用) 已遭到覆寫的每個套件的名稱。

例如,如果這是預設為啟用的變更,那麼在您使用開發人員選項或 ADB 關閉變更後,將列出應用程式的套件名稱。在此情況下,輸出結果會是:

packageOverrides={com.my.package=false}

依預設,受 targetSDKVersion 管制的變更可為啟用或停用,因此,根據個別應用程式的 targetSDKVersion,套件清單可能包含 truefalse 的執行個體。例如:

packageOverrides={com.my.package=true, com.another.package=false}

進一步瞭解特定變更

相容性架構的完整行為變更清單已包含在各個 Android 版本的說明文件中。如需詳細資訊,根據用於測試應用程式的 Android 版本,請參閱下列連結:

切換變更的時機

相容性架構的主要用途,在於讓您在使用新版 Android 測試應用程式時,享有控制權和彈性。本節說明一些參考策略,供您在測試及偵錯應用程式時,用來判斷何時開啟或關閉變更。

關閉變更的時機

決定變更關閉的時機,通常取決於變更是否受 targetSDKVersion 管制。

對所有應用程式啟用的變更

無論應用程式的 targetSDKVersion 為何,任何特定平台上預設為啟用且影響所有應用程式的變更,因此您能以該平台版本執行應用程式,藉此查看應用程式是否受到影響。

例如,如果您準備鎖定 12L (API 級別 32),可先在搭載 12L 的裝置上安裝應用程式,然後利用一般測試工作流程測試應用程式。如果您的應用程式發生問題,可停用造成該問題的變更,以便繼續測試其他問題。

由於無論 targetSDKVersion 為何,這些變更都可能會影響所有應用程式,因此在 targetSDKVersion 管制變更之前,通常應先針對這些變更測試並更新應用程式。這有助於確保使用者將裝置更新至新的平台版本時,應用程式體驗不會有所下降。

另外,您也應優先測試這些變更,因為使用 Android 的公開發布子版本時,無法關閉這些變更。在理想情況下,「在該版本處於預覽狀態時」,您應針對每個 Android 版本測試這些變更。

targetSDKVersion 管制的變更

如果應用程式適用於特定 targetSDKVersion,則受該版本管制的所有變更都會預設為啟用。因此,如果您將應用程式的 targetSDKVersion 切換為新版本,應用程式也會立即受到許多新變更的影響。

由於應用程式可能會受到一個以上的變更影響,因此在測試及偵錯應用程式時,您可能需要個別關閉其中的部分變更。

開啟變更的時機

每當應用程式適用的 SDK 版本低於受管制的版本時,受特定 targetSDKVersion 管制的變更會預設為停用。一般而言,當您準備鎖定新的 targetSdkVersion 時,將會提供行為變更清單,您必須據此測試並偵錯應用程式。

例如,您可能會根據下一個 targetSdkVersion 中的一系列平台變更,測試應用程式。使用開發人員選項或 ADB 指令,您可以逐一啟用並測試每個受管制的變更,而不必變更應用程式資訊清單,並立即選擇採納每個變更。這個額外控制項可協助您獨立測試變更,並避免立即偵錯及更新應用程式的多個部分。

啟用變更後,您可以透過一般測試工作流程,測試並偵錯應用程式。如果發生問題,請查看記錄,以判定問題原因。如果無法確認問題是否起因於已啟用的平台變更,請嘗試停用該變更,然後重新測試應用程式的該區域。

開啟或關閉變更

透過相容性架構,可使用開發人員選項或 ADB 指令開啟或關閉每個變更。由於開啟或關閉變更後,會導致應用程式停止運作或停用重要的安全性變更,因此可切換變更時有些限制

使用開發人員選項切換變更

使用開發人員選項來開啟或關閉變更。若要尋找開發人員選項,請依下列步驟操作:

  1. 如果開發人員選項尚未啟用,請啟用
  2. 開啟裝置的「設定」應用程式,並依序前往「System」(系統) >「Advanced」(進階) >「Developer options」(開發人員選項) >「App Compatibility Changes」(應用程式相容性變更)
  3. 從清單中選取您的應用程式。
  4. 在變更清單中,找到要開啟或關閉的變更,然後輕觸切換按鈕。

    可開啟或關閉的變更清單

使用 ADB 切換變更

若要使用 ADB 開啟或關閉變更,請執行下列任一指令:

adb shell am compat enable (CHANGE_ID|CHANGE_NAME) PACKAGE_NAME
adb shell am compat disable (CHANGE_ID|CHANGE_NAME) PACKAGE_NAME

請傳遞 CHANGE_ID (例如 119147584) 或 CHANGE_NAME (例如 CALLBACK_ON_CLEAR_CHANGE),以及應用程式的 PACKAGE_NAME

您也可以使用下列指令,將變更重設為預設狀態,移除您使用 ADB 或開發人員選項進行的所有覆寫作業:

adb shell am compat reset (CHANGE_ID|CHANGE_NAME) PACKAGE_NAME

切換變更的相關限制

每個行為變化都預設為啟用或停用。影響所有應用程式的變更會預設為啟用。其他變更則受 targetSdkVersion 管制。如果應用程式適用於對應 SDK 以上版本,這些變更會預設為啟用。如果應用程式適用的 SDK 版本低於受管制版本,這些變更則會預設為停用。開啟或關閉變更時,將會覆寫其預設狀態。

為避免相容性架構遭到濫用,切換變更時有些限制。至於您能否切換變更,則取決於變更的類型、應用程式是否可進行偵錯,以及裝置上執行的版本類型。下表說明何時可以切換不同類型的變更:

版本類型 不可進行偵錯的應用程式 可進行偵錯的應用程式
所有變更 受 targetSDKVersion 管制的變更 所有其他變更
開發人員預覽版或 Beta 版 無法切換 可切換 可切換
公開使用者版本 無法切換 可切換 無法切換