AAPT2

AAPT2 (Android 資產封裝工具) 是 Android Studio 和 Android Gradle 外掛程式用來編譯及封裝應用程式資源的一項建構工具。AAPT2 會剖析資源、建立索引,並將資源編譯為適用於 Android 平台的二進位格式。

Android Gradle 外掛程式 3.0.0 以上版本預設會啟用 AAPT2。您通常不需要自行叫用 aapt2。不過,如果您想要使用終端機和自己的建構系統,而不是 Android Studio,則可透過指令列使用 AAPT2。您也可以透過指令列,針對與 AAPT2 相關的建構錯誤進行偵錯。方法很簡單,在 Android SDK Build Tools 26.0.2 以上版本中,找出 AAPT2 這個獨立工具。

如要從指令列下載 Android SDK Build Tools,請使用 sdkmanager 並執行以下指令:

sdkmanager "build-tools;build-tools-version"

下載 SDK Build Tools 後,在 android_sdk/build-tools/version/ 中可以找到 AAPT2。

由於 Android SDK Build Tools 的修訂版本不會經常發布,因此您 SDK Build Tools 中的 AAPT2 可能不是最新版。如要取得最新版的 AAPT2,請參閱「前往 Google Maven 下載 AAPT2」。

如要透過 Linux 或 Mac 指令列使用 AAPT2,請執行 aapt2 指令。在 Windows 上執行 aapt2.exe 指令。

AAPT2 可讓您啟用漸進式編譯功能,讓資源編譯速度更快。為了完成漸進式編譯,資源處理會分為兩個步驟:

  • 編譯:將資源檔案編譯為二進位格式。
  • 連結:將所有已編譯的檔案與套件合併成一個套件。

這種劃分有助提升漸進式建構的效能。舉例來說,如果單一檔案發生變更,您只需要重新編譯該檔案。

前往 Google Maven 下載 AAPT2

如要取得建構工具中未搭售的最新版 AAPT2,可以從 Google Maven 存放區下載 AAPT2,方法如下:

  1. 存放區索引中,前往 com.android.tools.build > aapt2
  2. 複製最新版 AAPT2 的名稱。
  3. 請將您複製的版本名稱貼到以下網址中,並指定目標作業系統:https://dl.google.com/dl/android/maven2/com/android/tools/build/aapt2/aapt2-version/aapt2-aapt2-version- [windows | linux | osx].jar

    例如,如要下載 Windows 3.2.0-alpha18-4804415 版本,請使用以下這個檔案:https://dl.google.com/dl/android/maven2/com/android/tools/build/aapt2/3.2.0-alpha18-4804415/aapt2-3.2.0-alpha18-4804415-windows.jar

  4. 在瀏覽器中前往該網址。即將開始下載 AAPT2。

  5. 解壓縮您剛下載的 JAR 檔案。

    JAR 檔案應包含 aapt2 執行檔,以及執行檔需要的程式庫。

編譯

AAPT2 支援所有 Android 資源類型的編譯作業,例如可繪項目和 XML 檔案。叫用 AAPT2 編譯時,請將單一資源檔案當成每次叫用的輸入內容傳遞。AAPT2 會剖析檔案,並產生副檔名為 .flat 的中繼二進位檔案。

傳遞完整目錄時,AAPT2 會重新編譯目錄中的所有檔案,即使只有一項資源變更也一樣。雖然您可以使用 --dir 旗標,將包含多個資源檔案的資源目錄傳遞給 AAPT2,但這種做法並不會讓您取得增量資源編譯的優勢。

視您提供編譯的輸入內容而定,輸出檔案類型可能不同,如下表所示:

表 1. 編譯的輸入和輸出檔案類型。

輸入 輸出
XML 資源檔案,例如位於 res/values/ 目錄中的 StringStyle *.arsc.flat 為副檔名的資源資料表。
所有其他資源檔案。

除了 res/values/ 目錄下的檔案,系統會將所有檔案轉換為含 *.flat 副檔名的二進位 XML 檔案。

此外,所有 PNG 檔案都會根據預設壓縮處理,並採用 *.png.flat 副檔名。如果您選擇不壓縮 PNG 檔案,可以在編譯期間使用 --no-crunch 選項。

AAPT2 輸出的檔案不是執行檔,因此您必須在之後的連結階段加入這些二進位檔案才能產生 APK。不過,產生的 APK 檔案並非可立即部署於 Android 裝置上的執行檔,因為該檔案並未包含 DEX 檔案且未經簽署。

編譯語法

使用 compile 的一般語法如下:

aapt2 compile path-to-input-files [options] -o output-directory/

在下列範例中,AAPT2 會個別編譯名為 values.xmlmyImage.png 的資源檔案:

aapt2 compile project_root/module_root/src/main/res/values-en/strings.xml -o compiled/
aapt2 compile project_root/module_root/src/main/res/drawable/myImage.png -o compiled/

如表 1 所示,輸出檔案的名稱取決於輸入檔案名稱及其父項目錄的名稱。

以上述 strings.xml 檔案做為輸入範例,aapt2 會自動將輸出檔案命名為 values-en_strings.arsc.flat。但如果是儲存在可繪項目目錄中的已編譯可繪項目檔案,名稱會是 drawable_img.png.flat

編譯選項

您可以透過 compile 指令使用多個選項,如表 2 所示:

表 2. 編譯指令選項

選項 說明
-o path

指定已編譯資源的輸出路徑。

此為必填旗標,因為您必須指定目錄路徑,讓 AAPT2 能夠輸出並儲存已編譯的資源。

--dir directory

指定要掃描資源的目錄。

雖然您可以透過單一指另使用此旗標來編譯多個資源檔案,但也會失去漸進式編譯的優勢。因此,這個旗標不應用於大型專案。

--pseudo-localize 產生預設字串的 pseudolocalized 版本,例如 en-XAen-XB
--no-crunch 停用 PNG 處理功能。

如果您已處理 PNG 檔案,或者您正在建立不需縮減檔案大小的偵錯版本,請使用這個選項。啟用這個選項可提升執行速度,但會增加輸出檔案大小。

--legacy 使用舊版的 AAPT 時,系統會將允許的錯誤視為警告。

這個旗標應用於非預期的編譯時間錯誤。如要解決使用 AAPT2 時可能出現的已知行為變更,請參閱使用 AAPT2 時的行為改變

-zip file file 是包含用於掃描資源的 res 目錄的 ZIP 檔案。
-output-text-symbols file 產生指定檔案中包含資源符號的文字檔案。
-preserve-visibility-of-styleables 如已指定,系統會針對所有其他資源所用的樣式套用相同的瀏覽權限規則。否則,所有的樣式都會公開。
-visibility [public|private|default|] 將已編譯資源的瀏覽權限設為指定層級。
-trace-folder folder 產生 systrace JSON 追蹤記錄片段至指定資料夾
-source-path path 將編譯資源檔案的來源檔案路徑設定為路徑
-h 顯示工具說明。
-v 啟用詳細記錄。

在連結階段,AAPT2 會將從編譯階段產生的所有中繼檔案合併,例如資源資料表、二進位 XML 檔案,以及已處理的 PNG 檔案,並將這些檔案封裝為單一 APK。此外,在這個階段會產生其他輔助檔案 (例如 R.java 和 ProGuard 規則檔案)。不過,產生的 APK 不包含 DEX 位元碼,且未簽署。您無法將這個 APK 部署至裝置。

如果您不是使用 Android Gradle 外掛程式透過指令列建構應用程式,則可使用其他指令列工具,例如 d8,將 Java 位元碼編譯成 DEX 位元碼,再使用 apksigner 簽署您的 APK。

使用 link 的一般語法如下:

aapt2 link path-to-input-files [options] -o
outputdirectory/outputfilename.apk --manifest AndroidManifest.xml

在以下範例中,AAPT2 合併了兩個中繼檔案:drawable_Image.flatvalues_values.arsc.flat,以及 AndroidManifest.xml 檔案。AAPT2 會將結果與 android.jar 檔案連結,該檔案保存了 android 套件中定義的資源:

 aapt2 link -o output.apk
 -I android_sdk/platforms/android_version/android.jar
    compiled/res/values_values.arsc.flat
    compiled/res/drawable_Image.flat --manifest /path/to/AndroidManifest.xml -v

您可以搭配 link 指令使用下列選項:

表 3. 連結指令選項

選項 說明
-o path

指定已連結資源 APK 的輸出路徑。

此為必填旗標,因為您必須指定輸出 APK 的路徑,且該路徑會保存已連結的資源。

--manifest file

指定要建構的 Android 資訊清單檔案路徑。

此為必填旗標,因為其中涵蓋應用程式的重要資訊,例如套件名稱和應用程式 ID。

-I

提供可能有助於建立功能的平台 android.jar 或其他 APK (例如 framework-res.apk) 的路徑。

如果您在資源檔案中使用含 android 命名空間的屬性,則此旗標為必填屬性。
-A directory 指定要納入 APK 的素材資源目錄。

您可以使用這個目錄儲存原始版本未經處理的檔案。詳情請參閱「存取原始檔案」。

-R file 使用 overlay 語意 (無須使用 <add-resource> 標記) 將個別 .flat 檔案傳遞至 link

當您提供現有的資源檔案時,系統會使用給定的最後衝突資源。

--package-id package-id 指定要用於應用程式的套件 ID。

除非與 --allow-reserved-package-id 組合使用,否則您指定的套件 ID 必須大於或等於 0x7f。

--allow-reserved-package-id

允許使用保留的套件 ID。

保留的套件 ID 通常是指派給共用資料庫的 ID,範圍從 0x02 到 0x7e (含)。您可以使用 --allow-reserved-package-id 指派屬於保留套件 ID 範圍的 ID。

這個選項只適用於 min-sdk 為 26 以下版本的套件。

--java directory 指定要在其中產生 R.java 的目錄。
--proguard proguard_options 產生 ProGuard 規則的輸出檔案。
--proguard-conditional-keep-rules 產生主要 DEX 的 ProGuard 規則輸出檔案。
--no-auto-version 停用自動樣式和版面配置 SDK 版本管理。
--no-version-vectors 停用向量可繪項目的自動版本管理功能。只有在使用向量可繪項目程式庫建構 APK 時,才能使用此旗標。
--no-version-transitions 停用轉換資源的自動版本管理功能。只有在使用轉換支援資料庫建構 APK 時,才能使用此旗標。
--no-resource-deduping 在相容設定中,停用含相同數值的資源自動重複資料刪除功能。
--enable-sparse-encoding 使用二進位檔搜尋樹狀結構啟用稀疏項目編碼功能。這適合用來最佳化 APK 大小,但會影響資源擷取效能。
-z 需要標示為「建議」的本地化字串。
-c config 提供以逗號分隔的設定清單。

舉例來說,如果支援資料庫有依附元件 (其中包含多種語言的翻譯),您可以只針對特定語言 (例如英文或西班牙文) 設定篩選資源。

您必須以兩個英文字母組成的 ISO 639-1 語言代碼定義語言設定,亦可選擇在後面接續兩個英文字母 ISO 3166-1-alpha-2 區域代碼,前面加上小寫的「r」。例如 en-rUS。

--preferred-density density 允許 AAPT2 選擇最接近的相符密度,並剔除所有其他項目。

應用程式中可以使用數種像素密度限定詞,例如 ldpi、hdpi 和 xhdpi。指定偏好的密度時,AAPT2 會在資源表格中選取並儲存最接近的相符密度,並移除所有其他項目。

--output-to-dir 將 APK 內容輸出至 -o 指定的目錄。

假如在使用此旗標時發生任何錯誤,請升級至 Android SDK Build Tools 28.0.0 以上版本來解決問題。

--min-sdk-version min-sdk-version 設定 AndroidManifest.xml 要使用的預設最低 SDK 版本。
--target-sdk-version target-sdk-version 設定 AndroidManifest.xml 要使用的預設目標 SDK 版本。
--version-code version-code 如果沒有顯示任何項目,請指定要在 AndroidManifest.xml 中插入的版本程式碼。
--version-name version-name 如果沒有顯示任何項目,請指定要在 AndroidManifest.xml 中插入的版本名稱。
--revision-code revision-code 如果沒有顯示任何項目,請指定要在 AndroidManifest.xml 檔案中插入的版本程式碼。
--replace-version 如已指定 --version-code--version-name--revision-code,這些值會取代資訊清單中已存在的任何值。根據預設,如果資訊清單已定義這些屬性,就不會變更任何內容。
--compile-sdk-version-nacodeme compile-sdk-version-name 如果沒有顯示任何項目,請指定要在 AndroidManifest.xml 檔案中插入的版本程式碼。
--compile-sdk-version-name compile-sdk-version-name 如果沒有顯示任何項目,請指定要在 AndroidManifest.xml 檔案中插入的版本名稱。
--proto-format 以 Protobuf 格式產生已編譯的資源。

適用於產生 Android App Bundle 的 bundletool 輸入。

--non-final-ids 產生含非最終資源 ID 的 R.java。在 kotlincjavac 編譯期間,系統不會參照應用程式程式碼的 ID。
--emit-ids path 在指定路徑傳送檔案,其中包含資源類型名稱與其 ID 對應項目的清單。適合搭配 --stable-ids 使用。
--stable-ids outputfilename.ext 消耗使用 --emit-ids 產生的檔案,內含資源類型名稱與其指派 ID 的清單。

即使您在連結時刪除或新增資源,這個選項可允許指派的 ID 保持穩定。

--custom-package package_name 指定要在其下產生 R.java 的自訂 Java 套件。
--extra-packages package_name 產生相同的 R.java 檔案,但套件名稱不同。
--add-javadoc-annotation annotation 將 JavaDoc 註解新增至所有產生的 Java 類別。
--output-text-symbols path 產生指定檔案中包含 R 類別資源符號的文字檔案。

您必須指定輸出檔案的路徑。

--auto-add-overlay 可在不使用 <add-resource> 標記的情況下新增重疊的新資源。
--rename-manifest-package manifest-package 重新命名 AndroidManifest.xml 檔案中的套件。
--rename-instrumentation-target-package instrumentation- target-package 變更 instrumentation 的目標套件名稱。

這個選項應結合 --rename-manifest-package 使用。

-0 extension

指定您不想壓縮的檔案副檔名。

--split path:config[,config[..]] 依據一組設定分割資源,以產生其他版本的 APK。

您必須指定輸出 APK 的路徑以及其他組設定。

--proguard-main-dex file 針對主要 DEX 產生 ProGuard 規則的輸出檔案。
--proguard-minimal-keep-rules 產生最少 ProGuard 保留規則集。
--no-resource-removal 停用自動移除不含預設值的資源。只有在建構執行階段資源覆蓋套件時,才能使用這個選項。
-x 指定使用套件 ID 0x01 的舊版旗標。
--product products-list 指定要保留的產品名稱清單 (以逗號分隔)。
--no-xml-namespaces res/*AndroidManifest.xml 檔案和 XML 二進位檔中移除 XML 命名空間前置字串和 URI 資訊。
--shared-lib 產生共用的 Android 執行階段程式庫。
--static-lib 產生靜態 Android 程式庫。
--no-static-lib-packages 合併應用程式套件下的所有程式庫資源。
--no-proguard-location-reference 防止 ProGuard 規則檔案參照來源檔案。
--private-symbols package-name package-name 會指定在針對私人符號產生 R.java 時要使用的套件名稱。如未指定,公開和私人符號則會使用應用程式的套件名稱。
--override-styles-instead-of-overlaying 使用 -R 資源中定義的樣式來取代先前的定義,而不是合併這些定義。
--rename-resources-package package-name 將資源資料表中的套件重新命名為 package-name
--no-compress 不會壓縮任何資源。
--keep-raw-values 保留 XML 檔案中的原始屬性值。
--no-compress-regex regular-expression 不會壓縮與 regular-expression 相符的擴充功能。在行尾使用 $ 符號。使用區分大小寫的 ECMAScript 規則運算式語法。
--warn-manifest-validation 將資訊清單驗證錯誤視為警告。
--exclude-configs qualifier[,qualifier[..]] 排除設定中包含指定限定詞的資源值。
--debug-mode android:debuggable="true" 插入資訊清單的應用程式節點,讓應用程式即使在生產裝置上也能進行偵錯。
--strict-visibility 不允許具有不同瀏覽權限等級的重疊。
--exclude-sources 以 Protobuf 格式產生資源時,不會序列化來源檔案資訊。
--trace-folder folder 產生 systrace JSON 追蹤記錄片段至指定的 folder
--merge-only 只在未驗證資源參照的情況下合併資源。這個旗標應只與 --static-lib 旗標搭配使用。
-h 顯示說明選單。
-v 啟用提高輸出的詳細程度。

傾印

dump 是用來列印使用 link 指令產生的 APK 相關資訊。

傾印語法

使用 dump 的一般語法如下:

aapt2 dump sub-command filename.apk [options]

下列範例會列印指定 APK 資源資料表的內容:

aapt2 dump resources output.apk

傾印子指令

使用 dump 指令指定下列其中一個子指令:

表 4. 傾印子指令

子指令說明
apc 列印在編譯期間產生的 AAPT2 容器 (APC) 內容。
badging 從 APK 資訊清單中擷取的列印資訊。
configurations 列印 APK 中由資源使用的所有設定。
overlayable 列印 APK 的可重疊資源。
packagename 列印 APK 套件名稱。
permissions 列印從 APK 資訊清單中擷取的權限。
strings 列印 APK 資源資料表字串集區的內容。
styleparents 列印 APK 中所使用的樣式父項。
resources 列印 APK 資源資料表的內容。
xmlstrings 列印 APK 已編譯 XML 中的字串。
xmltree 列印 APK 已編譯 XML 的樹狀結構。

傾印選項

請搭配 dump 使用下列選項:

表 5. 傾印選項

選項說明
--no-values 顯示資源時隱藏值輸出內容。
--file file 將檔案指定為引數,以便從 APK 傾印。
-v 提高輸出的詳細程度。

差異比較

使用 diff 比較兩個 APK,並找出兩者之間的差異。

差異比較語法

使用 diff 的一般語法如下:

aapt2 diff first.apk second.apk

沒有 diff 指令可用的選項。

盡力改善

optimize 用於在合併的資源和 resources.arsc 上執行最佳化,然後再將套件封裝至 APK。根據使用資源大小和數量,這項最佳化可縮減 APK 的大小約 1-3%。

最佳化語法

使用 optimize 的一般語法如下:

aapt2 optimize options file[,file[..]]

下列範例會最佳化 input.apk 中的資源,並在 output.apk 中建立新的最佳化 APK。這樣做可將一般的二維資料表呈現為更精簡的二進位搜尋樹狀圖,進而產生較小的 APK,但擷取效能也會隨之降低:

aapt2 optimize -o output.apk --enable-sparse-encoding input.apk

最佳化選項

下列選項可與 optimize 搭配使用:

表 6. 最佳化選項

選項說明
-o path 指定已連結資源 APK 的輸出路徑。

此為必填旗標,因為您必須指定輸出 APK 的路徑,且該路徑會保存已連結的資源。

-d directory 指定分割的輸出目錄路徑。
-x path 指定 XML 設定檔的路徑。
-p 列印多 APK 構件並結束。
--target-densities density[,density[..]] 指定 APK 最佳化的螢幕密度清單 (以逗號分隔)。這樣一來,指定密度裝置上未使用的所有資源都會從 APK 中移除。
--resources-config-path path

指定 resources.cfg 檔案的路徑,其中包含資源清單和每項資源的指令。

格式︰type/resource_name#[directive][,directive]

-c config[,config[..]] 指定要納入的以逗號分隔的設定清單。預設值為所有設定。
--split path:config[,config[..]] 依據一組設定分割資源,以產生其他版本的 APK。

您必須指定輸出 APK 的路徑以及其他組設定。

--keep-artifacts artifact[,artifact[..]] 指定要保留的以逗號分隔的構件清單。如未指定,則會保留所有構件。
--enable-sparse-encoding 使用二進位檔搜尋樹狀結構啟用稀疏項目編碼功能。這個選項適合用來最佳化 APK 大小,但會影響資源擷取效能。
--collapse-resource-names 將資源名稱收合為索引鍵字串集區中的單一值。在 --resources-config-path 指定的檔案中,使用 no_collapse 指令來排除資源。
--shorten-resource-paths 縮短 APK 內的資源路徑。
--resource-path-shortening-map path 指定將舊資源路徑對應至短路徑的輸出路徑。
-v 提高輸出的詳細程度。
-h 顯示工具說明。

轉換

根據預設,AAPT compile 指令會將資源編譯成適合 APK 的二進位格式。您也可以指定 --proto-format,藉此來指定適合 AAB 的 protobuf 格式。convert 指令會在這兩種格式之間轉換 APK。

轉換語法

使用 convert 的一般語法如下:

aapt2 convert -o output-file options file[,file[..]]

下列範例會轉換 input.apk 中的資源,並在 output.apk 中建立包含 protobuf 格式資源的新 APK。這樣做可將一般的二維資料表呈現為更精簡的二進位搜尋樹狀圖,進而產生較小的 APK,但擷取效能也會隨之降低:

aapt2 convert -o output.apk --output-format proto --enable-sparse-encoding input.apk

轉換選項

請搭配 convert 使用下列選項:

表 7. 轉換選項

選項說明
-o path

指定已連結資源 APK 的輸出路徑。

此為必填旗標,因為您必須指定輸出 APK 的路徑,且該路徑會保存已連結的資源。

--output-format [proto|binary] 輸出格式。可接受的值為 protobinary。如未設定,則預設為 binary
--enable-sparse-encoding 使用二進位檔搜尋樹狀結構啟用稀疏項目編碼功能。這個選項適合用來最佳化 APK 大小,但會影響資源擷取效能。
--keep-raw-values 保留 XML 檔案中的原始屬性值。
-v 提高輸出的詳細程度。
-h 顯示工具說明。

Daemon 模式

AAPT 2.19 版推出 Daemon 模式,可用於發出指令。Daemon 模式可讓您在單一 AAPT 工作階段輸入多個指令。

Daemon 語法

使用下列指令啟動 Daemon 模式:

aapt2 daemon

在 Daemon 模式執行後,您可以輸入指令。指令中的每個引數必須分行列出,並在指令結尾使用空白行。鍵入 Control+D 即可退出 Daemon 模式。

請考慮使用下列個別的 compile 指令:

aapt2 compile project_root/module_root/src/main/res/values-en/strings.xml -o compiled/
aapt2 compile project_root/module_root/src/main/res/drawable/myImage.png -o compiled/

這些指令可在 Daemon 模式下輸入,如下所示:

aapt2 daemon
Ready
compile
project_root/module_root/src/main/res/values-en/strings.xml
-o
compiled/

Done
compile
project_root/module_root/src/main/res/drawable/myImage.png
-o
compiled/

Done
^D
Exiting daemon

Daemon 模式選項

Daemon 模式的單一選項是 --trace-folder folder,這會向指定的 folder 產生 systrace JSON 追蹤記錄片段。

版本

確定您要透過 version 指令使用的 AAPT2 版本:

aapt2 version
Android Asset Packaging Tool (aapt) 2.19-8678579

使用 AAPT2 時的行為改變

在 AAPT2 之前,AAPT 是 Android 資產封裝工具的預設版本,現已淘汰。雖然 AAPT2 應立即處理舊版專案,但本節將說明您應注意的部分行為改變。

Android 資訊清單中的元素階層

在舊版 AAPT 中,AndroidManifest.xml 檔案中錯誤節點銜接的元素遭到忽略或導致警告。例如,請看以下範例:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="com.example.myname.myapplication">
   <application
       ...
       <activity android:name=".MainActivity">
           <intent-filter>
               <action android:name="android.intent.action.MAIN" />
               <category android:name="android.intent.category.LAUNCHER" />
           </intent-filter>
           <action android:name="android.intent.action.CUSTOM" />
       </activity>
   </application>
</manifest>

舊版 AAPT 只會忽略錯誤的 <action> 標記。

使用 AAPT2 時,系統會顯示下列錯誤:

AndroidManifest.xml:15: error: unknown element <action> found.

如要解決這個問題,請確認您的資訊清單元素正確銜接。詳情請參閱「應用程式資訊清單總覽」。

資源宣告

您無法再從 name 屬性表示資源類型。下列範例未正確宣告 attr 資源項目:

<style name="childStyle" parent="parentStyle">
    <item name="attr/my_attr">@color/pink</item>
</style>

以這種方式宣告資源類型會導致下列建構錯誤:

Error: style attribute 'attr/attr/my_attr (aka my.package:attr/attr/my_attr)'
not found.

如要解決這個錯誤,請使用 type="attr" 明確宣告類型:

<style name="childStyle" parent="parentStyle">
  <item type="attr" name="my_attr">@color/pink</item>
</style>

此外,在宣告 <style> 元素時,其父項也必須是樣式資源類型。否則,您會收到類似下列內容的錯誤:

Error: (...) invalid resource type 'attr' for parent of style

未正確使用 @ 資源參考符號

AAPT2 會在您省略或錯誤放置資源參照符號 (@) 時擲回建構錯誤。例如,如果您在指定樣式屬性時省略符號:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
  ...
  <!-- Note the missing '@' symbol when specifying the resource type. -->
  <item name="colorPrimary">color/colorPrimary</item>
</style>

建構模組時,AAPT2 會擲回下列建構錯誤:

ERROR: expected color but got (raw string) color/colorPrimary

此外,如果您從 android 命名空間存取資源時錯誤加入符號:

...
<!-- When referencing resources from the 'android' namespace, omit the '@' symbol. -->
<item name="@android:windowEnterAnimation"/>

建構模組時,AAPT2 會擲回下列建構錯誤:

Error: style attribute '@android:attr/windowEnterAnimation' not found

資料庫設定有誤

如果您的應用程式含有舊版 Android SDK Build Tools 建構第三方程式庫的依附元件,則該應用程式可能會在執行階段異常終止,且不會顯示任何錯誤或警告。這個異常終止情況的可能原因為,在程式庫建立期間,R.java 欄位會宣告 final。因此,所有資源 ID 都會內嵌至該程式庫的類別中。

AAPT2 仰賴在建立應用程式時,能將 ID 重新指派給程式庫資源的動作。如果程式庫假設 ID 是 final,且在資料庫 DEX 中內嵌這些 ID,則系統會發生執行階段不符的情形。

如要解決這個錯誤,請與程式庫作者聯絡,以使用最新版 Android SDK Build Tools 重新建構程式庫,然後重新發布程式庫。