共用方式為


準備發布應用程式

在應用程式經過程式代碼和測試之後,必須準備套件以供散發。 準備此套件的第一項工作是建置要發行的應用程式,這主要需要設定一些應用程式屬性。

使用下列步驟建置應用程式以供發行:

  • 指定應用程式圖示 – 每個 Xamarin.Android 應用程式都應該指定應用程式圖示。 雖然在技術上並非必要,但某些市場,如谷歌遊戲,需要它。

  • 版本應用程式 – 此步驟牽涉到初始化或更新版本設定資訊。 這對未來的應用程式更新很重要,並確保使用者知道他們已安裝的應用程式版本。

  • 壓縮 APK – 通過在受控程式碼上使用 Xamarin.Android 連結器和在 Java 位元碼上使用 ProGuard,可以大幅減少最終 APK 的大小。

  • 保護應用程式 – 藉由停用偵錯、混淆 Managed 程式代碼、新增反偵錯和反竄改,以及使用原生編譯,防止使用者或攻擊者偵錯、竄改或反向工程應用程式。

  • 設定封裝屬性 – 封裝 屬性可控制建立 Android 應用程式套件 (APK)。 此步驟會將 APK 優化、保護其資產,並視需要將封裝模組化。 此外,您可以為使用者提供針對其裝置優化的 Android 應用程式套件組合。

  • 編譯 – 此步驟會編譯程式代碼和資產,以確認其是以發行模式建置。

  • 封存以進行發佈 – 此步驟會建置應用程式,並將它放在封存中以進行簽署和發佈。

以下將詳細說明上述每個步驟。

指定應用程式圖示

強烈建議每個 Xamarin.Android 應用程式指定應用程式圖示。 某些應用程式市集不允許在沒有Android應用程式的情況下發佈。 屬性 IconApplication 屬性是用來指定 Xamarin.Android 專案的應用程式圖示。

在 Visual Studio 2017 和更新版本中,透過專案 [屬性] 的 [Android 指令清單] 區段指定應用程式圖示,如下列螢幕快照所示:

設定應用程式圖示

在這些範例中, @drawable/icon 是指位於 資源/可繪製/icon.png 的圖示檔案(請注意 ,資源 名稱中不包含.png擴展名)。 這個屬性也可以在 Properties\AssemblyInfo.cs 檔案中宣告,如下列範例代碼段所示:

[assembly: Application(Icon = "@drawable/icon")]

一般而言, using Android.App 會在 AssemblyInfo.cs 頂端宣告 (屬性的 Application 命名空間為 Android.App), 不過,如果尚未存在,您可能需要新增這個 using 語句。

為應用程式設置版本

版本控制對於Android應用程式維護和散發而言很重要。 如果沒有某種版本設定,很難判斷應用程式是否應該更新或如何更新。 為了協助版本設定,Android 會辨識兩種不同類型的資訊:

  • 版本號碼 – 代表應用程式版本的整數值(由 Android 和應用程式在內部使用)。 大部分的應用程式都是從此值設定為 1 開始,然後隨著每個組建遞增。 這個值與版本名稱屬性沒有關聯性或親和性(請參閱下文)。 應用程式和發佈服務不應向用戶顯示此值。 此值會儲存在 AndroidManifest.xml 檔案中,做為 android:versionCode

  • 版本名稱 – 字串,僅用於向使用者傳達有關應用程式版本的資訊(如安裝在特定裝置上)。 版本名稱是要向使用者或Google Play 中顯示。 Android 不會在內部使用此字串。 版本名稱可以是任何字串值,可協助使用者識別其裝置上安裝的組建。 此值會儲存在 AndroidManifest.xml 檔案中,做為 android:versionName

在 Visual Studio 中,您可以在專案 [屬性] 的 [Android 指令清單] 區段中設定這些值,如下列螢幕快照所示:

設定版本號碼

壓縮 APK

Xamarin.Android APK 可透過 Xamarin.Android 連結器的組合來縮小,該連結器會移除不必要的 Managed 程式代碼,而 Android SDK 中的 ProGuard 工具會移除未使用的 Java 位元組程式代碼。 建置程式會先使用 Xamarin.Android 連結器,在 Managed 程式代碼 (C#) 層級優化應用程式,然後稍後會使用 ProGuard (如果已啟用)在 Java 位元組程式代碼層級優化 APK。

設定連結器

發行模式會關閉共用運行時間並開啟連結,讓應用程式只提供運行時間所需的 Xamarin.Android 片段。 Xamarin.Android 中的 連結器 會使用靜態分析來判斷 Xamarin.Android 應用程式會使用或參考哪些元件、類型和類型成員。 接著,鏈接器會捨棄所有未使用或未參考的元件、類型和成員。 這可能會導致封裝大小大幅減少。 例如,請考慮 HelloWorld 範例,其 APK 的最終大小會減少 83%:

  • 設定:無 – Xamarin.Android 4.2.5 大小 = 17.4 MB。

  • 組態:僅限 SDK 元件 – Xamarin.Android 4.2.5 大小 = 3.0 MB。

透過專案 [屬性] 的 [Android 選項] 區段設定連結器選項:

連結器選項

[ 連結 ] 下拉功能表提供下列選項來控制連結器:

  • – 這會關閉連結器;不會執行任何連結。

  • 僅限 SDK 元件 – 只會連結 Xamarin.Android 所需的元件。 其他元件將不會連結。

  • Sdk 和使用者元件 – 這會連結應用程式所需的所有元件,而不只是 Xamarin.Android 所需的元件。

連結可能會產生一些非預期的副作用,因此請務必在實體裝置上的發行模式中重新測試應用程式。

ProGuard

ProGuard 是一種 Android SDK 工具,可連結 Java 程式代碼並混淆 Java 程式代碼。 ProGuard 通常用來在 APK 中減少大型內含連結庫(例如 Google Play Services)的使用量,以建立較小的應用程式。 ProGuard 會移除未使用的 Java 位元組程式代碼,讓產生的應用程式更小。 例如,在小型 Xamarin.Android 應用程式上使用 ProGuard 通常可達到大約 24 個% 大小縮減 -- 在具有多個連結庫相依性的較大應用程式上使用 ProGuard 通常可達到更大的大小縮減。

ProGuard 不是 Xamarin.Android 連結器替代方案。 Xamarin.Android 連結器會連結 Managed 程式代碼,而 ProGuard 則連結 Java 位元組程式代碼。 建置程式會先使用 Xamarin.Android 連結器來優化應用程式中的 Managed (C#) 程式代碼,然後稍後會使用 ProGuard(如果已啟用)在 Java 位元組程式代碼層級優化 APK。

核取 [啟用 ProGuard ] 時,Xamarin.Android 會在產生的 APK 上執行 ProGuard 工具。 ProGuard 組態檔會在建置階段由 ProGuard 產生及使用。 Xamarin.Android 也支援自定義 ProguardConfiguration 建置 動作。 您可以將自定義 ProGuard 組態檔新增至您的專案,以滑鼠右鍵按兩下它,然後選取它作為建置動作,如下列範例所示:

ProGuard 預設為停用。 [ 啟用 ProGuard ] 選項只有在項目設定為 [發行 ] 模式時才能使用。 除非核取 [啟用 ProGuard ] ,否則會忽略所有 ProGuard 建置動作。 Xamarin.Android ProGuard 組態不會模糊化 APK,而且即使使用自定義組態檔,也無法啟用混淆。 如果您想要使用模糊化,請參閱 使用 Dotfuscator 的應用程式保護

如需使用 ProGuard 工具的詳細資訊,請參閱 ProGuard

保護應用程式

停用偵錯

在 Android 應用程式開發期間,會使用 Java 調試線路協議(JDWP)來執行偵錯。 這是一項技術,可讓 adb 之類的工具為了偵錯而與 JVM 通訊。 預設會為 Xamarin.Android 應用程式的偵錯版本開啟 JDWP。 雖然 JDWP 在開發期間很重要,但它可能會對已發行的應用程式造成安全性問題。

這很重要

一律停用已發行應用程式中的偵錯狀態,因為如果此偵錯狀態未停用,可以(透過 JDWP)取得 Java 進程的完整存取權,並在應用程式內容中執行任意程式代碼。

Android 指令清單包含 android:debuggable 屬性,可控制是否可能偵錯應用程式。 通常建議將 android:debuggable 屬性設定為 false。 若要這樣做,最簡單的方式是在 AssemblyInfo.cs中新增條件式編譯語句:

#if DEBUG
[assembly: Application(Debuggable=true)]
#else
[assembly: Application(Debuggable=false)]
#endif

請注意,偵錯組建會自動設定一些許可權,讓偵錯變得更容易(例如 因特網ReadExternalStorage)。 不過,發行組建只會使用您明確設定的許可權。 如果您發現切換至發行組建會導致您的應用程式失去偵錯組建中可用的許可權,請確認您已在 [ 必要許可權 ] 列表中明確啟用此許可權,如 許可權中所述。

使用 Dotfuscator 的應用程式保護

即使 偵錯功能已停用,攻擊者仍有可能重新封裝應用程式,新增或者移除設定選項或權限。 這可讓他們進行逆向工程、偵錯或竄改應用程式。 Dotfuscator Community Edition (CE) 可用來模糊化 Managed 程式代碼,並在建置階段將運行時間安全性狀態偵測程式代碼插入 Xamarin.Android 應用程式中,以偵測和回應應用程式是否在根裝置上執行。

Dotfuscator CE 隨附於 Visual Studio 2017。 若要使用 Dotfuscator,請按兩下 [工具 > 先佔式保護 - Dotfuscator]。

若要設定 Dotfuscator CE,請參閱 搭配 Xamarin 使用 Dotfuscator Community Edition。 設定之後,Dotfuscator CE 會自動保護所建立的每個組建。

將組件組合成原生程式碼

啟用此選項時,元件會組合成原生共享連結庫。 這可讓元件壓縮,可使檔案 .apk 更小。 元件壓縮也會提供最基本的混淆形式,但不應過於依賴這種混淆。

此選項需要企業授權,且只有在停用 使用快速部署 時才可使用。 將元件組合成機器碼預設為停用。

請注意,捆綁為原生程式碼 選項並不意味著元件會編譯成原生代碼。 無法使用 AOT 編譯 將元件編譯成原生碼。

AOT 編譯

[AOT 編譯] 選項(在 [封裝屬性] 頁面上)啟用元件的預先編譯。 啟用此選項時,在運行時間之前先編譯元件,將 Just In Time (JIT) 啟動額外負荷降至最低。 產生的原生程式碼會連同未編譯的組件包含在 APK 中。 這會導致應用程式啟動時間較短,但代價是稍微較大的 APK 大小。

AOT 編譯選項需要 Enterprise 授權或更新版本。 只有在項目設定為發行模式,且預設為停用時,才能使用 AOT 編譯。 如需 AOT 編譯的詳細資訊,請參閱 AOT

LLVM 優化編譯程式

LLVM 優化編譯程式會建立較小且更快的編譯程式代碼,並將 AOT 編譯的元件轉換成機器碼,但代價是建置時間變慢。 LLVM 編譯程序預設為停用。 若要使用 LLVM 編譯程式,必須先啟用 [封裝屬性] 頁面上的 [AOT 編譯] 選項。

備註

LLVM 優化編譯程式選項需要企業授權。

設定封裝屬性

封裝屬性可以在專案 [屬性] 的 [Android 選項] 區段中設定,如下列螢幕快照所示:

封裝屬性

其中許多屬性,例如 使用共用運行時間,以及 使用快速部署 適用於偵錯模式。 不過,當應用程式設定為發行模式時,還有其他設定可決定應用程式如何 針對大小和執行速度進行優化、如何 保護它免於竄改,以及如何封裝以支援不同的架構和大小限制。

指定支持的架構

準備要發行的 Xamarin.Android 應用程式時,必須指定支援的 CPU 架構。 單一 APK 可以包含支援多個不同架構的機器碼。 如需支援多個 CPU 架構的詳細資訊,請參閱 CPU 架構

為每個選取的 ABI 生成一個 APK 套件

啟用此選項時,將會為每個支援的 ABI 建立一個 APK(如 CPU 架構中所述的 [進階] 索引標籤上選取),而不是針對所有支援的 ABI 建立單一大型 APK。 只有在專案設定為發行模式,且預設為停用時,才能使用此選項。

Multi-Dex

啟用 [ 啟用多重索引 ] 選項時,會使用 Android SDK 工具略過 .dex 檔案格式的 65K 方法限制。 65K 方法限制是以應用程式 所參考 的 Java 方法數目為基礎(包括應用程式相依的任何連結庫中的方法),而不是以 原始程式碼中寫入的方法數目為基礎。 如果應用程式只定義幾個方法,但使用許多(或大型連結庫),可能會超過65K限制。

應用程式可能未在每個參考的庫中使用每個方法,因此,像 ProGuard 這樣的工具可能會從程式碼中移除未使用的方法。 最佳做法是只有在絕對必要的情況下啟用 啟用 Multi-Dex ,也就是即使使用 ProGuard 之後,應用程式仍會參考超過 65K 個 Java 方法。

如需 Multi-Dex 的詳細資訊,請參閱 使用超過 64K 方法設定應用程式

Android 應用程式套件組合

應用程式套件組合與 APK 不同,因為它們無法直接部署到裝置。 其實,這是一種格式,旨在與所有已編譯的程式碼和資源一起上傳。 上傳已簽署的應用程式套件組合之後,Google Play 將擁有建置和簽署應用程式 APK 所需的一切,並使用動態傳遞將其服務給您的使用者。

若要啟用 Android 應用程式套件組合的支援,您必須選擇加入 bundle Android 專案選項內 Android 套件格式 屬性的值。 執行此動作之前,請確定您將專案變更為 Release 設定,因為應用程式套件組合僅適用於發行套件。

您現在可以遵循封存流程來產生應用程式捆包。 這會為您的應用程式產生應用程式套件組合。

如需Android應用程式套件組合的詳細資訊,請參閱 Android應用程式套件組合

編譯

完成上述所有步驟之後,應用程式便已準備好進行編譯。 選取 [建置 > 重建方案 ],確認它在發行模式中成功建置。 請注意,此步驟尚未產生 APK。

簽署應用程式套件更詳細地討論了打包和簽署的內容。

存檔以供發佈

若要開始發佈程序,請在 方案總管 中以滑鼠右鍵按一下專案,然後選取 封存... 選單項目:

封存應用程式

檔案。。。 會啟動 封存管理員 ,並開始封存應用程式套件組合的程式,如下列螢幕快照所示:

封存管理員

另一個建立封存的方式是以滑鼠右鍵按兩下 [ 方案 總管] 中的 [方案],然後選取 [ 封存全部...],以建置解決方案並封存所有可產生封存的 Xamarin 專案:

封存全部

封存封存全部都會自動啟動封存管理員。 若要直接啟動 封存管理員 ,請單擊 [工具 > 封存管理員...] 功能表項:

啟動封存管理員

隨時查看解決方案的封存,方法是右鍵按一下解決方案節點,然後選擇檢視封存

檢視檔案

封存管理員

封存管理員方案列表 視窗、封存清單詳細資訊面板 所組成:

封存管理員窗格

[ 方案清單 ] 會顯示至少有一個封存專案的所有解決方案。 解決方案清單包含下列各節:

  • 目前的方案 – 顯示目前的方案。 請注意,如果目前解決方案沒有現有的封存,此區域可能是空的。
  • 所有存檔 – 顯示包含存檔的所有解決方案。
  • 搜尋 文字框 (頂端) – 根據文字框中輸入的搜尋字串,篩選 [ 所有封存 ] 清單中所列的解決方案。

存列表 顯示所選解決方案的所有存檔。 檔案清單包含下列部分:

  • 選擇的解決方案名稱 – 顯示方案 清單中選取的解決方案名稱。 存清單中 顯示的所有資訊均與此選定的解決方案有關。
  • 平台篩選 – 此欄位可讓您依平台類型篩選封存(例如 iOS 或 Android)。
  • 封存項目 – 所選解決方案的封存清單。 此清單中的每個專案都包含項目名稱、建立日期和平臺。 它也可以顯示其他資訊,例如在封存或發佈項目時進度。

[詳細數據面板] 會顯示每個封存的其他資訊。 它也允許使用者啟動散發工作流程,或開啟已建立散發的資料夾。 [ 建置批注 ] 區段可讓您在封存中包含組建批注。

分配

當封存的應用程式版本準備好發佈時,請選取 [ 封存管理員 ] 中的封存,然後按兩下 [ 散發...] 按鈕:

[發佈] 按鈕

[ 散發通道 ] 對話框會顯示應用程式的相關信息、發佈工作流程進度的指示,以及散發通道的選擇。 在第一次執行時,會顯示兩個選項:

選取分銷渠道

您可以選擇下列其中一個散發通道:

  • 臨時 – 將已簽署的 APK 儲存到磁碟,然後可側載至 Android 裝置。 繼續 簽署應用程式套件 ,以瞭解如何建立Android簽署身分識別、建立Android應用程式的新簽署憑證,以及將 特定版本的應用程式 發佈至磁碟。 這是建立 APK 以進行測試的好方法。

  • Google Play – 將已簽署的 APK 發佈至 Google Play。 繼續 發佈至Google Play ,以瞭解如何在Google Play商店中簽署和發佈 APK。