當我們想要進行 Xamarin.Android 專案封存 Archive 作業,並且要產生出可以發布佈署的 .apk 檔案,我們可以雙擊 Android 專案的 Properties 節點,進入到 Android 專案的屬性頁面;在這個頁面中,切換到 Android 選項標籤頁次,我們可以看到這三個選項
- 將組譯碼組合成機器碼
- 符合 AOT 規範 (實驗性)
- 使用 LLVM 最佳化編譯器
關於這三個項目的說明,可以參考準備可供發行的應用程式
我曾在 2017.06 也寫過一篇類似的文章 Xamarin.Android 各種封存屬性測試 。當時所採用的測試專案為一個工作管理的範例專案,不過,今天,我們將會採用 Prism Template Pack 所提供的專案範本所產生的一個專案,這個專案內將沒有再去撰寫任何 C# / XAML 的程式碼。
我的測試環境為 Visual Studio Enterprise 2017 15.7.2 版本,我將會切到 Release 組態模式下,並且調整這三個選項:將組譯碼組合成機器碼 / 符合 AOT 規範 (實驗性) / 使用 LLVM 最佳化編譯器,最後,使用封存功能,產生出尚未進行程式碼簽名的 .apk 檔案,我們將會來觀察這些不同 Android 選項下所產生的 .apk 檔案,他的檔案大小為何?
透過這次的實驗,我發現到現在所使用 Visual Studio 2017 15.7.2 版本,不論使用上面三種選項的哪種組合,所產生出來的 .apk 檔案都已經大幅降低了許多,並且最佳化的處理也都表現得相當優異。
實驗 1 : 將組譯碼組合成機器碼 (無) / 符合 AOT 規範 (實驗性) (無) / 使用 LLVM 最佳化編譯器 (無)
在此模式下產生的 .apk 檔案大小為 : 17.7 MB
在這個 .apk 檔案的 assemblies 目錄下,存在這這些 .NET 組件檔案
在這個 .apk 檔案的 \lib\armeabi-v7a 目錄下,僅有這些檔案
實驗 2 : 將組譯碼組合成機器碼 (無) / 符合 AOT 規範 (實驗性) (有) / 使用 LLVM 最佳化編譯器 (無)
在此模式下產生的 .apk 檔案大小為 : 29.2 MB
在這個 .apk 檔案的 assemblies 目錄下,存在這這些 .NET 組件檔案,這些檔案內容與大小,皆與沒有設定 AOT 選項所產生的內相同。
在這個 .apk 檔案的 \lib\armeabi-v7a 目錄下,卻發現到更多的檔案出現,由副檔案名稱為 .so ,我們可以知道這些是 Android 系統下的 Native Code。因此,我們也就知道了當設定 AOT 模式,所產生的 .apk 檔案內,已經有這些 .NET 組件的機器碼 Native Code 產生在裡面了,因為,當實際執行這個 Xamarin.Android 專案的時候,我們就不再需要透過 JIT 來即時轉譯 IL 碼到 Native Code,因為,這些 Native Code 都已經產生好了,所以,按照理論上來說,執行效能應該會更好。
實驗 3 : 將組譯碼組合成機器碼 (無) / 符合 AOT 規範 (實驗性) (有) / 使用 LLVM 最佳化編譯器 (有)
在此模式下產生的 .apk 檔案大小為 : 26.7 MB
在這個 .apk 檔案的 assemblies 目錄下,存在這這些 .NET 組件檔案,這些檔案內容與大小,皆與沒有或者有設定 AOT 選項所產生的內相同。
在這個 .apk 檔案的 \lib\armeabi-v7a 目錄下,我們發現到這些 .so 檔案數量不變,不過,您可以發現到這些檔案的大小卻明顯的變小了許多,這些檔案變小,都是有助於 LVVM 有啟用的關係。
實驗 4 : 將組譯碼組合成機器碼 (有) / 符合 AOT 規範 (實驗性) (無) / 使用 LLVM 最佳化編譯器 (無)
在此模式下產生的 .apk 檔案大小為 : 8.83 MB
在這裡,我們要來檢測 將組譯碼組合成機器碼 選項,根據微軟官方文件上的說明:啟用此選項時,系統會將組件組合成原生共用程式庫。 此選項會保護程式碼的安全。它會將受控組件內嵌於原生二進位檔來予以保護。
現在,因為這些 .NET 組件被保護起來了,因此,我們在這個 .apk 檔案內,也就無法發現到 assemblies 目錄存在
在這個 .apk 檔案的 \lib\armeabi-v7a 目錄下,僅有這些檔案,比起實驗 1,多了一個 libmonodroid_bundle_app.so 檔案,我們可以知道,這個就是被保護起來的 .NET 組件檔案。
實驗 5 : 將組譯碼組合成機器碼 (有) / 符合 AOT 規範 (實驗性) (有) / 使用 LLVM 最佳化編譯器 (無)
在此模式下產生的 .apk 檔案大小為 : 20.3 MB
現在,因為這些 .NET 組件被保護起來了,因此,我們在這個 .apk 檔案內,也就無法發現到 assemblies 目錄存在
在這個 .apk 檔案的 \lib\armeabi-v7a 目錄下,多了取多檔案,這些都是 .NET 組件的 Native Code,不過,比起實驗 1,多了一個 libmonodroid_bundle_app.so 檔案,我們可以知道,這個就是被保護起來的 .NET 組件檔案。
實驗 6 : 將組譯碼組合成機器碼 (有) / 符合 AOT 規範 (實驗性) (有) / 使用 LLVM 最佳化編譯器 (有)
在此模式下產生的 .apk 檔案大小為 : 17.8 MB
現在,因為這些 .NET 組件被保護起來了,因此,我們在這個 .apk 檔案內,也就無法發現到 assemblies 目錄存在
在這個 .apk 檔案的 \lib\armeabi-v7a 目錄下,可以看得出來,經過 LLVM 的最佳化處理,這些 .NET 組件所產生的 Native Code,也都變小了許多。