針對不同 GL 材質建立多個 APK

如果您將應用程式發布到 Google Play,應建構並上傳 Android App Bundle。這樣一來,Google Play 會為每位使用者的裝置設定自動產生並提供最佳化 APK,使用者就能僅下載執行應用程式所需的程式碼和資源。如果您未將應用程式發布到 Google Play,發布多個 APK 是非常實用的做法,但請注意您必須自行建構、簽署及管理各個 APK。

當您開發 Android 應用程式,以利用 Google Play 上的多個 APK 時,請務必從一開始就採用一些建議做法,避免在開發過程中遇到不必要的麻煩。本課程將說明如何為應用程式建立多個 APK,每個 APK 都支援不同的 OpenGL 紋理格式子集。您也將取得一些必要工具,盡可能輕鬆維護多個 APK 程式碼集。

確認需要使用多個 APK

當您嘗試建立適用於所有可用 Android 裝置的應用程式時,無論應用程式是否都支援同一組 GL 紋理,您都希望應用程式在每部裝置上都能呈現出最佳效果。乍看之下,多個 APK 支援可能是最佳解決方案,但通常並非如此。多個 APK 開發人員指南的「使用單一 APK 替代」一節包含一些實用資訊,協助您瞭解如何在執行階段偵測支援的紋理格式。根據您的情況,將所有格式與應用程式組合在一起,而且只要在執行階段中挑選要使用的格式,就能更輕鬆。

如果您可以管理,將應用程式限制為單一 APK 有幾項好處,包括:

  • 發布與測試更容易
  • 只有一個程式碼集需要維護
  • 您的應用程式可根據裝置設定變更進行調整
  • 在所有裝置上還原應用程式的功能皆可正常運作
  • 您不必擔心市場偏好、從一個 APK 的「升級」到下一個 APK 的行為,以及哪些 APK 會與哪類裝置搭配使用

本課程的其餘部分假設您已研究過主題,工作室確實吸收連結資源中的素材,並判定多個 APK 是應用程式的正確路徑。

繪製資格條件圖表

Android 開發人員指南在支援 gl-Text 頁面提供了一些常見支援的紋理的實用參考資料。本頁也會提供一些提示,說明哪些手機 (或手機系列) 支援特定紋理格式。請注意,我們建議您讓其中一個 APK 支援 ETC1,因為所有支援 OpenGL ES 2.0 規格的 Android 裝置都支援這種紋理格式。

由於大多數 Android 裝置都支援多種紋理格式,因此您需要建立偏好的順序。建立圖表,其中包含應用程式要使用的所有格式。最左邊的儲存格將是最低的優先順序 (可能是 ETC1,效能和相容性方面真的是固定的)。接著為圖表中的顏色設定顏色,讓每個儲存格都代表一個 APK。

ETC1 先進產業技術 PowerVR

圖表中的顏色不僅會降低本指南的單色,還能簡化團隊內部通訊的方式。您現在可以直接將每個 APK 稱為「藍色」、「綠色」或「紅色」,而不是「支援 ETC1 紋理格式的」等。

將所有通用程式碼和資源放在程式庫專案中

無論是修改現有的 Android 應用程式,還是從頭啟動應用程式,都必須執行程式碼集的首要作業,這也是最重要的。程式庫專案中的所有內容都只需更新一次 (例如本地化字串、色彩主題、修正共用程式碼中的錯誤),這有助於改善開發時間,並減少容易避免的錯誤。

注意:雖然本課程範圍並不涵蓋建立及納入程式庫專案的實作詳細資料,但如果想快速掌握相關知識,請參閱「建立 Android 程式庫」。

如果您要將現有應用程式轉換成使用多個 APK 支援功能,請為每個本地化字串檔案搜尋程式碼集、值清單、主題顏色、選單圖示和版面配置,但這些內容不會因為 APK 不同而改變,然後把這些內容放到程式庫專案中。不會大幅變動的程式碼 也必須納入程式庫專案您可能會發現自己擴充這些類別,從而在 APK 中新增一或兩個方法。

不過,如果是從頭開始建立應用程式,請「先」盡可能在程式庫專案中編寫程式碼,然後再視需要將其移至個別 APK。長期下來,比起將 blob 新增到程式庫區段,在初期測試更容易管理的做法,數個月後開始嘗試判斷這個 blob 是否可移往程式庫區段,而不必向上捲動。

建立新的 APK 專案

您要發布的每個 APK 都應該有獨立的 Android 專案。為方便整理,請將程式庫專案和所有相關 APK 專案放在同一個上層資料夾下。此外請注意,每個 APK 都必須使用相同的套件名稱,但不一定要與程式庫共用套件名稱。如果按照上述配置建立 3 個 APK,根目錄可能會如下所示:

alexlucas:~/code/multi-apks-root$ ls
foo-blue
foo-green
foo-lib
foo-red

建立專案後,請將程式庫專案做為對每個 APK 專案的參照。如果可行,請在程式庫專案中定義起始活動,然後在 APK 專案中擴充該活動。在程式庫專案中定義的起始活動可以把所有應用程式初始化作業放在同一個位置,這樣每個 APK 就不必重新實作「通用」工作,例如初始化 Analytics (分析)、執行授權檢查,以及其他不會大幅從 APK 變更為 APK 的任何其他初始化程序。

調整資訊清單

如果使用者透過 Google Play 下載使用多個 APK 的應用程式,可以透過一些簡單規則選擇要使用的正確 APK:

  • 資訊清單必須表明特定 APK 符合資格
  • 在符合資格的 APK 中,最高版本號碼勝出
  • 只要裝置在市場上支援 APK 中列出的「任何」紋理格式,系統就會將該裝置視為符合資格

關於 GL 紋理,最後規則是很重要的。舉例來說,如果在同一個應用程式中使用不同的 GL 格式,請務必「非常」謹慎。如果希望 PowerVR 99% 的時間都能使用,但用 ETC1 處理,例如啟動畫面... 則您的資訊清單應一律指出支援這兩種格式。系統會將「只」受支援 ETC1 的裝置視為相容裝置,以便下載您的應用程式,而使用者會看到一些令人期待的當機訊息。常見的情況是,如果您為多個 APK 專門針對 GL 紋理支援功能使用不同裝置,則每個 APK 將採用一種紋理格式。

實際上,紋理支援與另外兩個多個 APK 維度、API 級別和螢幕大小稍有不同。任何裝置都只有一個 API 級別和一個螢幕大小,取決於 APK 支援多種裝置。使用紋理時,APK 一般會支援一種紋理,且裝置會支援多種紋理。一個支援多個 APK 的裝置通常會重疊,但解決方法是相同的:版本代碼。

比方說,用一些裝置為例,看看先前定義的 APK 數量,適用於每部裝置。

智慧型手機 Nexus S Evo
ETC1 ETC1 ETC1
PowerVR ATI TC

假設在可用情況下,PowerVR 和 ATI 格式在可用情況下優先於 ETC1,比起「勝出版本編號最高的版本」規則,如果在每個 APK 中設定了 versionCode 屬性 (例如紅色 ≥ ≥ 藍色),那麼在支援紅色和綠色的裝置上會一律由「紅色」和「綠色」選擇,而且裝置應能同時支援紅色和綠色。

如要將所有 APK 保存在獨立的「測試群組」上,請務必採用良好的版本代碼配置。請參閱開發人員指南的「版本代碼」區域,找到建議採用的代碼。由於 APK 範例組合只處理 3 種可能維度的其中一種,因此可以將每個 APK 1000 的單位分開,然後再遞增。看起來可能會像這樣:

藍色:1001、1002、1003、1004...
綠色:2001、2002、2003、2004...
紅色:3001、3002、3003、3004...

總而言之,Android 資訊清單看起來可能如下所示:

藍色:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="1001" android:versionName="1.0" package="com.example.foo">
    <supports-gl-texture android:name="GL_OES_compressed_ETC1_RGB8_texture" />
    ...

綠色:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="2001" android:versionName="1.0" package="com.example.foo">
    <supports-gl-texture android:name="GL_AMD_compressed_ATC_texture" />
    ...

紅色:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="3001" android:versionName="1.0" package="com.example.foo">
    <supports-gl-texture android:name="GL_IMG_texture_compression_pvrtc" />
    ...

詳閱正式發布前檢查清單

將檔案上傳至 Google Play 前,請仔細檢查下列項目。提醒您,這些資訊特別與多個 APK 相關,無法代表所有上傳至 Google Play 的應用程式完整清單。

  • 所有 APK 都必須使用相同的套件名稱
  • 所有 APK 都必須使用相同的憑證簽署
  • 請仔細檢查資訊清單篩選器是否含有衝突的資訊 (僅支援 XLARGE 螢幕支援杯子蛋糕的 APK 不會向任何人顯示)
  • 每個 APK 的資訊清單不得有至少一個支援的畫面、OpenGL 紋理或平台版本的資訊清單
  • 請嘗試在至少一個裝置上測試每個 APK。更棒的是,您在開發機器上的企業中 有一個最可自訂的裝置模擬器。堅持下去!

另外,在推出應用程式之前先檢查已編譯的 APK,確保 Google Play 不會發生任何意外情況,導致應用程式遭到隱藏。使用「aapt」工具 這個做法其實相當簡單Aapt (Android 資產封裝工具) 是建立及封裝 Android 應用程式的建構程序的一部分,也是檢查應用程式時非常便利的工具。

>aapt dump badging
package: name='com.example.hello' versionCode='1' versionName='1.0'
sdkVersion:'11'
uses-permission:'android.permission.SEND_SMS'
application-label:'Hello'
application-icon-120:'res/drawable-ldpi/icon.png'
application-icon-160:'res/drawable-mdpi/icon.png'
application-icon-240:'res/drawable-hdpi/icon.png'
application: label='Hello' icon='res/drawable-mdpi/icon.png'
launchable-activity: name='com.example.hello.HelloActivity'  label='Hello' icon=''
uses-feature:'android.hardware.telephony'
uses-feature:'android.hardware.touchscreen'
main
supports-screens: 'xlarge'
supports-any-density: 'true'
locales: '--_--'
densities: '120' '160' '240'

檢查 aapt 輸出內容時,請務必確認支援畫面和相容畫面的值沒有衝突,且您沒有因您在資訊清單中設定的權限而新增的非預期「uses-feature」值。在上例中,大多數裝置都看不見 APK。

原因是什麼?藉由新增必要權限 SEND_SMS,系統已默示新增 android.hardware.telephony 的功能需求。由於大部分 (不是所有) 超大型裝置都是沒有電話硬體硬體的平板電腦,因此 Google Play 在這些情況下會篩除這個 APK,直到日後的裝置夠大,足以回報為大螢幕尺寸且具備電話硬體設備為止。

不過,只要在資訊清單中新增以下內容,即可輕鬆修正這項問題:

<uses-feature android:name="android.hardware.telephony" android:required="false" />

android.hardware.touchscreen 要求也會以隱含方式加入。如要讓 APK 顯示在非觸控螢幕裝置的電視上,請在資訊清單中新增以下內容:

<uses-feature android:name="android.hardware.touchscreen" android:required="false" />

完成正式發布前檢查清單後,請將 APK 上傳到 Google Play。瀏覽 Google Play 時,應用程式可能需要一點時間才會顯示,如果是之後,請執行最後檢查。將應用程式下載到任何測試裝置上,確保 APK 的指定目標裝置是正確的。恭喜,大功告成!